泊坞窗服务如何设法从单独的泊坞窗容器中调用实例?

时间:2020-09-17 10:19:23

标签: docker docker-compose dockerfile celery

我最近开始使用Docker + Celery。我还分享了full sample codes for this example on github,下面是其中的一些代码段,以帮助解释我的观点。

对于上下文,我的示例被设计为一个预订微服务系统中的事件的节点。在此节点中,它包含以下服务:

  1. 订户(使用kombu订阅事件)
  2. Worker (将芹菜用于处理事件的异步任务)
  3. Redis(作为消息代理和celery的结果后端)

服务在docker-compose.yml文件中定义如下:

version: "3.7"
services:
    # To launch the Subscriber (using Kombu incl. in Celery)
    subscriber:
        build: .
        tty: true
        #entrypoint: ...

    # To launch Worker (Celery)
    worker:
        build: .
        entrypoint: celery worker -A worker.celery_app --loglevel=info
        depends_on: 
            - redis

    redis: 
        image: redis
        ports: 
            - 6379:6379
        entrypoint: redis-server

为简单起见,我省略了 subscriber 的代码,我认为在此示例中,在 subscriber容器中使用python交互式外壳就足够了:

python3
>>> from worker import add
>>> add.delay(2,3).get()
5

并在工人容器日志中:

worker_1      | [2020-09-17 10:12:34,907: INFO/ForkPoolWorker-2] worker.add[573cff6c-f989-4d06-b652-96ae58d0a45a]: Adding 2 + 3, res: 5
worker_1      | [2020-09-17 10:12:34,919: INFO/ForkPoolWorker-2] Task worker.add[573cff6c-f989-4d06-b652-96ae58d0a45a] succeeded in 0.011764664999645902s: 5

虽然一切似乎都正常,但我感到不安。我以为这个示例不尊重Docker容器的隔离原理。

容器不是旨在隔离其操作系统级别的, 流程和网络?而且如果容器必须进行通信,则不应该通过IP地址和网络协议(TCP / UDP等)完成

首先,在我的示例中, worker subscriber 运行相同的代码库,因此import语句上不会出现任何问题。

但是,芹菜工作者是从 worker容器中的entrypoint启动的,因此 subscriber 如何设法在应该隔离的工人容器

要进一步验证它实际上是从 worker容器调用celery worker实例,我停止了 worker容器,并在< strong>用户容器。再次打开工作容器后,请求将等待(这是芹菜的预期结果),并返回相同的结果。因此,IMO,是的,来自一个容器的服务正在从另一个容器调用应用程序实例,而没有网络连接,例如连接到Redis(使用IP地址等)。

请告知我的理解是不正确的,还是我不知道的地方可能有错误的实现。

2 个答案:

答案 0 :(得分:0)

消费者(工作人员)和生产者(子投标人)都配置为将Redis(redis)用作代理和结果后端。这就是为什么一切正常的原因。 -当您在订阅者容器中执行add.delay(2,3).get()时,它会将任务发送给Redis,然后它被运行在另一个容器中的Celery工作人员选择。 请记住,运行add.delay(2,3).get()代码的Python进程正在订阅者容器中运行,而执行add()函数并将结果存储在结果后端中的ForkPoolWorker-2进程正在worker容器中运行。这些过程是完全独立的。

订阅者进程未调用辅助容器中的任何内容! -用简单的英语说,这是我的工作:“在Redis中,这是我需要做的,请工作人员完成,并让我知道您已完成,以便我获取结果。”

答案 1 :(得分:0)

Docker-compose为在单个文件中创建的容器创建默认的docker网络。由于您正确地指向了所有内容,因此它将沿着该网络发出请求,这就是成功的原因。听说如果您要在不使用docker-compose的情况下并行并行运行每个容器,这种方法仍然有效,我会感到惊讶。