信号处理器

信号处理器会监听 Worker 进程和 自定义 进程启动后,自动注册到信号管理器中。

安装

  1. composer require hyperf/signal

发布配置

您可以通过下面的命令来发布默认的配置文件到您的项目中:

  1. php bin/hyperf.php vendor:publish hyperf/signal

添加处理器

以下我们监听 Worker 进程的 SIGTERM 信号,当收到信号后,打印出信号值。

  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Signal;
  4. use Hyperf\Signal\Annotation\Signal;
  5. use Hyperf\Signal\SignalHandlerInterface;
  6. /**
  7. * @Signal
  8. */
  9. class TermSignalHandler implements SignalHandlerInterface
  10. {
  11. public function listen(): array
  12. {
  13. return [
  14. [SignalHandlerInterface::WORKER, SIGTERM],
  15. ];
  16. }
  17. public function handle(int $signal): void
  18. {
  19. var_dump($signal);
  20. }
  21. }

因为 Worker 进程接收的 SIGTERM 信号被捕获后,无法正常退出,所以用户可以直接 Ctrl + C 退出,或者修改 config/autoload/signal.php 配置,如下:

WorkerStopHandler 不适配于 CoroutineServer,如有需要请自行实现

  1. <?php
  2. declare(strict_types=1);
  3. return [
  4. 'handlers' => [
  5. Hyperf\Signal\Handler\WorkerStopHandler::class => PHP_INT_MIN
  6. ],
  7. 'timeout' => 5.0,
  8. ];

WorkerStopHandler 触发后,会在所设置的 max_wait_time 配置时间后,关闭掉当前进程。

协程风格服务监听器配置示例

以上默认的监听器都是适配于异步风格服务的,如果需要在协程风格服务下使用,可以按照以下自定义配置

  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Kernel\Signal;
  4. use Hyperf\AsyncQueue\Driver\Driver;
  5. use Hyperf\Contract\ConfigInterface;
  6. use Hyperf\Process\ProcessManager;
  7. use Hyperf\Server\ServerManager;
  8. use Hyperf\Signal\SignalHandlerInterface;
  9. use Psr\Container\ContainerInterface;
  10. class CoroutineServerStopHandler implements SignalHandlerInterface
  11. {
  12. /**
  13. * @var ContainerInterface
  14. */
  15. protected $container;
  16. /**
  17. * @var ConfigInterface
  18. */
  19. protected $config;
  20. public function __construct(ContainerInterface $container)
  21. {
  22. $this->container = $container;
  23. $this->config = $container->get(ConfigInterface::class);
  24. }
  25. public function listen(): array
  26. {
  27. // 协程风格只会存在一个 Worker 进程,故这里只需要监听 WORKER 即可
  28. return [
  29. [self::WORKER, SIGTERM],
  30. [self::WORKER, SIGINT],
  31. ];
  32. }
  33. public function handle(int $signal): void
  34. {
  35. ProcessManager::setRunning(false);
  36. foreach (ServerManager::list() as [$type, $server]) {
  37. // 循环关闭开启的服务
  38. $server->shutdown();
  39. }
  40. }
  41. }