Docker未转发HTTP请求:Scala微服务运行正常Postman返回socket hang up
问题根因
你的Scala服务在容器内绑定的是本地回环地址127.0.0.1,容器内的回环地址仅允许容器内部的进程访问,Docker的端口转发机制无法将宿主机侧的请求转发到绑定了回环地址的服务上。你在宿主机上通过netstat看到的8080端口监听是Docker代理的监听,请求到达代理后无法转发到容器内的Scala服务,直接断连就会抛出socket hang up错误。
另外还有一个隐藏问题:你使用-d参数后台启动容器时,不会分配交互式终端,代码中的StdIn.readLine()会直接读取到EOF,触发后续的服务解绑、关闭逻辑,也会导致请求无法响应。
解决方案
- 修改服务绑定地址
将Main.scala中的服务绑定逻辑修改为绑定容器内所有网卡地址0.0.0.0:
val bindingFuture = Http() .newServerAt("0.0.0.0", 8080) // 把原来的127.0.0.1/localhost改为0.0.0.0 .bind(userRoute.route)
- 调整启动逻辑(可选,针对后台运行场景)
如果需要保持容器后台运行,避免StdIn.readLine()触发服务关闭,可以保留启动命令中的-i参数保持标准输入打开,或者修改代码移除StdIn.readLine()相关的逻辑,改用shutdown hook处理服务销毁逻辑。 - 重新构建镜像并启动
修改代码后重新构建Docker镜像,再使用原端口映射命令启动容器即可正常访问:
docker run -i -t -d -p 8080:8080 app-core:0.1.0-SNAPSHOT
验证方法
容器启动后,可以先进入容器内部验证服务是否正常响应:
# 先获取容器ID docker ps # 进入容器执行请求测试 docker exec -it <容器ID> curl http://127.0.0.1:8080/api/core-service/create-user
容器内部测试正常后,再用Postman从宿主机发起请求即可。
内容的提问来源于stack exchange,提问作者osumatu
相关产品推荐
相关产品推荐

