Rodando Magento 2 Crons com Queue no Kubernetes ou Docker

Submitted by Eric on dom, 21/04/2019 - 16:37
Imagem
magento kubernetes

Vou começar dizendo que este artigo será rápido e simples, mas foi uma dor de cabeça achar os problemas que encontramos rodando Magento com cron e queues no Kubernetes (ou até Docker).
Configurar o cron foi bem simples e a documentação do Magento é muito boa: https://devdocs.magento.com/guides/v2.3/config-guide/cli/config-cli-subcommands-cron.html

Mas o problema não é somente rodar os crons, mas se você rodar os crons enquanto tiver o queue ativado usando RabbitMQ, que vai utilizar os consumers. Você pode ler mais sobre queues e consumers aqui: https://devdocs.magento.com/guides/v2.3/config-guide/mq/rabbitmq-overview.html

Vamos dizer que você adicionou um novo módulo que irá consumir os queues ou você adicionou a configuração no app/etc/env.php:

'queue' =>
  array (
    'amqp' =>
    array (
      'host' => 'rabbitmq.example.com',
      'port' => '11213',
      'user' => 'magento',
      'password' => 'magento',
      'virtualhost' => '/',
      'ssl' => true,
      'ssl_options' => [
            'cafile' =>  '/etc/pki/tls/certs/DigiCertCA.crt',
            'certfile' => '/path/to/magento/app/etc/ssl/test-rabbit.crt',
            'keyfile' => '/path/to/magento/app/etc/ssl/test-rabbit.key'
       ],
     ),
  ),

Ou você adicionou o código abaixo durante a instalação:

--amqp-host="<hostname>" --amqp-port="5672" --amqp-user="<user_name>" --amqp-password="<password>" --amqp-virtualhost="/"

Bom, agora o Magento irá usar os consumers para trabalhar os queues. Aqui encontramos dois problemas. O primeiro é que sempre que o cron rodar, irá gerar processos no background com os consumers, como por exemplo:

$ kubectl exec -n my-store magento-75788af261-adwdc -c magento ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0  18048  1932 ?        Ss   14:13   0:00 /bin/bash /setup.sh
root        16  0.0  0.0   4284   588 ?        S    14:13   0:00 /bin/sh /usr/sbin/apache2ctl -D FOREGROUND
root        18  0.0  0.0 274652 19168 ?        S    14:13   0:00 /usr/sbin/apache2 -D FOREGROUND
www-data    20  0.9  0.2 344228 90216 ?        S    14:13   1:50 /usr/sbin/apache2 -D FOREGROUND
www-data    24  0.9  0.2 344232 86344 ?        S    14:13   1:41 /usr/sbin/apache2 -D FOREGROUND
www-data    59  0.0  0.2 291524 94128 ?        S    14:15   0:03 /usr/local/bin/php /var/www/html/bin/magento queue:consumers:start commonErrorManagement --pid-file-path=commonErrorManagement-magento76799dc865rglqw.pid --max-messages=10000
www-data    61  0.0  0.2 291524 94024 ?        S    14:15   0:03 /usr/local/bin/php /var/www/html/bin/magento queue:consumers:start ping --pid-file-path=ping-magento76799dc865rglqw.pid --max-messages=10000
www-data    63  0.0  0.3 317288 118348 ?       S    14:15   0:05 /usr/local/bin/php /var/www/html/bin/magento queue:consumers:start productConsumer --pid-file-path=productConsumer-magento76799dc865rglqw.pid --max-messages=10000
www-data    65  0.0  0.2 293740 95408 ?        S    14:15   0:03 /usr/local/bin/php /var/www/html/bin/magento queue:consumers:start stockConsumer --pid-file-path=stockConsumer-magento76799dc865rglqw.pid --max-messages=10000
www-data    67  0.0  0.2 293752 95652 ?        S    14:15   0:03 /usr/local/bin/php /var/www/html/bin/magento queue:consumers:start productReturnUpdatedConsumer --pid-file-path=productReturnUpdatedConsumer-magento76799dc865rglqw.pid --max-messages=10000
www-data    69  0.0  0.3 293704 97224 ?        S    14:15   0:03 /usr/local/bin/php /var/www/html/bin/magento queue:consumers:start refundUpdatedConsumer --pid-file-path=refundUpdatedConsumer-magento76799dc865rglqw.pid --max-messages=10000
www-data    71  0.0  0.3 317288 118240 ?       S    14:15   0:04 /usr/local/bin/php /var/www/html/bin/magento queue:consumers:start orderCancellation --pid-file-path=orderCancellation-magento76799dc865rglqw.pid --max-messages=10000
www-data    73  0.0  0.3 317288 118116 ?       S    14:15   0:04 /usr/local/bin/php /var/www/html/bin/magento queue:consumers:start orderGetNotifications --pid-file-path=orderGetNotifications-magento76799dc865rglqw.pid --max-messages=10000
www-data    75  0.0  0.3 317288 118440 ?       S    14:15   0:04 /usr/local/bin/php /var/www/html/bin/magento queue:consumers:start orderResendNotification --pid-file-path=orderResendNotification-magento76799dc865rglqw.pid --max-messages=10000
www-data    77  0.0  0.3 317292 118508 ?       S    14:15   0:04 /usr/local/bin/php /var/www/html/bin/magento queue:consumers:start orderConsumer --pid-file-path=orderConsumer-magento76799dc865rglqw.pid --max-messages=10000
www-data    79  0.0  0.2 291524 93944 ?        S    14:15   0:03 /usr/local/bin/php /var/www/html/bin/magento queue:consumers:start orderUpdatedConsumer --pid-file-path=orderUpdatedConsumer-magento76799dc865rglqw.pid --max-messages=10000
www-data    82  0.0  0.3 295756 97992 ?        S    14:15   0:03 /usr/local/bin/php /var/www/html/bin/magento queue:consumers:start customerShipmentDoneConsumer --pid-file-path=customerShipmentDoneConsumer-magento76799dc865rglqw.pid --max-messages=10000
www-data    84  0.0  0.2 291656 93784 ?        S    14:15   0:03 /usr/local/bin/php /var/www/html/bin/magento queue:consumers:start orderLineCancelledConsumer --pid-file-path=orderLineCancelledConsumer-magento76799dc865rglqw.pid --max-messages=10000
www-data    86  0.0  0.2 291656 94968 ?        S    14:15   0:03 /usr/local/bin/php /var/www/html/bin/magento queue:consumers:start shippingAddressUpdated --pid-file-path=shippingAddressUpdated-magento76799dc865rglqw.pid --max-messages=10000
www-data    92  0.0  0.3 317292 119656 ?       S    14:15   0:04 /usr/local/bin/php /var/www/html/bin/magento queue:consumers:start serviceBusDiscover --pid-file-path=serviceBusDiscover-magento76799dc865rglqw.pid --max-messages=10000
www-data    94  0.0  0.3 317292 118524 ?       S    14:15   0:04 /usr/local/bin/php /var/www/html/bin/magento queue:consumers:start async.operations.all --pid-file-path=async.operations.all-magento76799dc865rglqw.pid --max-messages=10000
www-data   178  1.6  0.2 336144 81796 ?        S    16:24   0:53 /usr/sbin/apache2 -D FOREGROUND
www-data   179  1.2  0.2 336220 83776 ?        S    16:24   0:42 /usr/sbin/apache2 -D FOREGROUND
www-data   195  1.3  0.2 336160 81964 ?        S    16:27   0:42 /usr/sbin/apache2 -D FOREGROUND
www-data   198  1.0  0.2 333196 74692 ?        S    16:30   0:31 /usr/sbin/apache2 -D FOREGROUND
www-data   199  1.0  0.2 333196 74696 ?        S    16:30   0:31 /usr/sbin/apache2 -D FOREGROUND
www-data   200  1.0  0.2 333212 74708 ?        S    16:30   0:29 /usr/sbin/apache2 -D FOREGROUND
www-data   201  1.3  0.2 333140 74632 ?        S    16:30   0:40 /usr/sbin/apache2 -D FOREGROUND
www-data   210  1.1  0.2 333140 74636 ?        S    16:30   0:34 /usr/sbin/apache2 -D FOREGROUND
root       440  0.0  0.0  36640  2712 ?        Rs   17:19   0:00 ps aux

