2017-07-05 23 views
3

我想我們的單片PHP的Symfony應用程序遷移到與碼頭工人一個較爲靈活的解決方案。應用程序和RabbitMQ之間有一些通信,我使用docker-compose將所有容器都放到了上面,在這裏是應用程序和RabbitMQ服務器。我應該如何構造碼頭化的RabbitMQ?

有很多圍繞着話題的討論是一個容器應產卵只有一個進程,而Docker best practices是有些含糊關於這一點:

雖然這個口頭禪本意是好的,它不一定是正確的那 每個容器應該只有一個操作系統進程。在 另外一個事實,即容器現在可以用一個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 

我可以使用nohup在後臺運行,其中一些其他的方式rabbitmq_consumer容器或運行了幾位消費者。

我想我的問題是:

我可以以某種方式自動執行「添加一個新的消費」,這樣我就不用編輯多克的「構建腳本」(和其他人一樣,ansible)每次新的消費者是從代碼中添加的?

是否有意義分離從消費者的RabbitMQ服務器,或者我應該使用在後臺運行的消費者兔子服務器?

還是應該放在應用程序容器的背景是什麼?

回答

3

我將分享我的經驗,批判性的思考一下。

消費者有在從一個網絡應用一個單獨的容器中運行。消費者容器運行一個進程管理器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' 

我可以以某種方式自動執行「添加一個新的消費」,這樣我就不必編輯每次從代碼中添加新消費者時,Docker的「構建腳本」(以及其他人,就像ansible)一樣?

不幸的是,RabbitMQ捆綁隊列管理還有很多不足之處。默認情況下,您必須爲每個隊列運行一個命令。如果你有100個隊列,你需要100個進程,每個隊列至少有一個進程。有一種方法configure a multi-queue consumer但需要完全不同的設置。順便說一下,排隊會好很多。您可以運行一個命令來一次消耗所有隊列。該--queue命令選項允許做更精確的調整。

將RabbitMQ服務器與消費者分開是否有意義,還是應該在後臺運行使用者的情況下使用Rabbit服務器?

的RabbitMQ服務器應在單獨的容器中運行。我不會建議將它們添加到一個容器中進行混合。

還是應該放在應用程序容器的背景是什麼?

我建議至少有兩個應用程序容器。一個運行Web服務器並提供HTTP請求,另一個運行隊列消費者。

+0

感謝您的見解和依據。擁有一個可以處理額外隊列的進程管理器容器是解決和分離許多事情的好主意。再然後,PHP還挺吮吸處理長期運行的流程,我真的很想嘗試一些替代品swoole,可能與一些Python或不便處理。 – reafle

相關問題