Swoole是PHP一个扩展,但和其余扩展只提供接口、函数不一样,Swoole从新定义PHP,接管并从新处理数据,将处理好的数据返回给PHP,支持百万TCP链接,同时支持异步/同步/协程等功能php
Swoole采用多进程架构模型,比多线程架构更方便,不存在线程安全问题,缺点是进程与进程通讯没有线程方便,另外PHP-FPM,Nginx采用的也是多进程模型,学习起来仍是容易接受。git
异步Worker进程是Swoole提供的一个非阻塞进程,投递一个异步任务到异步进程,执行完毕当即返回,异步进程能够继续处理新请求,进程间没有加锁争抢,性能异常优良。利用以上特性,能够用来处理耗时较长的事务。github
传统推送经过设置自动执行,或者手动执行读取运营后台设定数据,写入队列(可选),接着将数据推给第三方,第三方将推送结果告知程序,这个告知的过程一般以对方网络稳定决定了推送效率,推送短板也在这块。sql
异步任务运用在从队列读取数据过程当中,开启多个进程读取数据,接着发送数据给第三方,只要开启合适数量的进程,推送速度极快。数据库
话很少说,撸起代码就是干数组
一、注册定时器,写入任务安全
if ($workerId == 0) { Timer::Loop(1 * 1000, function () { PushLogic::addQueue(); }); }
<?php namespace App\Logic; use App\Logic\Queue; class PushLogic { const REDIS_KEY = 'push_list'; public static function addQueue($task) { Queue::push(self::REDIS_KEY, $task); } }
二、注册定时器 获取任务swoole
if ($workerId == 1) { Timer::Loop(5 * 1000, function () { $share = ShareMemory::getInstance(); // 启用16个异步Task进程 if ($share->get(Sys::PUSH_TASK_NUM) < 16) { AsyncTaskManager::getInstance()->add(PushTask::class); } }); }
三、封装异步执行逻辑网络
<?php namespace App\Logic; use App\Logic\Queue; class PushLogic { conse REDIS_KEY = 'push_list'; public static function handle($task) { // 进程数据隔离 文件锁 记录异步Task进程数量 $share = ShareMemory::getInstance(); $share->startTransaction(); $key = Sys::PUSH_TASK_NUM; $share->set($key, $share->get($key) + 1); $share->commit(); while (true) { $task = Queue::pop(self::REDIS_KEY); // 调用GCM或APNS逻辑 Gcm::send($task); } $share->startTransaction(); $share->set($key, $share->get($key) - 1); $share->commit(); } }
至此主要功能已处理完毕,具体推送结果能够根据实际状况存入Redis、Swoole内存表、数据库
注:推送结果不要存在全局变量或者静态变量,由于不一样进程内存隔离多线程
传统推送耗时:30分钟 异步多任务:3分钟