简体   繁体   English

使用 multiprocessing.manangers.BaseManager 作为 docker-compose 编排的一部分

[英]Using multiprocessing.manangers.BaseManager as part of docker-compose orchestration

I have used docker-compose quite a bit in the past and have enjoyed success leveraging the internal network created as part of a docker-compose orchestration.我过去曾多次使用 docker-compose,并且在利用作为 docker-compose 编排的一部分创建的内部网络方面取得了成功。

I have a very simple example where I have two services:我有一个非常简单的例子,我有两个服务:

version: '3'

services:
  intent:
    restart: always
    build: ./dockerfs/intent
    command: gunicorn -w 2 --bind 0.0.0.0:5000 --timeout 999 --log-level debug client:app
    ports: 
      - 8075:5000
  base_s:
    restart: always
    build: ./dockerfs/base

where service base_s is a base_s service by connecting to the BaseManager server "holding" global data in connections :其中 service base_s是一个 base_s 服务,通过连接到 BaseManager 服务器“持有” connections中的全局数据:

import json
import uuid
from multiprocessing import Lock
from multiprocessing.managers import BaseManager


connections = {}
lock = Lock()


def get_connection(intent_id):
    with lock:
        if intent_id not in connections:
            print(f"{intent_id} not in connections. creating now...")
            connections[intent_id] = object()
            print(f"addining intent_id {intent_id} to connections")

        return connections[intent_id]


print("starting BaseManager!")
manager = BaseManager(("localhost", 8098), b"password")
manager.register("get_connection", get_connection)
server = manager.get_server()
server.serve_forever()

and service intent is a flask app that "gets" data from the BaseManager service:并且服务意图是从 BaseManager 服务“获取”数据的 flask 应用程序:

import uuid
from multiprocessing.managers import BaseManager
from flask import g, session, Flask, jsonify


app = Flask(__name__)


client_id = uuid.uuid4().hex


def get_client():
    # if not hasattr(g, "rserve"):
    # calling http:<service> as I normally would to "interact" with service in shared network
    manager = BaseManager(("http://base_s", 8098), b"password")  # <<
    manager.register("get_connection")
    manager.connect()
    o = manager.get_connection(client_id)
    print(f"got object using id {o}")

    return f"got it {o}"


@app.route("/", methods=["GET", "POST"])
def client():
    o = get_client()

    return jsonify({"client_id": client_id, "object_id": o}

I can run the above code with success on local host but when I spin up these services using the docker-compose file shared above, I get a intent_1 | socket.gaierror: [Errno -2] Name or service not known我可以在本地主机上成功运行上述代码,但是当我使用上面共享的docker-compose文件启动这些服务时,我得到了一个intent_1 | socket.gaierror: [Errno -2] Name or service not known intent_1 | socket.gaierror: [Errno -2] Name or service not known . intent_1 | socket.gaierror: [Errno -2] Name or service not known

I was under the impression that I would be able to interact with the BaseManager service since docker-compose maintains an internal network which leads me to think that I maybe do not understand how the BaseManager is served.我的印象是我可以与 BaseManager 服务交互,因为 docker-compose 维护一个内部网络,这让我认为我可能不了解 BaseManager 的服务方式。

Can anyone think of why I am not able to connect to the BaseManager service?谁能想到为什么我无法连接到 BaseManager 服务?

Thanks in advance.提前致谢。

update:更新:

as part of the netstat -a command in the base_s service I see作为我看到的base_s服务中netstat -a命令的一部分

Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 ip-127-0-0-11.ec2:37121 0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:8098            0.0.0.0:*               LISTEN     
udp        0      0 ip-127-0-0-11.ec2:53041 0.0.0.0:*   

so it looks like everything is listening as it should.所以看起来一切都在听。

Got it working.得到它的工作。

two changes that I made were:我所做的两个更改是:

In base_s service codebase_s服务代码中

  1. manager = BaseManager(("localhost", 8098), b"password") to manager = BaseManager(("", 8098), b"password") manager = BaseManager(("localhost", 8098), b"password")manager = BaseManager(("", 8098), b"password")

this chooses a default address to ensure you are not listening on a loopback address这会选择一个默认地址以确保您没有监听环回地址

In client flask api code 2) manager = BaseManager(("http://base_s", 8098), b"password") to在客户端 flask api 代码 2) manager = BaseManager(("http://base_s", 8098), b"password")

I think the real fix was 2 - I assume that BaseManager does not expect a HTTP connection.我认为真正的修复是2 - 我假设 BaseManager 不期望 HTTP 连接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM