Skip to content

Commit 167259d

Browse files
committed
minor #13597 Messenger process managers (tvlooy)
This PR was submitted for the 5.1 branch but it was merged into the 5.4 branch instead. Discussion ---------- Messenger process managers Add information about mysql timeouts, supervisor FATAL, systemd user services. Or, how should you handle this MySQL timeout issue, supervisor restart (FATAL) issues? How do you people do this? What does the component author thinks about this? I myself am using with systemd user services in production for a while and it's running okay. Commits ------- 1560584 Add documentation of Supervisor BACKOFF strategy 09fd70c Messenger process managers
2 parents 78452d9 + 1560584 commit 167259d

File tree

1 file changed

+112
-6
lines changed

1 file changed

+112
-6
lines changed

messenger.rst

+112-6
Original file line numberDiff line numberDiff line change
@@ -486,23 +486,30 @@ Deploying to Production
486486

487487
On production, there are a few important things to think about:
488488

489-
**Use Supervisor to keep your worker(s) running**
489+
**Use a Process Manager like Supervisor or systemd to keep your worker(s) running**
490490
You'll want one or more "workers" running at all times. To do that, use a
491-
process control system like :ref:`Supervisor <messenger-supervisor>`.
491+
process control system like :ref:`Supervisor <messenger-supervisor>`
492+
or :ref:`systemd <messenger-systemd>`.
492493

