symfony - 我应该如何构建 dockerized RabbitMQ?

标签 symfony docker rabbitmq docker-compose amqp

我正在尝试使用 Docker 将我们的单体 PHP Symfony 应用程序迁移到更具可扩展性的解决方案。应用程序和RabbitMQ之间有一些通信,我使用docker-compose启动所有容器,在本例中是应用程序和 RabbitMQ 服务器。

关于一个容器应该只产生一个进程的话题有很多讨论,还有 Docker best practices关于这一点有点含糊:

While this mantra has good intentions, it is not necessarily true that there should be only one operating system process per container. In addition to the fact that containers can now be spawned with an init process, some programs might spawn additional processes of their own accord.



为每个 RabbitMQ 消费者创建一个单独的 Docker 容器有意义吗?不让rabbitmq 服务器知道用于处理队列的语言/工具,这种感觉是“正确的”和“干净的”。我想出了( docker-compose.yml 的相关部分):
  app :
    # my php-fpm app container

  rabbitmq_server:
    container_name: sf.rabbitmq_server
    build: .docker/rabbitmq
    ports:
        - "15672:15672"
        - "5672:5672"
    networks:
      - app_network

  rabbitmq_consumer:
    container_name: sf.rabbit_consumer
    extends: app
    depends_on:
      - rabbitmq_server
    working_dir: /app
    command: "php bin/console rabbitmq:consumer test"
    networks:
      - app_network

我可以在 rabbitmq_consumer 中运行多个消费者容器使用 nohup或其他一些在后台运行它们的方式。

我想我的问题是:

我可以以某种方式自动执行“添加新使用者”,这样每次从代码中添加新使用者时,我就​​不必编辑 Docker(和其他人,如 ansible)的“构建脚本”吗?

将 RabbitMQ 服务器与消费者分开是否有意义,还是应该将 Rabbit 服务器与在后台运行的消费者一起使用?

还是应该将它们放置在应用程序容器的背景中?

最佳答案

我会分享我的经验,所以要批判性地思考它。

消费者必须在与 Web 应用程序不同的容器中运行。消费者容器运行进程管理器 like these .它的职责是产生一些子消费者处理器,如果它们退出,则重新启动它们,重新加载 SIGUSR1 信号,在 SIGTERM 上正确关闭它们。如果主进程存在,则整个容器也存在。对于这种情况,您可能会遇到警察,例如总是重新启动。 consume.php 是这样的脚本看起来像:

<?php

// bin/consume.php
use App\Infra\SymfonyDaemon;
use Symfony\Component\Process\ProcessBuilder;

require __DIR__.'/../vendor/autoload.php';

$workerBuilder = new ProcessBuilder(['bin/console', 'enqueue:consume', '--setup-broker', '-vvv']);
$workerBuilder->setPrefix('php');
$workerBuilder->setWorkingDirectory(realpath(__DIR__.'/..'));
$daemon = new SymfonyDaemon($workerBuilder);
$daemon->start(3);

容器配置如下所示:
app_consumer:
    restart: 'always'
    entrypoint: "php bin/consume.php"
    depends_on:
      - 'rabbitmq_server'

Can I somehow automate the "adding a new consumer", so that I would not have to edit the "build script" of Docker (and others, like ansible) every time the new consumer is added from the code?



不幸的是,RabbitMQ 捆绑队列管理还有很多不足之处。默认情况下,您必须为每个队列运行一个命令。如果您有 100 个队列,则需要 100 个进程,每个队列至少一个。有办法到configure a multi-queue consumer但需要完全不同的设置。顺便说一下,enqueue 做得更好。您可以运行一个命令一次从所有队列中使用。 --queue命令选项允许进行更准确的调整。

Does it make sense to separate RabbitMQ server from Consumers, or should I use the Rabbit server with consumers running in the background?



RabbitMQ 服务器应该在一个单独的容器中运行。我不建议将它们添加到一个容器中。

Or should they be placed in the background of the app container?



我建议至少有两个应用程序容器。一个运行 Web 服务器并为 HTTP 请求提供服务,另一个运行队列消费者。

关于symfony - 我应该如何构建 dockerized RabbitMQ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44926606/

相关文章:

c# - 当 ReplyTo 是临时队列时检索异常

python - Celery 为什么任务停留在队列中

php - Symfony2 独立表单组件 - 设置表单

php - 如何在 Symfony 控制台中禁用命令的输出?

php - 如何使 in_memory security.yaml 提供的用户在 Symfony 4.3 中使用登录表单正常工作?

php - 如何在 PHP docker 镜像上安装 yarn 和 npm(symfony 4 项目)

docker - 什么是暂停容器?

android - 在 Android Service 中处理 Rabbitmq Client 收到的消息

mysql - 如何在mysql工作台中打开mysql容器docker

php - PHP-FPM不会从Dockerfile开始