@@ -462,22 +462,23 @@ Deploying to Production
462
462
463
463
On production, there are a few important things to think about:
464
464
465
- **Use Supervisor to keep your worker(s) running **
465
+ **Use a process manager like Supervisor or systemd to keep your worker(s) running **
466
466
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 >`.
468
469
469
470
**Don't Let Workers Run Forever **
470
471
Some services (like Doctrine's EntityManager) will consume more memory
471
472
over time. So, instead of allowing your worker to run forever, use a flag
472
473
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
474
475
are also other options like ``--memory-limit=128M `` and ``--time-limit=3600 ``.
475
476
476
477
**Restart Workers on Deploy **
477
478
Each time you deploy, you'll need to restart all your worker processes so
478
479
that they see the newly deployed code. To do this, run ``messenger:stop-workers ``
479
480
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
481
+ it's currently handling and shut down gracefully. Then, the process manager will create
481
482
new worker processes. The command uses the :ref: `app <cache-configuration-with-frameworkbundle >`
482
483
cache internally - so make sure this is configured to use an adapter you like.
483
484
@@ -633,6 +634,132 @@ config and start your workers:
633
634
634
635
See the `Supervisor docs `_ for more details.
635
636
637
+ If a worker dependency like your database server is down, or timeout is reached,
638
+ you can try to add reconnect logic, or just quit the worker (catch Exception,
639
+ PDOException or do something more fine grained):
640
+
641
+ // SomeMessageHandler.php
642
+ public function __invoke(SomeMessage $message): void
643
+ {
644
+ try {
645
+ $thing = $this->someRepository->find($message->getThingId());
646
+ if (null === $thing) {
647
+ return;
648
+ }
649
+ $this->thingService->doStuff($thing);
650
+ } catch (\E xception $e) {
651
+ echo 'Received exception "'.$e->getMessage().'" from "'.get_class($e).'". Quitting worker';
652
+ exit(1);
653
+ }
654
+ }
655
+
656
+ But, then you can end up in a situation where the supervisor job gets into a
657
+ FATAL (too many start retries) state. You can prevent this by wrapping the
658
+ Symfony script with a shell script:
659
+
660
+ .. code-block :: bash
661
+
662
+ #! /bin/bash
663
+
664
+ # Supervisor sends TERM to services when stopped.
665
+ # This wrapper has to pass the signal to it's child.
666
+ # Note that we send TERM (graceful) instead of KILL (immediate).
667
+ _term () {
668
+ echo " [GOT TERM, SIGNALING CHILD]"
669
+ kill -TERM $child 2> /dev/null
670
+ exit 1
671
+ }
672
+
673
+ trap _term SIGTERM
674
+
675
+ # Execute console.php with whatever arguments were specified to this script
676
+ " $@ " &
677
+ child=$!
678
+ wait " $child "
679
+
680
+ # Delay to prevent supervisor from restarting too fast on failure
681
+ sleep 30
682
+
683
+ # Return 1 so supervisor will restart the script
684
+ exit 1
685
+
686
+ The worker would then look like this:
687
+
688
+ .. code-block :: ini
689
+
690
+ ; /etc/supervisor/conf.d/messenger-worker.conf
691
+ [program:messenger-consume]
692
+ command =/path/to/your/console_wrapper php /path/to/your/app/bin/console messenger:consume async --time-limit =3600
693
+ ...
694
+
695
+ .. _messenger-systemd :
696
+
697
+ Systemd Configuration
698
+ ~~~~~~~~~~~~~~~~~~~~~
699
+
700
+ While Supervisor is a great tool, it has the disadvantage that you need system
701
+ access to run it. Systemd has become the standard on most Linux distributions,
702
+ and has a good alternative called user services.
703
+
704
+ Systemd user service configuration files typically live in a ``~/.config/systemd/user ``
705
+ directory. For example, you can create a new ``messenger-worker.service `` file. Or a
706
+ ``
[email protected] `` file if you want more instances running at the same time:
707
+
708
+ .. code-block :: text
709
+
710
+ [Unit]
711
+ Description=Symfony messenger-consume %i
712
+
713
+ [Service]
714
+ ExecStart=php /path/to/your/app/bin/console messenger:consume async --time-limit=3600
715
+ Restart=always
716
+ RestartSec=30
717
+
718
+ [Journal]
719
+ Storage=persistent
720
+
721
+ [Install]
722
+ WantedBy=default.target
723
+
724
+ Now, tell systemd to enable and start one worker:
725
+
726
+ .. code-block :: terminal
727
+
728
+ $ systemctl --user enable [email protected]
729
+
730
+ $ systemctl --user start [email protected]
731
+
732
+ Then enable and start another 19:
733
+
734
+ .. code-block :: terminal
735
+
736
+ $ systemctl --user enable messenger-worker@{2..20}.service
737
+
738
+ $ systemctl --user start messenger-worker@{2..20}.service
739
+
740
+ If you would change your service config file, reload the daemon:
741
+
742
+ .. code-block :: terminal
743
+
744
+ $ systemctl --user daemon-reload
745
+
746
+ Restart all your consumers:
747
+
748
+ .. code-block :: terminal
749
+
750
+ $ systemctl --user restart messenger-consume@*.service
751
+
752
+ Logs are manged by journald and can be worked with using the journalctl
753
+ command, but you do need elevated privileges (sudo) for that:
754
+
755
+ .. code-block :: terminal
756
+
757
+ $ sudo journalctl -f [email protected]
758
+
759
+ $ sudo journalctl -f _UID=$UID
760
+
761
+ See the `systemd docs `_ for more details.
762
+
636
763
.. _messenger-retries-failures :
637
764
638
765
Retries & Failures
@@ -1663,4 +1790,5 @@ Learn more
1663
1790
.. _`Enqueue's transport` : https://github.com/sroze/messenger-enqueue-transport
1664
1791
.. _`streams` : https://redis.io/topics/streams-intro
1665
1792
.. _`Supervisor docs` : http://supervisord.org/
1793
+ .. _`systemd docs` : https://www.freedesktop.org/wiki/Software/systemd/
1666
1794
.. _`SymfonyCasts' message serializer tutorial` : https://symfonycasts.com/screencast/messenger/transport-serializer
0 commit comments