493494
**Don't Let Workers Run Forever**
494495
Some services (like Doctrine's ``EntityManager``) will consume more memory
495496
over time. So, instead of allowing your worker to run forever, use a flag
496497
like ``messenger:consume --limit=10`` to tell your worker to only handle 10
497-
messages before exiting (then Supervisor will create a new process). There
498+
messages before exiting (then the process manager will create a new process). There
498499
are also other options like ``--memory-limit=128M`` and ``--time-limit=3600``.
499500

501+
**Stopping Workers That Encounter Errors**
502+
If a worker dependency like your database server is down, or timeout is reached,
503+
you can try to add :ref:`reconnect logic <middleware-doctrine>`, or just quit
504+
the worker if it receives too many errors with the ``--failure-limit`` option of
505+
the ``messenger:consume`` command.
506+
500507
**Restart Workers on Deploy**
501508
Each time you deploy, you'll need to restart all your worker processes so
502509
that they see the newly deployed code. To do this, run ``messenger:stop-workers``
503510
on deployment. This will signal to each worker that it should finish the message
504-
it's currently handling and should shut down gracefully. Then, Supervisor will create
505-
new worker processes. The command uses the :ref:`app <cache-configuration-with-frameworkbundle>`
511+
it's currently handling and should shut down gracefully. Then, the process manager
512+
will create new worker processes. The command uses the :ref:`app <cache-configuration-with-frameworkbundle>`
506513
cache internally - so make sure this is configured to use an adapter you like.
507514

508515
**Use the Same Cache Between Deploys**
@@ -669,11 +676,25 @@ times:
669676
startsecs=0
670677
autostart=true
671678
autorestart=true
679+
startretries=10
672680
process_name=%(program_name)s_%(process_num)02d
673681
674682
Change the ``async`` argument to use the name of your transport (or transports)
675683
and ``user`` to the Unix user on your server.
676684

685+
.. caution::
686+
687+
During a deployment, something might be unavailable (e.g. the
688+
database) causing the consumer to fail to start. In this situation,
689+
Supervisor will try ``startretries`` number of times to restart the
690+
command. Make sure to change this setting to avoid getting the command
691+
in a FATAL state, which will never restart again.
692+
693+
Each restart, Supervisor increases the delay by 1 second. For instance, if
694+
the value is ``10``, it will wait 1 sec, 2 sec, 3 sec, etc. This gives the
695+
service a total of 55 seconds to become available again. Increase the
696+
``startretries`` setting to cover the maximum expected downtime.
697+
677698
If you use the Redis Transport, note that each worker needs a unique consumer
678699
name to avoid the same message being handled by multiple workers. One way to
679700
achieve this is to set an environment variable in the Supervisor configuration
@@ -696,7 +717,7 @@ Next, tell Supervisor to read your config and start your workers:
696717
See the `Supervisor docs`_ for more details.
697718

698719
Graceful Shutdown
699-
~~~~~~~~~~~~~~~~~
720+
.................
700721

701722
If you install the `PCNTL`_ PHP extension in your project, workers will handle
702723
the ``SIGTERM`` POSIX signal to finish processing their current message before
@@ -712,6 +733,88 @@ of the desired grace period in seconds) in order to perform a graceful shutdown:
712733
[program:x]
713734
stopwaitsecs=20
714735
736+
.. _messenger-systemd:
737+
738+
Systemd Configuration
739+
~~~~~~~~~~~~~~~~~~~~~
740+
741+
While Supervisor is a great tool, it has the disadvantage that you need system
742+
access to run it. Systemd has become the standard on most Linux distributions,
743+
and has a good alternative called *user services*.
744+
745+
Systemd user service configuration files typically live in a ``~/.config/systemd/user``
746+
directory. For example, you can create a new ``messenger-worker.service`` file. Or a
747+
``[email protected]`` file if you want more instances running at the same time:
748+
749+
.. code-block:: ini
750+
751+
[Unit]
752+
Description=Symfony messenger-consume %i
753+
754+
[Service]
755+
ExecStart=php /path/to/your/app/bin/console messenger:consume async --time-limit=3600
756+
Restart=always
757+
RestartSec=30
758+
759+
[Install]
760+
WantedBy=default.target
761+
762+
Now, tell systemd to enable and start one worker:
763+
764+
.. code-block:: terminal
765+
766+
$ systemctl --user enable [email protected]
767+
$ systemctl --user start [email protected]
768+
769+
# to enable and start 20 workers
770+
$ systemctl --user enable messenger-worker@{1..20}.service
771+
$ systemctl --user start messenger-worker@{1..20}.service
772+
773+
If you change your service config file, you need to reload the daemon:
774+
775+
.. code-block:: terminal
776+
777+
$ systemctl --user daemon-reload
778+
779+
To restart all your consumers:
780+
781+
.. code-block:: terminal
782+
783+
$ systemctl --user restart messenger-consume@*.service
784+
785+
The systemd user instance is only started after the first login of the
786+
particular user. Consumer often need to start on system boot instead.
787+
Enable lingering on the user to activate that behavior:
788+
789+
.. code-block:: terminal
790+
791+
$ loginctl enable-linger <your-username>
792+
793+
Logs are managed by journald and can be worked with using the journalctl
794+
command:
795+
796+
.. code-block:: terminal
797+
798+
# follow logs of consumer nr 11
799+
$ journalctl -f --user-unit [email protected]
800+
801+
# follow logs of all consumers
802+
$ journalctl -f --user-unit messenger-consume@*
803+
804+
# follow all logs from your user services
805+
$ journalctl -f _UID=$UID
806+
807+
See the `systemd docs`_ for more details.
808+
809+
.. note::
810+
811+
You either need elevated privileges for the ``journalctl`` command, or add
812+
your user to the systemd-journal group:
813+
814+
.. code-block:: terminal
815+
816+
$ sudo usermod -a -G systemd-journal <your-username>
817+
715818
Stateless Worker
716819
~~~~~~~~~~~~~~~~
717820

@@ -2190,6 +2293,8 @@ middleware and *only* include your own:
21902293
If a middleware service is abstract, a different instance of the service will
21912294
be created per bus.
21922295

2296+
.. _middleware-doctrine:
2297+
21932298
Middleware for Doctrine
21942299
~~~~~~~~~~~~~~~~~~~~~~~
21952300

@@ -2377,6 +2482,7 @@ Learn more
23772482
.. _`streams`: https://redis.io/topics/streams-intro
23782483
.. _`Supervisor docs`: http://supervisord.org/
23792484
.. _`PCNTL`: https://www.php.net/manual/book.pcntl.php
2485+
.. _`systemd docs`: https://www.freedesktop.org/wiki/Software/systemd/
23802486
.. _`SymfonyCasts' message serializer tutorial`: https://symfonycasts.com/screencast/messenger/transport-serializer
23812487
.. _`Long polling`: https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-short-and-long-polling.html
23822488
.. _`Visibility Timeout`: https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-visibility-timeout.html

0 commit comments

Comments
 (0)