如何通过监控重启服务呢?

qq7467466

问题描述

我在db里面插入一条记录,每条记录代表代表一个进程, 如果有新的进程进来或者状态更新, 那么需要新增进程/禁用相应的进程,这样的功能应该如何实现呢?

想到的解决方案

简单粗暴的方法就行通过php start.php restart -d 去执行重启命令, 但是因为db里面的数据是随时可能发生变化的, 不能每次都去手动的执行重启, 因此想到了借鉴内存溢出重启/文件监控的方案, posix_kill($ppid, SIGUSR1) 但是测试了下是直接重启的当前进程, 我新增的进程不会,所以应该要如何搞呢, 有指令可以发送重启的命令吗? 测试过了reload不符合我的业务逻辑,必须用restart

这是我插件自定的process, kafkaConfig是DB读出来的数据

$process = [];
foreach ($kafkaConfig as $value) {
    if($value){
        $process[$value['app_uid']] = [
            'handler'     => \app\queue\kafka\Events::class,
            'count'       => $value['count'], // 进程数
            //'user'    => $group_id,
            //'group'   => $group_id,
            'constructor' => [
                'groupId'    => $value['app_uid'],
                'partition'  => $value['partition'],
                'messageKey' => $value['messageKey'] ?? '',
            ]
        ];
    }
}
return $process;

新起一个监控进程monitor_kafka_config

检测DB数据...发生改变,执行一下命令

测试的命令
$ppid = posix_getppid();
$pid = posix_getpid();
posix_kill($ppid, SIGINT);
posix_kill($pid, SIGUSR1);
531 4 0
4个回答

软饭工程师

这是我的一些大致想法
1,是否真的需要重启进程?能否以数据或者回调函数来驱动进程内逻辑的执行
2,是否可以使用自定义进程之类的方法,提前启动需要的进程,然后进行进程分配,老大说的重启单个进程 https://www.workerman.net/q/510
3,是否可以使用fork子进程的方法来创建进程并销毁进程,只创建和销毁进程,不重启

  • qq7467466 2023-08-23

    这个我试过, 因为我process里面最终不是return 出来一个数组吗? 动态的, kill掉并重启的话只会重启第一次渲染出来process, 比如说我首次动态启动了5个进程, 然后这时候db增加了1个进程, 按理说kill掉主进程之后这时候应该会出来6个进程, 但是测试的时候并不会把新的进程自动启动进来

  • 软饭工程师 2023-08-23

    既然这样,你想办法把进程数写到服务器环境变量里或者写到文件里,然后kill 掉所有的webman 进程,包括主进程,然后用supervisord拉起webman 主进程并读取进程数量

  • 软饭工程师 2023-08-23

    也就是说把进程数量做持久化,然后主动杀死所有的webman进程,这个时候进程数还在,读取进程数,然后依赖docker 健康检查或者supervisord 把webman 服务拉起来

  • qq7467466 2023-08-23

    感谢大佬回复, 我试下在主程序里面直接kill掉主进程, 然后用supervisord拉起进程

  • 软饭工程师 2023-08-23

    直接使用php start.php stop 杀死进程,然后用supervisord或者docker 健康检查拉起进程

北月

首选 workerman 不支持业务调用 pcntl_fork,进程一旦启动就不能动态修改进程数,想要根据数据库变化进程数就只能重启。

另外起一个 Workerman,用 Timer 或者 workerman/redis-queue,监控数据库变动,然后再去重启 webman

  • qq7467466 2023-08-23

    怎么用一个新的Workman 去重启 webman 呢?

  • 北月 2023-08-23

    如果你不想那么复杂,可以采用简单粗暴的做法:shell_exec("php /path/to/webman/start.php restart -d");

  • qq7467466 2023-08-23

    我试过了, 报错 Workerman[start.php] stopping ... worker[monitor_kafka_config:5099] exit with status 9 Workerman[start.php] has been stopped PHP Notice: fwrite(): write of 152 bytes failed with errno=32 Broken pipe in /data/wwwroot/cloud-events_test/vendor/workerman/workerman/Worker.php on line 2254

  • 北月 2023-08-23

    你自己的业务代码有问题,重新拉一个空的webman项目跑一下,是OK的。

    截图

  • qq7467466 2023-08-23

    你的这个重启命令是在 那个进程里面写的呢? 能贴下代码吗

  • 北月 2023-08-23

    代码很简单就一个定时器:截图

  • qq7467466 2023-08-23

    我已经找到指令了, \posix_kill(posix_getppid(), SIGINT); 然后配合守护进程启动, 很棒! 感谢大佬

软饭工程师

我配置了健康检查,并将进程数作为环境变量传入容器,在容器中手动通过,php start.php stop 停止容器,几秒钟后容器被健康检查拉起
截图
容器中,也能从环境变量读取到进程数,
截图
现在就是怎么处理进程数的问题。
如上面老哥所说,再起个Workerman 进程维护进程数量,然后通过workman 定时器 拉起 webman 服务也很好

  • 暂无评论
efnic

目前我通过这个方法,实现增减进程。
https://www.workerman.net/q/11025
用模型事件:

  1. 当增加或者停止进程时,生成./runtime/restart.crontab;
  2. 使用系统本身的crontab,定期执行一个重启webman的php脚本
  • 暂无评论
🔝