consik/yii2-daemons

为创建带有systemd单元的PHP守护进程的Yii2扩展

安装: 557

依赖项: 0

建议者: 0

安全: 0

星级: 0

关注者: 2

分支: 0

开放问题: 0

类型:yii2-extension

1.0.1 2017-01-05 16:29 UTC

This package is not auto-updated.

Last update: 2024-09-14 20:15:00 UTC


README

Latest Stable Version Total Downloads License

介绍

使用pcntl_fork()或其他方法没有具体的守护进程化PHP脚本的实现。当我们有像systemd这样的可以将我们的PHP脚本做成服务的包时,我们不需要它。因此,在包中有DaemonInterface,它只包含两个方法startDaemon()和stopDaemon(),以及一个实现了此接口的AbstractLoopDaemon。

您可以使用自己的脚本,该脚本在后台运行,只需在那里实现DaemonInterface。

使您的PHP脚本成为守护进程的所有函数都将由systemd和ServiceController执行。

安装

安装此扩展的首选方式是通过 composer

运行

composer require consik/yii2-daemons

或添加

"consik/yii2-daemons": "^1.0"

创建守护进程。

如我上面所说,您只需要实现DaemonInterface。

简单的循环守护进程

<?php
class TestDaemon implements DaemonInterface
{
	private $stop = false;
	private $counter = 0;

	public function startDaemon()
	{
		while (!$this->stop) {
			$counter++;
			sleep(1)
		}
	}

	public function stopDaemon()
	{
		$this->stop = true;
	}
}

在这个实现中,stopDaemon()从不被调用,当守护进程被终止时,我们丢失了结果;

现在让我们通过扩展AbstractLoopDaemon和此包中的ServiceConfigInterface和LoopDaemonSignalsBehavior扩展来创建相同的守护进程。

<?php
namespace app\daemons;

use consik\yii2daemons\daemons\AbstractLoopDaemon;
use consik\yii2daemons\daemons\behaviors\LoopDaemonSignalsBehavior;
use consik\yii2daemons\service\ServiceConfigInterface;

class TestDaemon extends AbstractLoopDaemon implements ServiceConfigInterface
{
    public $serviceConfig = [];
	protected $i = 1;
    protected $iterationTimeout = 10;

    public function getServiceConfig()
    {
        return $this->serviceConfig;
    }

	public function behaviors()
    {
        return[
            [
                'class' => LoopDaemonSignalsBehavior::className(),
                'signalHandlers' => [SIGTERM => [$this, 'stopDaemon']]
            ]
        ];
    }

    public function stopDaemon()
    {
        echo $this->i;
        parent::stopDaemon();
    }

    protected function iterate()
    {
        $this->i++;
    }
}

此守护进程每10秒将$i增加1。同时使用LoopDaemonSignalsBehavior,我们处理SIGTERM信号,它调度'stopDaemon'方法。当守护进程停止时,它将输出当前$i的值。

有关处理信号的信息,请参阅有关pcntl_signal()的文档。为了便于实现,如果您扩展了AbstractLoopDaemon,则可以使用HandleSignalsBehavior或LoopDaemonSignalsBehavior。如果您使用HandleSignalsBehavior,不要忘记调用$this->callSignalDispatch()pcntl_signal_dispatch()

ServiceConfigInterface有一个getServiceConfig()方法。此方法将由ServiceController用于获取当前守护进程systemd单元的参数。

使用ServiceController

在您的应用程序中使用ServiceController,以便轻松创建systemd单元并控制您的守护进程。

config\console.php

<?php
...
'controllerMap' => [
        'service' => [
            'class' => '\consik\yii2daemons\service\ServiceController',
			'daemons' => [
                'testDaemon' => [
                    'class' => 'app\daemons\TestDaemon',
                ]
            ]
		]
	]
...

生成systemd单元

要生成systemd单元文件,请使用此命令:php yii service/systemd-file DaemonName

注册服务

ServiceController只能通过action systemd-file生成systemd单元(*.service)文件。在包中有一个用于快速在系统中注册systemd单元的bash脚本。使用示例,在服务控制器配置后

sudo bash vendor\consik\yii2-daemons\service\systemd.register ServiceName "$(php yii service/systemd-file DaemonName)"

注意:如果不想混淆,请使用与DaemonName相同的ServiceName。

控制您的守护进程

检查您的守护进程状态:sudo systemctl status ServiceName

启动服务:sudo systemctl start ServiceName

重启服务 sudo systemctl restart ServiceName

停止服务:sudo systemctl stop ServiceName

您还可以使用ServiceController的方法,如statusstop,但最好使用systemctl功能

通过ServiceController检查状态

sudo php yii service/status DaemonName

通过向守护进程进程发送SIGTERM信号来停止守护进程

sudo php yii service/stop DaemonName

有关单元文件配置和控制您的守护进程的更多信息,请参阅man systemd

配置systemd单元

有三个参数来源用于生成systemd单元。以下所有来源的数组结构如下

...
[
	'SectionName' => [
		'ParamName' => 'ParamValue'
	]
]
...

它等于服务单元文件

[SectionName]
ParamName=ParamValue

有关可用选项,请参阅官方文档

以下所有配置来源按优先级排序

混凝土守护进程服务配置。覆盖通用服务配置。

如果守护进程实现了 ServiceConfigInterface 接口,则将使用它。服务控制器调用 getServiceConfig() 方法来获取配置。例如,为每个守护进程设置 systemd 单元参数

在您的守护进程中实现 ServiceConfigInterface 并声明函数 getServiceConfig()

定义您的守护进程配置参数

  • 简单的方法是声明一个公共变量,您可以在控制器守护进程定义中更改它,并在 getServiceConfig() 中返回该变量;

    守护进程代码

     public $serviceConfig = [];
     public function getServiceConfig()
     {
     	return $this->serviceConfig;
     }
    

    Yii2 控制台配置文件

     	...
     	'controllerMap' => [
     	'service' => [
     	    'class' => '\consik\yii2daemons\service\ServiceController',
     			'daemons' => [
     				'testDaemon' => [
     					'class' => 'app\daemons\TestDaemon',
     					'serviceConfig' => [
     						'Service' => ['Type' => 'forking']
     					],
     				]
     			]
     		]
     	]
     	...
  • 或者在守护进程中实现自己的 getServiceConfig 函数,该函数将返回配置参数

     	public function getServiceConfig()
     	{
     		return [
     			'Service' => ['Type' => 'forking']
     		];
     	}

通用服务配置。覆盖基本服务配置。变量 ServiceController::$commonServiceConfig。

It can be changed in your controller configuration. Yii2 console config file:
```php
	...
	'controllerMap' => [
		'service' => [
		    'class' => '\consik\yii2daemons\service\ServiceController',
		    'commonServiceConfig' => [
					'Service' => ['Type' => 'forking']
				],
		],
	]
	...
```

基本服务配置。优先级最低的参数。通过方法 ServiceController::getBasicServiceConfig(string $daemonName) 返回。

此方法返回所有守护进程的基本 systemd 单元配置(Service: ExecStart,Type;Unit:描述,After;Install:WantedBy)。默认情况下,所有生成的服务都在 mysql.service 之后启动。如果不需要它或您的守护进程有其他依赖项(例如 mongodb.service),请覆盖 Unit 部分的 After 参数。

在生成每个守护进程配置文件之前,将通过 array_replace_recursive() 合并所有这些配置;