spring-boot - 从 dockerized jar 发送 post-request 到本地 python-service
问题描述
我在我的 Mac 上运行一个 dockerized jar 和一个本地烧瓶服务。jar 代表音乐目录的网络应用程序,flask-service 将音符转换为基于 xml 的音乐编码格式。当用户单击下载按钮时调用该服务。通过 PyCharm 和 IntelliJ 启动应用程序工作正常,但在容器中我得到:
2019-11-30 19:36:14.504 ERROR 1 --- [nio-8080-exec-1] o.a.c.c.C.[.[.
[/].[dispatcherServlet] : Servlet.service() for servlet
[dispatcherServlet] in context with path [] threw exception [Request
processing failed; nested exception is
org.springframework.web.client.ResourceAccessException: I/O error on
POST request for "http://0.0.0.0:5000/test": Connection refused
(Connection refused); nested exception is java.net.ConnectException:
Connection refused (Connection refused)] with root cause
java.net.ConnectException: Connection refused (Connection refused)
at java.base/java.net.PlainSocketImpl.socketConnect(Native Method) ~[na:na]
at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:399) ~[na:na]
at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:242) ~[na:na]
at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:224) ~[na:na]
at java.base/java.net.Socket.connect(Socket.java:591) ~[na:na]
at java.base/java.net.Socket.connect(Socket.java:540) ~[na:na]
at java.base/sun.net.NetworkClient.doConnect(NetworkClient.java:182) ~[na:na]
at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:474) ~[na:na]
at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:569) ~[na:na]
at java.base/sun.net.www.http.HttpClient.<init>(HttpClient.java:242) ~[na:na]
at java.base/sun.net.www.http.HttpClient.New(HttpClient.java:341) ~[na:na]
at java.base/sun.net.www.http.HttpClient.New(HttpClient.java:362) ~[na:na]
at java.base/sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:1248) ~[na:na]
at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1187) ~[na:na]
at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1081) ~[na:na]
at java.base/sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:1015) ~[na:na]
at org.springframework.http.client.SimpleBufferingClientHttpRequest.executeInternal(SimpleBufferingClientHttpRequest.java:76) ~[spring-web-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48) ~[spring-web-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53) ~[spring-web-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:735) ~[spring-web-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:670) ~[spring-web-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:414) ~[spring-web-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
at com.masterarbeit.wolfganggabrielvz.adapter.userRoles.MEIAdapter.getData(MEIAdapter.java:51) ~[classes!/:0.0.1-SNAPSHOT]
at com.masterarbeit.wolfganggabrielvz.adapter.controller.IncipitController.getMei(IncipitController.java:51) ~[classes!/:0.0.1-SNAPSHOT]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104) ~[spring-webmvc-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:892) ~[spring-webmvc-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) ~[spring-webmvc-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1039) ~[spring-webmvc-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942) ~[spring-webmvc-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005) ~[spring-webmvc-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:908) ~[spring-webmvc-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:660) ~[tomcat-embed-core-9.0.22.jar!/:9.0.22]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882) ~[spring-webmvc-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[tomcat-embed-core-9.0.22.jar!/:9.0.22]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.22.jar!/:9.0.22]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.22.jar!/:9.0.22]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.22.jar!/:9.0.22]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.22.jar!/:9.0.22]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.22.jar!/:9.0.22]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118) ~[spring-web-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.22.jar!/:9.0.22]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.22.jar!/:9.0.22]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92) ~[spring-web-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118) ~[spring-web-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.22.jar!/:9.0.22]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.22.jar!/:9.0.22]
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) ~[spring-web-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118) ~[spring-web-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.22.jar!/:9.0.22]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.22.jar!/:9.0.22]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) ~[spring-web-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118) ~[spring-web-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.22.jar!/:9.0.22]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.22.jar!/:9.0.22]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.22.jar!/:9.0.22]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) ~[tomcat-embed-core-9.0.22.jar!/:9.0.22]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490) ~[tomcat-embed-core-9.0.22.jar!/:9.0.22]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) ~[tomcat-embed-core-9.0.22.jar!/:9.0.22]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.22.jar!/:9.0.22]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-9.0.22.jar!/:9.0.22]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) ~[tomcat-embed-core-9.0.22.jar!/:9.0.22]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408) ~[tomcat-embed-core-9.0.22.jar!/:9.0.22]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) ~[tomcat-embed-core-9.0.22.jar!/:9.0.22]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:853) ~[tomcat-embed-core-9.0.22.jar!/:9.0.22]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1587) ~[tomcat-embed-core-9.0.22.jar!/:9.0.22]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.22.jar!/:9.0.22]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.22.jar!/:9.0.22]
at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]
这是来自 Spring-Boot 应用程序的 dockerfile:
FROM amazoncorretto:11
ADD target/springbootapp-0.0.1-SNAPSHOT.jar springbootapp-
0.0.1-SNAPSHOT.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar","springbootapp-0.0.1-SNAPSHOT.jar"]
我如何构建图像:
docker build -f Dockerfile -t catalogue_image .
我加载图像并将其与 mysql-db 链接
docker run --name catalogue_image -p 8080:8080 -d --link catalogueDB:mysql catalogue_image
正在运行的容器的网络设置:
"NetworkSettings": {
"Bridge": "",
"SandboxID": "56bd5ecdaab28c726711b368f0fa73a1d181d66605056cdfbecce0188bd7c1f5",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {
"8080/tcp": [
{
"HostIp": "0.0.0.0",
"HostPort": "8080"
}
]
},
"SandboxKey": "/var/run/docker/netns/56bd5ecdaab2",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "b0366c7e1b934208f7eb748d58cc18dac76a94d5da3e09184761d6da38c52373",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:02",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "eda38ae3c3fc27a3990e3761dc7f35ddd98f04e9f6e55cce46e191557df688d8",
"EndpointID": "b0366c7e1b934208f7eb748d58cc18dac76a94d5da3e09184761d6da38c52373",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:02",
"DriverOpts": null
}
}
Flask 在我的本地机器上运行。服务调用失败后,它不会返回任何错误代码:
python3 gateway.py
['/usr/local/lib/python3.7/site-packages', '/Users/max/PycharmProjects/flaskmicroservice/app', '/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python37.zip', '/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python3.7', '/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib- dynload', '/Users/max/Library/Python/3.7/lib/python/site-packages', '/usr/local/lib/python3.7/site-packages', '/usr/local/lib/python3.7/site-packages/verovio- 2.0.0-py3.7-macosx-10.13-x86_64.egg']
* Serving Flask app "gateway" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
之前,我得到了 FileNotFound-Exception,但我已经可以通过更改资源路径来修复它。我也进入容器并在 etc/hosts 下添加了 localhost 但它不起作用。我阅读了有关从容器内部访问本地服务的所有其他解决方案,但并没有解决我的问题。
我将不胜感激每一个帮助!
编辑:我现在正在使用 docker-compose 文件
version: "3"
services:
db:
image: mysql:latest
environment:
- MYSQL_ROOT_PASSWORD=crescendo
- MYSQL_USER=root
- MYSQL_PASSWORD=crescendo
- MYSQL_DATABASE=wolfgang_gabriel_db
ports:
- 3306:3306
web:
image: gabriel_verzeichnis
depends_on:
- db
ports:
- 8080:8080
domainname: localhost
network_mode: "host"
environment:
- DATABASE_HOST=db
- DATABASE_USER=root
- DATABASE_PASSWORD=crescendo
- DATABASE_NAME=wolfgang_gabriel_db
- DATABASE_PORT=3306
links:
- db:3306
关于答案,我尝试将 network_mode 设置为主机以访问我的本地计算机,但它不起作用。我做错了什么吗?
解决方案
好的,这里的问题是您在 docker 容器中运行客户端,在主机上运行服务器,并且您没有安排在它们之间路由流量。
默认情况下,容器是它自己的本地主机。因此,当您访问 0.0.0.0 时,它会映射回您从中访问它的容器。您想引用主机,以便可以访问那里的服务。这不是一个好主意,但可以使用--network host
标志。这是一个糟糕的主意,我将为您提供一个替代方案。
一个好的解决方案是在容器中运行烧瓶并将其地址作为环境变量传递给客户端容器。您可以通过多种方式执行此操作(包括作为客户端命令行上的标志),但最简单的方法之一是使用 docker-compose 并将这两个服务放在 compose 文件中,然后您的 url 将引用烧瓶服务的主机名,而不是 IP 地址,并且 docker 将确保正确路由流量。
推荐阅读
- java - MenuItem(系统托盘)的文本颜色
- php - 如何将 2 个 PHP 数组转换为 1 个 JSON 对象数组?
- excel - EXCEL:带有 sumproduct 或 rank.avg 的列表的平均排名?
- php - 如何在php中打印由特殊字符组成的列的内容
- javascript - 在函数中声明没有 var 的变量
- android - 无法解决:legacy-support-core-ui-1.0.0
- mysql - Rails 在单个查询中使用多个查询来导入 csv 文件数据
- python - 训练中 epoch loss 的正确计算方法是什么?
- java - 向 mpandroid 条形图添加 x 轴标签仅显示数组列表中的第一个标签
- gitlab - 如何在 Gitlab Ce 中的组之间移动项目