常驻型 哪些修改需要重启
之前在yii的项目里用redis作为消息队列,现在很多任务需要延迟需求,于是把之前redis的消息队列替换成了rabbitmq
于是使用yii的yii2-queue这个组件
但是由于提供的yii queue/listen
是个单进程的消费,而且也不是守护进程,如果有个任务阻塞,就会对其它的任务有影响,开多个又难以管理
于是使用master-worker的方式 开多个worker干活,master监控worker状态
但是进程常驻的程序 又牵扯到代码修改了重启的问题
比如 在master启动就已经加载到内存的程序代码 不重启master是无法得到修改的变更的
下面例子来演示哪些代码需要重启,哪些不需要
这里使用的是从项目里抽出来的简要的进程管理组件
composer require hkui/process_manager
job.php
class job { public function do($obj){ $i=0; while(true){ $i++; echo posix_getpid()."=".$i."-job-".A.PHP_EOL; sleep(2); $obj->isExit($i); } } }
demo.php
require '../../../vendor/autoload.php'; use ProcessManager\Process; define("A","456"); class demo extends Process { public function runJob($worker, $index) { \swoole_set_process_name(sprintf('%s-worker-%d', 'test',$index)); include 'job.php'; $job=new job(); $job->do($this); } } if(count($argv)<3){ exit( "params lost".PHP_EOL); } $process_name=$argv[1]; $worker_num=3; if(isset($argv[3])){ $worker_num=intval($argv[3]); } $cmd=$argv[2]; $config=[ 'process_name'=>$process_name, 'worker_num'=>$worker_num, 'out_file'=>'/tmp/out', 'max_run_time'=>10 //运行10个后自己退出,然后master补上 ]; $process=new demo($config); echo posix_getpid().PHP_EOL; $process->run($cmd);
开启1个master3个worker php demo.php test start 3 [root@6fb38402a4c6 process_manager]# php demo.php test status 9982 Array ( [0] => 9979 9980 9981 [1] => USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND [2] => root 9882 0.0 0.1 144952 7420 ? Ss 08:42 0:00 test-master [3] => root 9979 0.0 0.1 147004 9212 ? S 08:49 0:00 \_ test-worker-1 [4] => root 9980 0.0 0.1 147004 9212 ? S 08:49 0:00 \_ test-worker-2 [5] => root 9981 0.0 0.1 147004 9212 ? S 08:49 0:00 \_ test-worker-0 ) 修改常量A的值,worker在重启(运行满10次 或者执行 php demo.php test reload) 后,输出的结果不会体现出A的修改变更 但是修改 job.php里runJob里的输出,worker在重启后会执行最新的代码 如果我们把 include 'job.php'; 拿到外面 demo部分替换成 define("A","456"); include 'job.php'; class demo extends Process { public function runJob($worker, $index) { \swoole_set_process_name(sprintf('%s-worker-%d', 'test',$index)); $job=new job(); $job->do($this); } } 这时修改job代码后,worker重启也不会生效了 runJob里的代码都是子进程worker里的代码 我们在最开始版本的demo代码里 打印下print_r(get_included_files()); define("A","456"); class demo extends Process { public function runJob($worker, $index) { print_r(get_included_files()); \swoole_set_process_name(sprintf('%s-worker-%d', 'test',$index)); include 'job.php'; $job=new job(); $job->do($this); } } 得到 Array ( [0] => /www/process/vendor/hkui/process_manager/demo.php [1] => /www/process/vendor/autoload.php [2] => /www/process/vendor/composer/autoload_real.php [3] => /www/process/vendor/composer/ClassLoader.php [4] => /www/process/vendor/composer/autoload_static.php [5] => /www/process/vendor/hkui/process_manager/src/Process.php ) 这时job.php并没有加载到内存里 所以每次woker重启,new job时 都会加载最新的job.php代码 ,而常量A在demo.php里定义,已经加载到了内存,所以改A必须重启master才能生效 如果把 include 'job.php'; define("A","456"); 下面,这时的get_included_files() 为 Array ( [0] => /www/process/vendor/hkui/process_manager/demo.php [1] => /www/process/vendor/autoload.php [2] => /www/process/vendor/composer/autoload_real.php [3] => /www/process/vendor/composer/ClassLoader.php [4] => /www/process/vendor/composer/autoload_static.php [5] => /www/process/vendor/hkui/process_manager/job.php [6] => /www/process/vendor/hkui/process_manager/src/Process.php ) 修改job内容 worker重启后new Job 不再加载job.php,而是从父进程master继承 所以不会生效,必须重启父进程master