Como pode ver acima, existe vários consumers rodando, eles são todos do Magento. Se você tiver algum queue customizado, ele irá aparecer na lista também. Agora é que o segundo problema aparece.
Magento tem na documentação que cada consumer processa 1000 mensagens e depois finaliza: https://devdocs.magento.com/guides/v2.3/config-guide/mq/manage-message-queues.html#configuration

max_messages - the maximum number of messages for each consumer that must be processed before consumer terminate, by default is 1000. If it is 0, then the consumer never stops working.

Mas como você pode ver acima, está configurado para 10000 e podemos confirmar no código: https://github.com/magento/magento2/blob/2.3-develop/app/code/Magento/MessageQueue/Model/Cron/ConsumersRunner.php#L114

Sem problemas se você estiver rodando o cron em um único ou vários servidores, mas assim que você inicializa o cron os processos no background também inicializam e somente finalizam quando 10000 mensagens são processadas (por padrão). O cron irã rodar até que o timeout do Kubernetes aconteça (padrão de uma hora).
Então poderiamos configurar o --max-messages para 1, mas da forma que o Magento funciona SEMPRE irá esperar por aquela 1 mensagem, ao invéz de checar se o queue está vazio e terminar. Existe um issue aberto no repositório deles, mas sem sinal de que algo será feito: https://github.com/magento/magento2/issues/17951

Então o que fazer: Bom, por agora decidimos rodar o Supervisord no seu próprio pod e os consumers dentro do Supervisord. E não esqueça de desabilitar os consumers durante o cron:

...
    'cron_consumers_runner' => array(
        'cron_run' => false
    ),
...

Espero que um dia a Magento considere fazer o Magento pronto para DevOps.
Caso você tenha feito de outra forma, não deixe de deixar seu comentário.


FacebookTwitterGoogle+Share

Comentar

HTML restrito

  • Tags HTML permitidas: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Quebras de linhas e parágrafos são gerados automaticamente.
  • Web page addresses and email addresses turn into links automatically.
CAPTCHA
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.