PHP使用进程监听模拟消费者,失败重试,连续失败写日志,并存入失败表

mac2022-06-30  33

<?php class Daemon{ protected $pid; protected $paused = false; protected $shouldQuit = false; protected $count = 1; protected $sigalrm = 3; protected $now_job = ''; protected $max_count = 3; protected $now_count = 1; public function setSigalrm($num = 3){ $this->sigalrm = $num; } public function setMaxCount($count){ $this->max_count = $count; } protected function handle($job, $is_retry = false) { $rand_num = rand(0, 1); //$rand_num = 0; if( $rand_num == 0 ){ sleep(5); }else{ sleep(1); if($is_retry == false){ echo $job . ": success\n"; } return 1; } } protected function supportsAsyncSignals() { return version_compare(PHP_VERSION, '7.1.0') >= 0 && extension_loaded('pcntl'); } protected function registerTimeoutHandler() { if ($this->supportsAsyncSignals()) { pcntl_signal(SIGALRM, function () { echo $this->now_job . ': 超时处理失败,正在重试...' . "\n"; if($this->handle($this->now_job, true)){ echo $this->now_job . ': 重试成功!' . "\n"; }else{ echo $this->now_job . ': 超时处理失败,已写入失败表中,并记录日志' . "\n"; } //$this->kill(); }); pcntl_alarm(3); } } public function kill($status = 0) { if (extension_loaded('posix')) { posix_kill($this->pid, SIGKILL); } exit($status); } protected function listenForSignals() { if ($this->supportsAsyncSignals()) { pcntl_async_signals(true); pcntl_signal(SIGINT, function () { $this->kill(); }); pcntl_signal(SIGTERM, function () { $this->kill(); }); pcntl_signal(SIGUSR2, function () { $this->paused = true; }); pcntl_signal(SIGCONT, function () { $this->paused = false; }); } } public function daemon() { $this->listenForSignals(); for( ; $this->count <= 5; $this->count++){ $this->now_job = 'send email to why' . $this->count; $this->registerTimeoutHandler(); $this->handle($this->now_job); } //print_r($this->max_count); } } set_time_limit(0); $a = new Daemon(); $a->setSigalrm(3); $a->daemon();

原理

在handle设置随机数永远为0,也就是永远sleep5秒,所以每次重试都会超过3秒,触发SIGALRM定时器信号,所以每个job失败后默认重试一次,第二次失败写入磁盘。

结果

[weihaoyu@iZ23u681ae1Z openadmin]$ php daemon.php send email to why1: success send email to why2: success send email to why3: 超时处理失败,正在重试... send email to why3: 超时处理失败,已写入失败表中,并记录日志 send email to why4: 超时处理失败,正在重试... send email to why4: 重试成功! send email to why5: 超时处理失败,正在重试... send email to why5: 超时处理失败,已写入失败表中,并记录日志 [weihaoyu@iZ23u681ae1Z openadmin]$

 

最新回复(0)