【问题标题】:Container not staying up on docker-compose up容器不停留在 docker-compose up
【发布时间】:2024-06-20 13:25:02
【问题描述】:

编写了一个简单的 RabbitMQ 生产者/消费者示例,但我无法让我的消费者容器继续在 docker-compose up -d 上运行。它应该在无限循环中运行。

如您所见,我可以在运行 docker-compose run consumerdocker-compose run -d consumer 时让它保持正常运行

app.py

​​>
#!/usr/bin/env python
import argparse
import pika
import json

connection = None
channel = None
TYPES = ['producer', 'consumer']


def producer():
    global connection, channel
    connection = pika.BlockingConnection(pika.ConnectionParameters('rabbit'))
    channel = connection.channel()

    channel.queue_declare(queue='hello')

    # Currently a python dict
    data = {
        'key': 'myvalue'
    }

    channel.basic_publish(exchange='',
                          routing_key='hello',
                          body=json.dumps(data))  # Encode as a JSON string
    print(f' [x] Sent {data}')
    connection.close()


def consumer():
    global connection, channel
    connection = pika.BlockingConnection(pika.ConnectionParameters('rabbit'))
    channel = connection.channel()
    channel.queue_declare(queue='hello')

    def callback(ch, method, properties, body):
        data = json.loads(body)  # decode JSON string into a python dict
        print(f' [x] Received: {data} type {type(data)}')

    channel.basic_consume(callback,
                          queue='hello',
                          no_ack=True)
    print(' [*] Waiting for messages. To exit press CTRL+C')

    # Infinite loop
    try:
        channel.start_consuming()
    except KeyboardInterrupt:
        print('\nExiting...')


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('type', help='producer/consumer')
    args = parser.parse_args()

    client_type = args.type.lower()
    if client_type not in TYPES:
        print(f'{client_type} is not a valid type {TYPES}')
    elif client_type == TYPES[0]:
        producer()
    elif client_type == TYPES[1]:
        consumer()

if __name__ == '__main__':
    main() 

如您所见,它相当简单。基本上是从 RabbitMQ 文档中复制的。在写完大部分内容后,我运行了docker-compose logs consumer,得到了以下结果。

这表明它在初始构建时无法连接。即使在初始构建之后运行docker-compose up 时,它也无法保持正常运行。

docker-compose.yml

version: '3'
services:
  producer:
    build: .

  consumer:
    build: .
    depends_on:
      - rabbit
    command: example consumer

  rabbit:
    image: rabbitmq:3.6

我使用了depends_on,因为我认为应该确保在 RabbitMQ 服务之后构建消费者服务。

代码仓库为here

【问题讨论】:

    标签: python docker rabbitmq docker-compose


    【解决方案1】:

    您是否尝试过使用 restart 关键字为 consumer 容器设置重启策略?在这些情况下经常发生的情况是,您的应用程序在该服务运行之前尝试连接到后端服务(在本例中为 RabbitMQ)并且一切都崩溃了。如果你设置了重启策略,docker 会自动重启容器,希望到这个时候,你的后端服务会启动并运行。

    有更经典的方法可以做到这一点,但以最简单的形式,这对你有用。

    您可以通过重新启动您的消费者容器并查看它是否保持运行来测试我的理论。

    docker-compose restart consumer
    

    【讨论】:

    • 是的,我有点意识到这很可能是在发布它并阅读此docs.docker.com/compose/startup-order 后发生的事情,我认为使用wait-for-it 脚本可能比将重启策略设置为始终(解决了这个问题)。
    • 您对wait-for-it 与简单设置restart: always 有什么看法?我认为重启策略应该是always不管。
    • 我想这取决于您的用例。对于简单的本地开发,我可以接受重启策略。如果您打算在生产中使用 compose(不是特别常见),您需要更加小心并使用 wait-for-it
    • 好的。谢谢伙计,自从我使用 Docker 以来已经有一分钟了,所以我觉得这个有点愚蠢,但我也没有读过或听说过 wait-for-it,所以没那么糟糕。