redis+php事务,swoole+redis订阅,多进程处理事务实例:

这里是基于TP的commond实现的class requestLog extends \app\common\think\Command

{

public $works = [];

public $max_precess = 10;//最大进程数

public $new_index = 0;//当前进行数

public $mpid = 0;//父进程id

public $cache_key = '';

protected function configure()

{

$this->setName('requestLog')

//最大进程数

->addArgument('max_process_count', Argument::OPTIONAL, 'max process count',0)

->addOption('daemon','d', Argument::OPTIONAL, 'daemon','start')

->setDescription('save requestlog');

}

protected function execute(Input $input, Output $output)

{

//守护进程

$act = $input->getOption('daemon');

// die();

$this->daemon('',$act);

if ($act=='stop'){

return ;

}

swoole_set_process_name("request log");

$output->comment("start request log");

ini_set('default_socket_timeout', -1);

$this->mpid = posix_getpid();//获取当前进程id

$max_process_count = trim($input->getArgument('max_process_count'));

if ($max_process_count > 0){

$this->max_precess = $max_process_count;

}

$redis = new Redis();

$queue_key = CacheKeys::REQUEST_QUEUE_KEY;//订阅频道key

$this->cache_key = CacheKeys::REQUEST_LOG_CACHE_KEY;

$redis->subscribe(array($queue_key),function ($instance, $channelName, $message) {//订阅redis,收到发布消息,则执行以下方法

$this->runTask();

});

}

private function runTask()

{

if (count($this->works) < $this->max_precess) {//如果未达到最大进程数,则创建,否则回收

$pid = $this->createProcess($this->new_index);//创建进程

if ($pid) {

$this->new_index++;

}

}else{

$this->processWait(false);//开始回收

}

}

protected function createProcess($index = null,$cache=null)

{

echo 'start process'.PHP_EOL;

$process = new \swoole_process(function (\swoole_process $worker) use ($index) {

$this->clacData();//处理业务的代码

$this->checkMpid($worker, $index);//检测当前进程是否存在,如果不存在则回收

}, false, false);

$pid = $process->start();

if ($pid) {

$this->works[$index] = $pid;

}

$this->processWait(false);//回收结束运行的子进程。

return $pid;

}

/**

* Notes :检测父级进程是否存在,如果不存在则结束当前子进程

* @param $worker

* @param $index

* author: leojen

* @date: 18-4-19 下午6:30

*/

public function checkMpid(&$worker, $index)

{

if (!\swoole_process::kill($this->mpid, 0)) {

$worker->exit(0);

unset($this->works[$index]);

}

}

/**

* Notes : 回收进程

* @param bool $blocking 是否阻塞 默认是

* author: leojen

* @date: 18-4-19 下午6:17

*/

public function processWait($blocking = true)

{

if (count($this->works)) {

$ret = \swoole_process::wait($blocking);//回收子进程,操作成功会返回一个数组包含子进程的PID、退出状态码、被哪种信号KILL,失败返回false

if ($ret && isset($ret['pid'])) {

$index = array_search($ret['pid'], $this->works);

unset($this->works[$index]);

echo "this [{$ret['pid']}] aready quit \r\n";

}

}

}

/**

* Notes :

* @param null $redis

* author: leojen

* @date: 18-4-19 下午6:52

*/

private function clacData()

{

//业务逻辑代码

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值