|
@@ -5,66 +5,14 @@ include_once "../vendor/autoload.php"; |
|
@@ -5,66 +5,14 @@ include_once "../vendor/autoload.php"; |
5
|
// 这里试试不用多进程模式,用多协程模式
|
5
|
// 这里试试不用多进程模式,用多协程模式
|
6
|
|
6
|
|
7
|
\Lib\DbPool::$clientNumber = 60;
|
7
|
\Lib\DbPool::$clientNumber = 60;
|
|
|
8
|
+\Lib\RedisPool::$clientNumber = 60;
|
8
|
|
9
|
|
9
|
class SendJob {
|
10
|
class SendJob {
|
10
|
|
11
|
|
11
|
- public $cnum = 0;
|
|
|
12
|
-
|
|
|
13
|
- private $run_timer = 0;
|
|
|
14
|
-
|
|
|
15
|
- public function __construct()
|
|
|
16
|
- {
|
|
|
17
|
- $this->run_timer = time();
|
|
|
18
|
- }
|
|
|
19
|
-
|
|
|
20
|
- /**
|
|
|
21
|
- * 是否停止
|
|
|
22
|
- * @return bool
|
|
|
23
|
- * @author:dc
|
|
|
24
|
- * @time 2024/4/10 9:12
|
|
|
25
|
- */
|
|
|
26
|
- private function isStop(){
|
|
|
27
|
- // 运行超过1天的 停止
|
|
|
28
|
- if($this->run_timer < (time()-43200)){
|
|
|
29
|
-// @posix_kill(getmypid(), SIGTERM);
|
|
|
30
|
- return true;
|
|
|
31
|
- }
|
|
|
32
|
- return redis()->get('send_job_is_stop') == 'stop';
|
|
|
33
|
- }
|
|
|
34
|
-
|
|
|
35
|
- /**
|
|
|
36
|
- * 休眠
|
|
|
37
|
- * @param float $sleep
|
|
|
38
|
- * @return bool
|
|
|
39
|
- * @author:dc
|
|
|
40
|
- * @time 2024/4/10 9:12
|
|
|
41
|
- */
|
|
|
42
|
- private function s_sleep(float $sleep):bool {
|
|
|
43
|
- if($sleep > 0){
|
|
|
44
|
- $t = microtime(1);
|
|
|
45
|
-
|
|
|
46
|
- while (!$this->isStop()){
|
|
|
47
|
- co::sleep(0.1);
|
|
|
48
|
- if($sleep - (microtime(1)-$t) <= 0){
|
|
|
49
|
- break;
|
|
|
50
|
- }
|
|
|
51
|
- }
|
|
|
52
|
- }
|
|
|
53
|
- return true;
|
|
|
54
|
- }
|
|
|
55
|
-
|
|
|
56
|
-
|
|
|
57
|
public function start(){
|
12
|
public function start(){
|
58
|
_echo('启动邮件群发任务 '.getmypid());
|
13
|
_echo('启动邮件群发任务 '.getmypid());
|
59
|
- // 删除key
|
|
|
60
|
- redis()->delete('send_job_is_stop');
|
|
|
61
|
-
|
|
|
62
|
|
14
|
|
63
|
while (1){
|
15
|
while (1){
|
64
|
- // 是否要停止
|
|
|
65
|
- if($this->isStop()){
|
|
|
66
|
- break;
|
|
|
67
|
- }
|
|
|
68
|
|
16
|
|
69
|
$lists = db()->all(\Model\sendJobsSql::sendList(500));
|
17
|
$lists = db()->all(\Model\sendJobsSql::sendList(500));
|
70
|
$lists = $lists?$lists:[];
|
18
|
$lists = $lists?$lists:[];
|
|
@@ -92,18 +40,8 @@ class SendJob { |
|
@@ -92,18 +40,8 @@ class SendJob { |
92
|
}
|
40
|
}
|
93
|
}
|
41
|
}
|
94
|
// 休眠30秒
|
42
|
// 休眠30秒
|
95
|
- $this->s_sleep(30);
|
|
|
96
|
-
|
|
|
97
|
- }
|
|
|
98
|
-
|
43
|
+ co::sleep(30);
|
99
|
|
44
|
|
100
|
- // 这个是等待所有协程退出
|
|
|
101
|
- while (true){
|
|
|
102
|
- _echo('等待协程退出...');
|
|
|
103
|
- if(!$this->cnum){
|
|
|
104
|
- break;
|
|
|
105
|
- }
|
|
|
106
|
- co::sleep(1);
|
|
|
107
|
}
|
45
|
}
|
108
|
|
46
|
|
109
|
}
|
47
|
}
|
|
@@ -118,16 +56,16 @@ class SendJob { |
|
@@ -118,16 +56,16 @@ class SendJob { |
118
|
*/
|
56
|
*/
|
119
|
public function go_($list){
|
57
|
public function go_($list){
|
120
|
// 控制50个协程内
|
58
|
// 控制50个协程内
|
121
|
- while ($this->cnum>=50){
|
|
|
122
|
- co::sleep(0.5);
|
59
|
+ while (\Lib\SwGo::$runNumber >= 50){
|
|
|
60
|
+ co::sleep(1);
|
123
|
}
|
61
|
}
|
124
|
|
62
|
|
125
|
|
63
|
|
126
|
// 占用 id
|
64
|
// 占用 id
|
127
|
if(redis()->add('send_job_run_id_'.$list['id'],$list['id'],600)){
|
65
|
if(redis()->add('send_job_run_id_'.$list['id'],$list['id'],600)){
|
128
|
- go(function ($data) {
|
66
|
+ \Lib\SwGo::start(function ($data) {
|
129
|
_echo('正在执行任务 '.$data['id']);
|
67
|
_echo('正在执行任务 '.$data['id']);
|
130
|
- $this->cnum++; // 协程数+1
|
68
|
+
|
131
|
// 表单数据
|
69
|
// 表单数据
|
132
|
$data['maildata'] = json_decode($data['maildata'],true);
|
70
|
$data['maildata'] = json_decode($data['maildata'],true);
|
133
|
// 查询邮箱
|
71
|
// 查询邮箱
|
|
@@ -184,13 +122,8 @@ class SendJob { |
|
@@ -184,13 +122,8 @@ class SendJob { |
184
|
_echo('进入时间等待区 '.$to['email'].' 等待:'.$time);
|
122
|
_echo('进入时间等待区 '.$to['email'].' 等待:'.$time);
|
185
|
$block = false;
|
123
|
$block = false;
|
186
|
while (true){
|
124
|
while (true){
|
187
|
- // 没5秒循环一次
|
|
|
188
|
- if($this->isStop()){
|
|
|
189
|
- $block = true;
|
|
|
190
|
- break;
|
|
|
191
|
- }
|
|
|
192
|
$time-=5;
|
125
|
$time-=5;
|
193
|
- $this->s_sleep(5);
|
126
|
+ co::sleep(5);
|
194
|
// 执行下一次了
|
127
|
// 执行下一次了
|
195
|
if (!$time){
|
128
|
if (!$time){
|
196
|
$block = true;
|
129
|
$block = true;
|
|
@@ -231,36 +164,26 @@ class SendJob { |
|
@@ -231,36 +164,26 @@ class SendJob { |
231
|
|
164
|
|
232
|
}
|
165
|
}
|
233
|
|
166
|
|
234
|
- // 协程结束后
|
|
|
235
|
- co::defer(function ($id) use($data){
|
|
|
236
|
- $this->cnum--;
|
|
|
237
|
- // 验证是否完成
|
|
|
238
|
- if($data['maildata']['massSuit']??0){
|
|
|
239
|
- $dst = db()->first(\Model\sendJobsSql::isStatus($data['id']));
|
|
|
240
|
- if($dst && $dst['status'] != 3){
|
|
|
241
|
- $total = db()->first(\Model\sendJobStatusSql::countSum($data['id']));
|
|
|
242
|
- if($total){
|
|
|
243
|
- // 更新状态
|
|
|
244
|
- db()->update(\Model\sendJobsSql::$table,[
|
|
|
245
|
- 'status' => $total['t'] == $data['total'] ? 2 : 0,
|
|
|
246
|
- 'success' => $total['s'],
|
|
|
247
|
- 'error' => $total['e'],
|
|
|
248
|
- ],dbWhere(['id'=>$data['id']]));
|
|
|
249
|
- }
|
167
|
+ },function ($data){
|
|
|
168
|
+ // 验证是否完成
|
|
|
169
|
+ if($data['maildata']['massSuit']??0){
|
|
|
170
|
+ $dst = db()->first(\Model\sendJobsSql::isStatus($data['id']));
|
|
|
171
|
+ if($dst && $dst['status'] != 3){
|
|
|
172
|
+ $total = db()->first(\Model\sendJobStatusSql::countSum($data['id']));
|
|
|
173
|
+ if($total){
|
|
|
174
|
+ // 更新状态
|
|
|
175
|
+ db()->update(\Model\sendJobsSql::$table,[
|
|
|
176
|
+ 'status' => $total['t'] == $data['total'] ? 2 : 0,
|
|
|
177
|
+ 'success' => $total['s'],
|
|
|
178
|
+ 'error' => $total['e'],
|
|
|
179
|
+ ],dbWhere(['id'=>$data['id']]));
|
250
|
}
|
180
|
}
|
251
|
}
|
181
|
}
|
|
|
182
|
+ }
|
|
|
183
|
+ // 删除占用
|
|
|
184
|
+ redis()->delete('send_job_run_id_'.$data['id']);
|
252
|
|
185
|
|
253
|
- // 写入日志
|
|
|
254
|
- \Lib\Log::getInstance()->write();
|
|
|
255
|
-
|
|
|
256
|
- // 删除占用
|
|
|
257
|
- redis()->delete('send_job_run_id_'.$data['id']);
|
|
|
258
|
-
|
|
|
259
|
-
|
|
|
260
|
- _echo('执行任务完成'.$data['id']);
|
|
|
261
|
-
|
|
|
262
|
- db()->close();
|
|
|
263
|
- });
|
186
|
+ _echo('执行任务完成'.$data['id']);
|
264
|
|
187
|
|
265
|
},$list);
|
188
|
},$list);
|
266
|
}
|
189
|
}
|
|
@@ -268,55 +191,11 @@ class SendJob { |
|
@@ -268,55 +191,11 @@ class SendJob { |
268
|
}
|
191
|
}
|
269
|
|
192
|
|
270
|
}
|
193
|
}
|
|
|
194
|
+// 开启协程
|
|
|
195
|
+\Co\run(function (){
|
271
|
|
196
|
|
|
|
197
|
+ (new SendJob)->start();
|
272
|
|
198
|
|
273
|
-$ps = "ps -ef | grep \"send_job.php start\" | grep -v grep | wc -l";
|
|
|
274
|
-
|
|
|
275
|
-switch ($argv[1]??0){
|
|
|
276
|
- case 'start':{
|
|
|
277
|
-
|
|
|
278
|
- // 开启协程
|
|
|
279
|
- \Co\run(function (){
|
|
|
280
|
-
|
|
|
281
|
- $handler = function ($signal){
|
|
|
282
|
- // 可以处理其他程序
|
|
|
283
|
- redis()->set('send_job_is_stop','stop');
|
|
|
284
|
-
|
|
|
285
|
- _echo('收到退出信号 '.$signal);
|
|
|
286
|
- };
|
199
|
+ _echo('进程已退出');
|
287
|
|
200
|
|
288
|
- \Swoole\Process::signal(SIGTERM,$handler);
|
|
|
289
|
- \Swoole\Process::signal(SIGINT,$handler);
|
|
|
290
|
-
|
|
|
291
|
- (new SendJob)->start();
|
|
|
292
|
-
|
|
|
293
|
- _echo('进程已退出');
|
|
|
294
|
-
|
|
|
295
|
- db()->close();
|
|
|
296
|
- });
|
|
|
297
|
-
|
|
|
298
|
- break;
|
|
|
299
|
- }
|
|
|
300
|
- case 'stop':{
|
|
|
301
|
- \Co\run(function ($ps){
|
|
|
302
|
- echo "正在退出程序...\n非必要请不要强制kill掉进程\n";
|
|
|
303
|
-
|
|
|
304
|
- redis()->set('send_job_is_stop','stop');
|
|
|
305
|
-
|
|
|
306
|
- while (true){
|
|
|
307
|
-
|
|
|
308
|
- $num = exec($ps);
|
|
|
309
|
- if(!$num){
|
|
|
310
|
- break;
|
|
|
311
|
- }
|
|
|
312
|
- co::sleep(0.2);
|
|
|
313
|
- }
|
|
|
314
|
- echo "已退出程序\n";
|
|
|
315
|
- },$ps);
|
|
|
316
|
-
|
|
|
317
|
- break;
|
|
|
318
|
- }
|
|
|
319
|
- default:{
|
|
|
320
|
- break;
|
|
|
321
|
- }
|
|
|
322
|
-} |
201
|
+}); |