python—将multiprocessing.manangers.basemanager用作docker compose编排的一部分

bpsygsoo  于 2021-07-13  发布在  Java
关注(0)|答案(1)|浏览(379)

我在过去使用过docker compose,并成功地利用了docker compose编排中创建的内部网络。
我有一个非常简单的例子,我有两个服务:

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

何处服务 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()

而service intent是一个flask应用程序,它从basemanager服务“获取”数据:

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}

我可以在本地主机上成功运行上面的代码,但是当我使用 docker-compose 上面共享的文件,我得到一个 intent_1 | socket.gaierror: [Errno -2] Name or service not known .
因为docker compose维护着一个内部网络,这让我觉得我可能不了解basemanager是如何服务的,所以我的印象是我能够与basemanager服务交互的。
有人能想到为什么我不能连接到basemanager服务吗?
提前谢谢。
更新:
作为 netstat -a 中的命令 base_s 服务我明白了

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:*

所以看起来一切都在倾听。

1l5u6lss

1l5u6lss1#

开始工作了。
我做了两个改变:
base_s 服务代码 manager = BaseManager(("localhost", 8098), b"password")manager = BaseManager(("", 8098), b"password") 这将选择一个默认地址,以确保您没有监听环回地址
客户端(api代码2) manager = BaseManager(("http://base_s", 8098), b"password")
我想真正的解决办法是 2 -我假设basemanager不需要http连接。

相关问题