@@ -462,22 +462,29 @@ Deploying to Production
462462
463463On production, there are a few important things to think about:
464464
465- **Use Supervisor to keep your worker(s) running **
465+ **Use a process manager like Supervisor or systemd to keep your worker(s) running **
466466 You'll want one or more "workers" running at all times. To do that, use a
467- process control system like :ref: `Supervisor <messenger-supervisor >`.
467+ process control system like :ref: `Supervisor <messenger-supervisor >`
468+ or :ref: `systemd <messenger-systemd >`.
468469
469470**Don't Let Workers Run Forever **
470471 Some services (like Doctrine's EntityManager) will consume more memory
471472 over time. So, instead of allowing your worker to run forever, use a flag
472473 like ``messenger:consume --limit=10 `` to tell your worker to only handle 10
473- messages before exiting (then Supervisor will create a new process). There
474+ messages before exiting (then the process manager will create a new process). There
474475 are also other options like ``--memory-limit=128M `` and ``--time-limit=3600 ``.
475476
477+ **Stopping Workers That Encounter Errors **
478+ If a worker dependency like your database server is down, or timeout is reached,
479+ you can try to add :ref: `reconnect logic <middleware-doctrine >`, or just quit
480+ the worker if it receives too many errors with the ``--failure-limit `` option of
481+ the ``messenger:consume `` command.
482+
476483**Restart Workers on Deploy **
477484 Each time you deploy, you'll need to restart all your worker processes so
478485 that they see the newly deployed code. To do this, run ``messenger:stop-workers ``
479486 on deploy. This will signal to each worker that it should finish the message
480- it's currently handling and shut down gracefully. Then, Supervisor will create
487+ it's currently handling and shut down gracefully. Then, the process manager will create
481488 new worker processes. The command uses the :ref: `app <cache-configuration-with-frameworkbundle >`
482489 cache internally - so make sure this is configured to use an adapter you like.
483490
@@ -633,6 +640,131 @@ config and start your workers:
633640
634641 See the `Supervisor docs `_ for more details.
635642
643+ It is possible to end up in a situation where the supervisor job gets into a
644+ FATAL (too many start retries) state when trying to restart when something is
645+ not yet available. You can prevent this by wrapping the Symfony script with a
646+ shell script and sleep when the script fails:
647+
648+ .. code-block :: bash
649+
650+ #! /usr/bin/env bash
651+
652+ # Supervisor sends TERM to services when stopped.
653+ # This wrapper has to pass the signal to it's child.
654+ # Note that we send TERM (graceful) instead of KILL (immediate).
655+ _term () {
656+ echo " [GOT TERM, SIGNALING CHILD]"
657+ kill -TERM " $child " 2> /dev/null
658+ exit 1
659+ }
660+
661+ trap _term SIGTERM
662+
663+ # Execute console.php with whatever arguments were specified to this script
664+ " $@ " &
665+ child=$!
666+ wait " $child "
667+ rc=$?
668+
669+ # Delay to prevent supervisor from restarting too fast on failure
670+ sleep 30
671+
672+ # Return with the exit code of the wrapped process
673+ exit $rc
674+
675+ The supervisor job would then look like this:
676+
677+ .. code-block :: ini
678+
679+ ; /etc/supervisor/conf.d/messenger-worker.conf
680+ [program:messenger-consume]
681+ command =/path/to/your/app/bin/console_wrapper php /path/to/your/app/bin/console messenger:consume async --time-limit =3600"
682+ ...
683+
684+ .. _messenger-systemd :
685+
686+ Systemd Configuration
687+ ~~~~~~~~~~~~~~~~~~~~~
688+
689+ While Supervisor is a great tool, it has the disadvantage that you need system
690+ access to run it. Systemd has become the standard on most Linux distributions,
691+ and has a good alternative called user services.
692+
693+ Systemd user service configuration files typically live in a ``~/.config/systemd/user ``
694+ directory. For example, you can create a new ``messenger-worker.service `` file. Or a
695+ ``
[email protected] `` file if you want more instances running at the same time:
696+
697+ .. code-block :: ini
698+
699+ [Unit]
700+ Description =Symfony messenger-consume %i
701+
702+ [Service]
703+ ExecStart =php /path/to/your/app/bin/console messenger:consume async --time-limit =3600
704+ Restart =always
705+ RestartSec =30
706+
707+ [Install]
708+ WantedBy =default.target
709+
710+ Now, tell systemd to enable and start one worker:
711+
712+ .. code-block :: terminal
713+
714+ $ systemctl --user enable [email protected] 715+
716+ $ systemctl --user start [email protected] 717+
718+ Then enable and start another 19:
719+
720+ .. code-block :: terminal
721+
722+ $ systemctl --user enable messenger-worker@{2..20}.service
723+
724+ $ systemctl --user start messenger-worker@{2..20}.service
725+
726+ If you would change your service config file, reload the daemon:
727+
728+ .. code-block :: terminal
729+
730+ $ systemctl --user daemon-reload
731+
732+ Restart all your consumers:
733+
734+ .. code-block :: terminal
735+
736+ $ systemctl --user restart messenger-consume@*.service
737+
738+ The systemd user instance is only started after the first login of the
739+ particular user. We want to start our workers on system boot instead. Enable
740+ lingering on the user to activate that behavior:
741+
742+ .. code-block :: terminal
743+
744+ $ loginctl enable-linger <your-username>
745+
746+ Logs are managed by journald and can be worked with using the journalctl
747+ command, but you do need elevated privileges for that, or add your user to the
748+ systemd-journal group:
749+
750+ .. code-block :: terminal
751+
752+ $ sudo usermod -a -G systemd-journal <your-username>
753+
754+ Now you can watch your service logs as your user, for example tail and follow
755+ the logs of
[email protected] , all messenger-consume services, or
756+ tail and follow all logs for your user ID:
757+
758+ .. code-block :: terminal
759+
760+ $ journalctl -f --user-unit [email protected] 761+
762+ $ journalctl -f --user-unit messenger-consume@*
763+
764+ $ journalctl -f _UID=$UID
765+
766+ See the `systemd docs `_ for more details.
767+
636768.. _messenger-retries-failures :
637769
638770Retries & Failures
@@ -1541,6 +1673,8 @@ middleware and *only* include your own:
15411673 If a middleware service is abstract, a different instance of the service will
15421674 be created per bus.
15431675
1676+ .. _middleware-doctrine :
1677+
15441678Middleware for Doctrine
15451679~~~~~~~~~~~~~~~~~~~~~~~
15461680
@@ -1663,4 +1797,5 @@ Learn more
16631797.. _`Enqueue's transport` : https://github.com/sroze/messenger-enqueue-transport
16641798.. _`streams` : https://redis.io/topics/streams-intro
16651799.. _`Supervisor docs` : http://supervisord.org/
1800+ .. _`systemd docs` : https://www.freedesktop.org/wiki/Software/systemd/
16661801.. _`SymfonyCasts' message serializer tutorial` : https://symfonycasts.com/screencast/messenger/transport-serializer
0 commit comments