rea*_*fle 5 amqp rabbitmq symfony docker docker-compose
我正在尝试使用Docker将我们的单片PHP Symfony应用程序迁移到更具可扩展性的解决方案.应用程序和RabbitMQ之间有一些通信,我docker-compose用来启动所有容器,在这种情况下是app和RabbitMQ服务器.
围绕该主题进行了大量讨论,一个容器应该只生成一个进程,而Docker最佳实践在这一点上有些模糊:
虽然这个口头禅具有良好的意图,但每个容器应该只有一个操作系统进程并不一定正确.除了现在可以使用init进程生成容器这一事实之外,某些程序可能会自行生成其他进程.
为每个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
Run Code Online (Sandbox Code Playgroud)
我可以在rabbitmq_consumer容器中使用nohup或在后台运行它们的其他方式运行多个使用者.
我想我的问题是:
我可以以某种方式自动化"添加新的消费者",这样每次从代码中添加新的消费者时,我都不必编辑Docker的"构建脚本"(以及其他的,如ansible)吗?
将RabbitMQ服务器与消费者分开是否有意义,或者我应该将Rabbit服务器与在后台运行的消费者一起使用?
或者它们应该放在app容器的背景中?
我将分享我的经验,因此请批判性地思考。
消费者必须在与 Web 应用程序不同的容器中运行。消费者容器运行这样的进程管理器。它的职责是生成一些子消费者处理器,如果它们退出则重新启动它们,在 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);
Run Code Online (Sandbox Code Playgroud)
容器配置如下所示:
app_consumer:
restart: 'always'
entrypoint: "php bin/consume.php"
depends_on:
- 'rabbitmq_server'
Run Code Online (Sandbox Code Playgroud)
我能否以某种方式自动执行“添加新消费者”,这样每次从代码添加新消费者时,我就不必编辑 Docker(以及其他人,例如 ansible)的“构建脚本”?
不幸的是,RabbitMQ 捆绑队列管理还有很多不足之处。默认情况下,您必须为每个队列运行一个命令。如果您有 100 个队列,则需要 100 个进程,每个队列至少一个。有一种方法可以配置多队列消费者,但需要完全不同的设置。顺便说一句,enqueue 做得更好。您可以运行单个命令来一次从所有队列中使用。命令选项--queue允许进行更准确的调整。
将 RabbitMQ 服务器与消费者分开是否有意义,或者我应该将 Rabbit 服务器与在后台运行的消费者一起使用?
RabbitMQ 服务器应该在单独的容器中运行。我不建议将它们添加到一个容器中混合。
或者应该将它们放置在应用程序容器的后台?
我建议至少有两个应用程序容器。一个运行 Web 服务器并提供 HTTP 请求,另一个运行队列消费者。
| 归档时间: |
|
| 查看次数: |
997 次 |
| 最近记录: |