利用swoole开启常驻进程,需要几个按自己的情况来定,swoole进程数最好是和服务器cpu核数相等
上篇和这里我用的都是woker进程没有用task_worker
redis 有序集合score可以按时间戳来吧需要发送的数据存储起来
利用swoole启动的常驻进程不断的去探测,可以设定一段时间去按照score时间排序去把这个时间段的有序集合的数据取出来消费
下面上代码:
swoole启动代码
function run() { try { $swoole = new \swoole_server(127.0.0.1, 9999); $swoole->set([ 'daemonize' => 1, //是否开启守护进程 'worker_num' => 8, //实际需要去设定 'log_file' => __APP_LOGS_PATH__ . '/swoole.log' ]); $swoole->on('WorkerStart', 'onWorkerStart'); $swoole->on('Receive', 'onReceive'); $swoole->start(); } catch (\Exception $e) { logs(['err_code' => $e->getCode(), 'err_msg' => $e->getMessage()], 'error'); } }
具体的分配进程去redis有序集合取数据然后消费
function onWorkerStart(swoole_server $swoole, $worker_id) { for ($i = 1; $i <= 3000; $i++) { $redis = connectRedis(); if ($worker_id == 0) { $quedata = []; $quedata['tag'] = 'test'; if ($redis->zCard('cron:test')) { $data = $quedata['data'] = $redis->zRevRangeByScore('cron:test', time(), time() - 500); if (empty($data)) { sleep(300); } else { $quedata = json_encode($quedata); call_user_func_array('postMessage', [&$quedata, &$redis]); foreach ($data as $v) { $redis->zRem('cron:test', $v); } } } else { sleep(300); } } elseif ($worker_id == 1) { $quedata = []; $quedata['tag'] = 'order'; if ($redis->zCard('cron:order')) { $data = $quedata['data'] = $redis->zRevRangeByScore('cron:order', time(), time() - 500); if (empty($data)) { sleep(300); } else { $quedata = json_encode($quedata); call_user_func_array('postMessage', [&$quedata, &$redis]); foreach ($data as $v) { $redis->zRem('cron:order', $v); } } } else { sleep(300); } } } $redis->close(); unset($redis); method_exists($swoole, 'stop') ? $swoole->stop() : @exit; }当然我这里有序集合只设置了一个,然后去固定的有序集合去消费。
你也可以用不同的业务模块建立不同的redis有序集合,然后配合分配的进程去消费