作者 邓超

1

  1 +<?php
  2 +
  3 +\Swoole\Timer::tick(2000,function (){
  4 + echo '1';
  5 +});
@@ -22,64 +22,61 @@ function start(){ @@ -22,64 +22,61 @@ function start(){
22 // 初始时,进行一次统计 22 // 初始时,进行一次统计
23 $table->set('etotal',['val'=> db()->count(\Model\email::count())]); 23 $table->set('etotal',['val'=> db()->count(\Model\email::count())]);
24 24
25 -// 启动一个进程池进行管理  
26 - $topPool = new Process\Pool(WORKER_NUM);  
27 -  
28 - // 每10分钟统计一次邮箱数量  
29 - $timer_id = \Swoole\Timer::tick(600,function () use (&$table){  
30 - $table->set('etotal',['val'=> db()->count(\Model\email::count())]);  
31 - }); 25 + // 进程管理器
  26 + $pm = new Process\Manager();
  27 +
  28 + // 启动一个进程来管理定时
  29 + $pm->add(function (Process\Pool $pool, int $workerId)use (&$table){
  30 + _echo("进程({$workerId})启动成功");
  31 + // 每10分钟统计一次邮箱数量
  32 + \Swoole\Timer::tick(600000,function () use (&$table){
  33 + $table->set('etotal',['val'=> db()->count(\Model\email::count())]);
  34 + });
32 35
33 - // 每2秒执行一次  
34 - $timer_check_id = \Swoole\Timer::tick(2,function () use (&$table,$topPool){  
35 - // 是否停止脚本  
36 - $table->set('stop',['val'=> redis()->get(RUNNING_REDIS_KEY) === 'stop' ? 1 : 0]);  
37 -  
38 - // 检查是否结束了所有的协程同步代码  
39 - if ($table->get('stop','val')) {  
40 - $stop_num = 0;  
41 - foreach (range(0, WORKER_NUM) as $i) {  
42 - if ($table->exists('ps' . $i)) {  
43 - $stop_num++; 36 + // 每2秒执行一次
  37 + \Swoole\Timer::tick(2000,function () use (&$table,&$pool){
  38 + // 是否停止脚本
  39 + $table->set('stop',['val'=> redis()->get(RUNNING_REDIS_KEY) === 'stop' ? 1 : 0]);
  40 +// _echo('定时器');
  41 + // 检查是否结束了所有的协程同步代码
  42 + if ($table->get('stop','val')) {
  43 + $stop_num = 0;
  44 + foreach (range(0, WORKER_NUM) as $i) {
  45 + if ($table->exists('ps' . $i)) {
  46 + $stop_num++;
  47 + }
44 } 48 }
45 - }  
46 - if($stop_num >= WORKER_NUM){ 49 + if($stop_num >= WORKER_NUM){
47 // 退出进程 50 // 退出进程
48 - $topPool->shutdown(); 51 + $pool->shutdown();
  52 + }
49 } 53 }
50 - }  
51 54
52 - // 邮件总数  
53 - $total = redis()->get('email_total',0);  
54 - if($total > $table->get('etotal','val')){  
55 - $table->set('etotal',['val'=> $total]);  
56 - } 55 + // 邮件总数
  56 + $total = redis()->get('email_total',0);
  57 + if($total > $table->get('etotal','val')){
  58 + $table->set('etotal',['val'=> $total]);
  59 + }
57 60
58 - }); 61 + });
59 62
  63 + // 进行阻塞,否则定时器无法运行
  64 + while (true){
  65 + co::sleep(9999);
  66 + }
  67 + },true);
60 68
61 69
62 - // 这个是启用协程  
63 - $topPool->set(['enable_coroutine' => true]);  
64 - // 协程配置 70 +// 协程配置
65 \co::set([ 71 \co::set([
66 'max_coroutine'=>COROUTINE_MAX_NUM, // 最大携程数量 72 'max_coroutine'=>COROUTINE_MAX_NUM, // 最大携程数量
67 'hook_flags'=>SWOOLE_HOOK_TCP, // redis需要的配置 73 'hook_flags'=>SWOOLE_HOOK_TCP, // redis需要的配置
68 ]); 74 ]);
69 75
70 - // 开始工作  
71 - $topPool->on('WorkerStart',function (Process\Pool $pool,$worker_id) use (&$table){ 76 + // 启动业务进程
  77 + $pm->addBatch(WORKER_NUM,function (Process\Pool $pool, int $worker_id) use (&$table){
72 _echo("进程({$worker_id})启动成功"); 78 _echo("进程({$worker_id})启动成功");
73 79
74 - // 是否停止,这里进行阻塞  
75 - if ($table->get('stop','val')){  
76 - // 某个进程退出了  
77 - $table->set('ps'.$worker_id,['val'=>1]);  
78 -  
79 - co::sleep(1);  
80 - return true;  
81 - }  
82 -  
83 // 协程id集 80 // 协程id集
84 $cid = []; 81 $cid = [];
85 82
@@ -132,19 +129,25 @@ function start(){ @@ -132,19 +129,25 @@ function start(){
132 // 跳出无限循环了 129 // 跳出无限循环了
133 if(!$cid){ 130 if(!$cid){
134 _echo('正常关闭进程('.$worker_id.')'); 131 _echo('正常关闭进程('.$worker_id.')');
135 - // 关闭当前进程  
136 -// $pool->shutdown();  
137 break; 132 break;
138 } 133 }
139 } 134 }
140 135
141 - });  
142 - // 停止工作后的回调  
143 - $topPool->on('WorkerStop', function (\Swoole\Process\Pool $pool, $workerId) {  
144 - _echo("[Worker #{$workerId}] WorkerStop\n");  
145 - }); 136 + // 是否停止,这里进行阻塞
  137 + if ($table->get('stop','val')){
  138 + // 某个进程退出了
  139 + $table->set('ps'.$worker_id,['val'=>1]);
  140 + // 阻塞直到 主进程 kill掉所有子进程
  141 + while (true){
  142 + co::sleep(5);
  143 + }
  144 + }
  145 +
  146 +
  147 + },true);
  148 +
146 149
147 - $topPool->start(); 150 + $pm->start();
148 151
149 } 152 }
150 153
@@ -165,7 +168,7 @@ function create_coroutine(array &$cid,int &$isRunMaxCNum,$worker_id){ @@ -165,7 +168,7 @@ function create_coroutine(array &$cid,int &$isRunMaxCNum,$worker_id){
165 while (true){ 168 while (true){
166 // 是否退出协程 169 // 是否退出协程
167 if(!$isRunMaxCNum){ 170 if(!$isRunMaxCNum){
168 - _echo('协程('.co::getCid().'): stop '.$isRunMaxCNum); 171 +// _echo('协程('.co::getCid().'): stop '.$isRunMaxCNum);
169 break; 172 break;
170 } 173 }
171 174
@@ -182,8 +185,8 @@ function create_coroutine(array &$cid,int &$isRunMaxCNum,$worker_id){ @@ -182,8 +185,8 @@ function create_coroutine(array &$cid,int &$isRunMaxCNum,$worker_id){
182 } 185 }
183 186
184 // 协程完成后执行的函数 187 // 协程完成后执行的函数
185 - co::defer(function () use (&$cid){  
186 - _echo('正常关闭协程('.co::getCid().')'); 188 + co::defer(function () use (&$cid,$worker_id){
  189 + _echo('正常关闭进程('.$worker_id.')下的协程('.co::getCid().')');
187 unset($cid[co::getCid()]); 190 unset($cid[co::getCid()]);
188 }); 191 });
189 192
1 -<?php  
2 -  
3 -echo co::getCid();  
  1 +# 环境要求
  2 +* php >= 8.0
  3 +* swoole >= 5.0
  4 +* mysql >= 5.7
  5 +* 必须使用linux系统
  6 +
  7 +## 脚本
  8 +
  9 +1.启动 ,请以守护进程模式运行
  10 +~~~
  11 + php sync_email.php start
  12 +~~~
  13 +
  14 +2.退出
  15 +~~~
  16 + php sync_email.php stop
  17 +~~~
  18 +
  19 +3.注意:如果使用 进程守护器(supervisord) 执行退出后会被 守护器重新运行
  20 +
  21 +
  22 +