Python ';URL';超过最大重试次数;两个Docker容器相互发送POST请求,在本地主机上运行
我正在本地主机上的两个单独的Docker容器上运行两个Flask应用程序,端口映射为Python ';URL';超过最大重试次数;两个Docker容器相互发送POST请求,在本地主机上运行,python,docker,flask,docker-compose,http-post,Python,Docker,Flask,Docker Compose,Http Post,我正在本地主机上的两个单独的Docker容器上运行两个Flask应用程序,端口映射为3000:3000和5000:5000。它们中的每一个都有一个接受POST请求并执行某些功能的路由。以下是应用程序1的代码: @app.route('/preprocess', methods=['POST']) def app_preprocess(): req_data = request.get_json() bucket = req_data['bucket'] input_fi
3000:3000
和5000:5000
。它们中的每一个都有一个接受POST请求并执行某些功能的路由。以下是应用程序1的代码:
@app.route('/preprocess', methods=['POST'])
def app_preprocess():
req_data = request.get_json()
bucket = req_data['bucket']
input_file = req_data['input']
upload_file = input_file + "_1"
# do some functions
to_send = {"bucket": bucket, "input": upload_file}
to_send_string = json.dumps(to_send)
requests.post("http://127.0.0.1:3000/postprocess", json=to_send_string)
return "Sent request to 2"
if __name__ == "__main__":
app.run(debug=True, host='0.0.0.0', port=5000)
和应用程序2:
@app.route('/postprocess', methods=['POST'])
def app_postprocess():
req_data = request.get_json()
bucket = req_data['bucket']
input_file = req_data['input']
upload_file = input_file + "_2"
# do some functions
return "Uploaded 2"
if __name__ == "__main__":
app.run(debug=True, host='0.0.0.0', port=3000)
我使用Postman将POST请求分别发送到每个应用程序。应用程序1和2都完成了它的工作(“执行某些功能”位)。应用2会很好地返回“上传2”
应用程序1在请求处停止。发布部分,并返回错误:
requests.exceptions.ConnectionError: HTTPConnectionPool(host='127.0.0.1', port=3000): Max retries exceeded
with url: /postprocess (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at
0x7f74d3fc6b10>: Failed to establish a new connection: [Errno 111] Connection refused')) // Werkzeug Debugger
请帮忙修理一下,谢谢。我也是Flask和HTTP路由的新手,所以我可能会错过一些东西
编辑:这是docker-compose.yaml
version: '3'
services:
uploader-1:
build: ./uploader-1
image: uploader-1
container_name: uploader-1
ports:
- 5000:5000
uploader-2:
build: ./uploader-2
image: uploader-2
container_name: uploader-2
ports:
- 3000:3000
您有两个单独的容器,其中应用程序在第一个容器中的端口5000和第二个容器中的端口3000上运行
当您从应用程序在端口5000上运行的第一个容器中发送请求时,您会得到requests.exceptions.ConnectionError:HTTPConnectionPool(host='127.0.0.1',port=3000)
这是因为3000上的第一个容器中没有运行应用程序
每个容器的localhost都不同,它与docker主机的localhost也不同
如果要以这种方式发送请求,则需要通过向docker compose添加network:host
来允许容器堆叠:
uploader-2:
build: ./uploader-2
image: uploader-2
container_name: uploader-2
network: host
ports:
- 3000:3000
另一个更好的选择是连接到作为容器名的主机名
从:
默认情况下,Compose为应用程序设置单个网络。每个
服务的容器加入默认网络,并且是
可由该网络上的其他容器访问,并可由
它们的主机名与容器名称相同
所以代码看起来像:
requests.post(“http://uploader-2:3000/postprocess,json=to\u send\u string)
甚至,更好的选择是向服务名称发送请求。可以在docker compose或:
任何服务都可以以该服务的名称访问任何其他服务
错误源于使用IP地址127.0.0.1
Docker引入了一个虚拟网络,因此每个Docker都可以看到
它本身不是主机
(thx@Jmons)
要在本地启动代码,请使用固定的IPv4地址
对于Windows用户:打开命令提示符(cmd)并运行ipconfig
命令,检索位于IPv4地址的IP@……:代码>它的类型通常为192.168.x.x
因此,当您创建docker实例时,它会在您的计算机上创建一个虚拟网络-因此每个docker实例都认为127.0.0.1(或localhost)是它自己,而不是您的实际计算机(您认为是127.0.0.1)。因此,您应该查看docker网络,并且
a) 引用要连接到的docker实例,或
b) 添加一个端口(这就是您所做的),然后引用父计算机ip
看看这里的第二个答案:您是使用docker compose来运行应用程序还是纯docker?我使用docker compose,让我用YMLY编辑我的帖子。您应该使用另一个docker compose服务的名称作为主机名,而不是本地主机-请求http://uploader-2:3000/postprocess,json=to_send_string)
所以我试过了,它不再给我错误;然而,应用程序2现在没有完成它的工作(“执行某些功能”块)。有什么方法可以让我读取uploader-2的输出日志吗?标准的方法是将你的flask应用程序移动到WSGi服务器上进行管理。例如Gunicorn。关于如何做这件事以及如何将其装箱,有很多文档。关于通过postman
模块的请求
的观点取决于它们如何在内部使用线程这是一种绕过真正问题的技巧:每个容器都是自己的localhost
,硬编码的URL是错误的。描述整个网络设置以及可用的主机名。@DavidMaze我的答案提供了第一个选项,因为这是代码在没有任何更改的情况下的工作方式。但是,我同意最好使用服务名称。编辑了我的答案。这是不正确的-这不是说127是被禁止的-它的ThatDocker引入了一个虚拟网络,因此每个docker isntance都将自己视为127而不是主机。Thx@Jmons,0.0.0.0也是这样吗?不完全一样-0.0.0通常用于表示任何地址,但实际上它是一个无效地址。i、 e.0.0.0.0/0表示CIDR符号中的任何符号。当您“绑定到ip”时,通常绑定0.0.0.0意味着接受任何ip。(因此,如果您的机器有很多ip,s或正在混乱模式下侦听,这就是它的意思)。