“URL超过最大重试次数”,两个Docker容器在本地主机上相互发送POST请求

2024-06-28 10:29:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在本地主机上的两个单独的Docker容器上运行两个Flask应用程序,端口映射为3000:30005000: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.post部分停止,并返回错误:

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

Tags: tonamesendjsonapp应用程序inputdata
3条回答

因此,当您创建docker实例时,它会在您的计算机上创建一个虚拟网络-因此每个docker实例都认为127.0.0.1(或localhost)是它自己,而不是您的实际计算机(您认为是127.0.0.1)。因此,您应该查看docker网络,并且

a)引用要连接到的docker实例,或 b) 添加一个端口(这就是您所做的),然后引用父计算机ip

看看这里的第二个答案:How to get the IP address of the docker host from inside a docker container

您有两个单独的容器,其中应用程序在第一个容器中的端口5000和第二个容器中的端口3000上运行

当您从应用程序在端口5000上运行的第一个容器中发送请求时,您将得到requests.exceptions.ConnectionError: HTTPConnectionPool(host='127.0.0.1', port=3000)

这是因为3000上的第一个容器中没有运行应用程序

每个容器的localhost都不同,它与docker主机的localhost也不同

如果希望以这种方式发送请求,则需要通过向docker compose添加network: host来允许容器reuse host network堆栈:

  uploader-2:
    build: ./uploader-2
    image: uploader-2
    container_name: uploader-2
    network: host
    ports:
        - 3000:3000

另一个更好的选择是连接到作为容器名的主机名

docs开始:

By default Compose sets up a single network for your app. Each container for a service joins the default network and is both reachable by other containers on that network, and discoverable by them at a hostname identical to the container name.

所以代码看起来像:

requests.post("http://uploader-2:3000/postprocess", json=to_send_string)

甚至,更好的选择是向服务名称发送请求。可以在docker compose或docker-swarm中执行此操作:

any service can reach any other service at that service’s name

错误来自使用IP地址127.0.0.1

Docker introduces a virtual network, so each docker-isntance sees itself as 127 not the host machine

(thx@Jmons)


要在本地启动代码,请使用您的固定IPv4地址

对于Windows用户:打开命令提示符(cmd)并运行ipconfig命令,检索位于IPv4 address. . . . . . . . . . . . . .:的IP@它通常是 192.168.x.x类型

IPv4 address in command prompt

相关问题 更多 >