基于swoole、redis集合做一个消息订阅

利用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有序集合,然后配合分配的进程去消费

猜你喜欢

转载自blog.csdn.net/star_hacker/article/details/79557841