yii2框架添加异步daemon

本文介绍如何在Yii2中创建基于Redis List的异步队列进程。通过在commands目录下创建Controller,利用PHP CLI启动守护进程,监控并fork子进程处理队列任务。详细讲解了启动流程、daemon控制器的编写以及配置文件设置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在PHP的yii2框架中,有时候需要一些异步队列的功能,这篇文章主要写如何自己增加几个文件创建一个基于redis list的异步队列进程。
在yii2的框架里,要用到php-cli进程,需要将Controller放入commands文件夹中,并且使用php ./yii ...的方式进行调用。

首先创建一个Controller用于启动异步队列,代码如下:

<?php
namespace app\commands\daemon;

use yii\console\Controller;
use Yii;

class DaemonController extends Controller
{
   
    private $running_children_pid = [];
    
    private $running = true;
    private static $_master_pid;
    public static $pid_file;
    private $alarm_times = 0;
    private $pid = 0;

    public function __construct($id, $module, $config = array())
    {
   
        $this->checkPcntl();
        static::$pid_file = __DIR__ . "/../../runtime/dasheng_yii_daemon.pid";
        parent::__construct($id, $module, $config);
    }
    
    //检查环境是否支持pcntl支持
    private function checkPcntl()
    {
   
        // Make sure PHP has support for pcntl
        if (!function_exists('pcntl_signal')) {
   
            $message = 'PHP does not appear to be compiled with the PCNTL extension.  This is neccesary for daemonization';
            echo $message;
            throw new \Exception($message);
        }
        
    }
    
    private function killallChildren()
    {
   
        foreach ($this->running_children_pid as $pname => $pids) {
   
            foreach ($pids as $pid) {
   
                posix_kill($pid, SIGQUIT);
            }
        }
    }

    private function sendWarningMail($msg)
    {
   
        try {
   
            Yii::$app->mailer->compose()
                ->setFrom('***')
                ->setTo('***')
                ->setSubject('daemon服务器报警')
                ->setHtmlBody("<html>$msg</html>")
                ->send();
        } catch (\Exception $e) {
   
            \Yii::warning("【daemon服务器报警】发送预警邮件失败>>>" . $e->getMessage());
        }
    }
    
    //信号处理函数
    public function signalHandler($signo)
    {
   
        EchoFormat::out("" . $this->pid . " signalHandler($signo)");
        switch ($signo) {
   
            //子进程结束信号,可能会有多个子进程结束,用同一个信号,所以while里也要wait
            case SIGCHLD:
                $stopped_pid = pcntl_wait($status, WNOHANG);
                EchoFormat::out($this->pid." wait pid=".$stopped_pid);
                $this->removePid($stopped_pid);

                //发送报警
                if($this->running)
                {
   
                    EchoFormat::out("running");
                    ++$this->alarm_times;
                    switch ($this->alarm_times)
                    {
   
                        case 1:
                        case 10:
                        case 100:
                            $ip_info = shell_exec('ifconfig');
                            $this->sendWarningMail("<pre>$ip_info</pre>");
                            break;
                        default:
                            break;
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值