作者 邓超

预热邮件

1 <?php 1 <?php
2 2
  3 +//error_reporting();
3 4
4 -swoole_set_process_name('php-email-sync-list'); 5 +use Swoole\Process;
5 6
6 -$pm = new \Swoole\Process\Manager();  
7 7
8 8
9 -$pm->addBatch(60,function ($work_id) { 9 +function start(){
  10 +
  11 +// 删除停止运行的值
  12 +// redis()->delete(SYNC_RUNNING_REDIS_KEY,'email_sync_stop_num');
  13 +
  14 + // 进程管理器
  15 + $pm = new Process\Manager();
  16 +
  17 + // 启动业务进程
  18 + $pm->addBatch(10,function (Process\Pool $pool, int $worker_id){
  19 +
  20 + swoole_set_process_name('php-email-sync-list-'.$worker_id);
10 21
11 include_once __DIR__."/../vendor/autoload.php"; 22 include_once __DIR__."/../vendor/autoload.php";
  23 + _echo("业务进程({$worker_id})启动成功");
12 24
13 - $number = 0; 25 + $goNum = 0;
  26 + // 循环阻塞
14 while (true){ 27 while (true){
15 - if($number > 500){ break; }  
16 - 28 + while ($goNum > 50){
  29 + co::sleep(0.3);
  30 + continue;
  31 + }
17 // 需要同步的id 32 // 需要同步的id
18 $id = redis()->lPop('sync_email_lists'); 33 $id = redis()->lPop('sync_email_lists');
19 34
20 if($id && is_numeric($id)){ 35 if($id && is_numeric($id)){
21 // 占用当前的id,占用2小时 36 // 占用当前的id,占用2小时
22 if(redis()->add('just_sync_'.$id,time(),600)){ 37 if(redis()->add('just_sync_'.$id,time(),600)){
23 - $number++;  
24 - 38 + // 启动一个协程
  39 + go(function () use ($id,&$goNum){
  40 + $goNum++;
25 try{ 41 try{
26 // 开始同步 42 // 开始同步
27 $email = db()->cache(3600)->first(\Model\emailSql::first($id)); 43 $email = db()->cache(3600)->first(\Model\emailSql::first($id));
28 if($email){ 44 if($email){
29 $sync = new \Service\SyncMail($email); 45 $sync = new \Service\SyncMail($email);
30 - $search = new \Lib\Imap\ImapSearch();  
31 - // 第一次同步 只同步当天的  
32 - if(!db()->cache(600)->count(\Model\listsSql::first('`id` > 0'))){  
33 - $sync->search($search->dateGt($email['created_at']));  
34 - }else{  
35 -  
36 - if(strtotime("-2 day") > strtotime($email['created_at'])){ 46 + // ai邮件只同步2天内的
37 $sync->search( 47 $sync->search(
38 - $search->dateGt(  
39 - date('Y-m-d',  
40 - strtotime("-2 day")  
41 - )  
42 - ) 48 + (new \Lib\Imap\ImapSearch())
  49 + ->dateGt(date('Y-m-d',strtotime("-1 day")))
43 ); 50 );
44 - }else{  
45 - $sync->search(  
46 - $search->dateGt($email['created_at'])  
47 - );  
48 - }  
49 -  
50 - }  
51 -  
52 $sync->sync(); 51 $sync->sync();
53 52
54 $sync = null; 53 $sync = null;
@@ -59,24 +58,39 @@ $pm->addBatch(60,function ($work_id) { @@ -59,24 +58,39 @@ $pm->addBatch(60,function ($work_id) {
59 logs('sync : '.$e->getMessage()); 58 logs('sync : '.$e->getMessage());
60 } 59 }
61 60
  61 +
  62 + // 协程完成后执行的函数
  63 + co::defer(function () use ($id,&$goNum){
  64 + $goNum--;
62 // 30秒后 消除占用 65 // 30秒后 消除占用
63 redis()->expire('just_sync_'.$id,120); 66 redis()->expire('just_sync_'.$id,120);
  67 + // 写入日志
  68 + \Lib\Log::getInstance()->write();
  69 + });
64 70
  71 + });
65 } 72 }
66 } 73 }
67 - else{  
68 - sleep(1);  
69 - } 74 +
  75 + //每次都暂停1秒,防止同一时间启动太多的任务
  76 + co::sleep(0.1);
  77 +
  78 +
70 79
71 } 80 }
72 -});  
73 81
  82 + },true);
  83 +
  84 +
  85 + // 启动管理器
  86 + $pm->start();
74 87
75 -$pm->start(); 88 +}
76 89
77 90
78 91
79 92
  93 +start();
80 94
81 95
82 96
@@ -29,7 +29,14 @@ function stop(){ @@ -29,7 +29,14 @@ function stop(){
29 } 29 }
30 } 30 }
31 31
32 -while (1){ 32 +\Co\run(function (){
  33 + $goNum = 0;
  34 + while (1){
  35 +
  36 + if($goNum>=50){
  37 + co::sleep(1);
  38 + continue;
  39 + }
33 40
34 $id = redis()->lPop('sync_email_lists_my'); 41 $id = redis()->lPop('sync_email_lists_my');
35 redis()->set('sync_my_pid:'.getmypid(),time(),86400); 42 redis()->set('sync_my_pid:'.getmypid(),time(),86400);
@@ -41,23 +48,34 @@ while (1){ @@ -41,23 +48,34 @@ while (1){
41 // 占用当前的id,占用2小时 48 // 占用当前的id,占用2小时
42 if(redis()->add('just_sync_'.$id,time(),600)){ 49 if(redis()->add('just_sync_'.$id,time(),600)){
43 50
  51 + go(function ($id) use (&$goNum){
  52 + $goNum++;
44 try{ 53 try{
45 // 开始同步 54 // 开始同步
46 (new \Service\SyncMail($id))->sync(); 55 (new \Service\SyncMail($id))->sync();
47 }catch (Throwable $e){ 56 }catch (Throwable $e){
48 _echo($e->getMessage()); 57 _echo($e->getMessage());
49 } 58 }
  59 +
  60 + co::defer(function () use ($id,&$goNum){
  61 + $goNum--;
50 // 30秒后 消除占用 62 // 30秒后 消除占用
51 redis()->expire('just_sync_'.$id,30); 63 redis()->expire('just_sync_'.$id,30);
52 64
53 \Lib\Log::getInstance()->write(); 65 \Lib\Log::getInstance()->write();
54 66
  67 + });
  68 + },$id);
  69 +
  70 +
55 } 71 }
56 }else{ 72 }else{
57 - sleep(1); 73 + co::sleep(1);
58 } 74 }
59 75
60 -} 76 + }
  77 +});
  78 +
61 79
62 80
63 81