MySQL异步推送_异步任务推送的实践

目录

初识Swoole

异步进程介绍

传统推送业务逻辑

异步任务推送逻辑

效率对比

初识Swoole

Swoole是PHP一个扩展,但和其他扩展只提供接口、函数不同,Swoole重新定义PHP,接管并重新处理数据,将处理好的数据返回给PHP,支持百万TCP连接,同时支持异步/同步/协程等功能

a82a9973e27732fd07179a7df8b51eb2.png

Swoole采用多进程架构模型,比多线程架构更方便,不存在线程安全问题,缺点是进程与进程通信没有线程方便,另外PHP-FPM,Nginx采用的也是多进程模型,学习起来还是容易接受。

异步Worker进程介绍

异步Worker进程是Swoole提供的一个非阻塞进程,投递一个异步任务到异步进程,执行完毕立即返回,异步进程可以继续处理新请求,进程间没有加锁争抢,性能异常优良。利用以上特性,可以用来处理耗时较长的事务。

传统推送业务逻辑

a6186844fa9a189f698535eec1e99b9e.png

传统推送通过设置自动执行,或者手动执行读取运营后台设定数据,写入队列(可选),接着将数据推给第三方,第三方将推送结果告知程序,这个告知的过程通常以对方网络稳定决定了推送效率,推送短板也在这块。

异步任务进程推送逻辑

b2cb8d67a5471d4b2e47f8e97fca550b.png

异步任务运用在从队列读取数据过程中,开启多个进程读取数据,接着发送数据给第三方,只要开启合适数量的进程,推送速度极快。

下面介绍用到技术

EasySwoole框架

Redis队列

定时器

Task进程

话不多说,撸起代码就是干

1、注册定时器,写入任务

if ($workerId == 0) {

Timer::Loop(1 * 1000, function () {

PushLogic::addQueue();

});

}

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);

}

}

2、注册定时器 获取任务

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);

}

});

}

3、封装异步执行逻辑

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内存表、数据库

注:推送结果不要存在全局变量或者静态变量,因为不同进程内存隔离

效率对比

系统:CenOS release 5.11

CPU: 4核

内存:32G

PHP:7.1

总终端数量:1百万

单次任务终端数量:1千

传统推送耗时:30分钟

异步多任务:3分钟

温馨提示

EasySwoole框架是常驻内存,连接数据库需要采用断线重连,否则会出现MySQL server has gone away,可以参考这里的使用方法PHP-MySQLi-Database-Class

获取任务时,应避免所有异步任务进程处于忙的状态。

代码不要出现sleep/usleep等睡眠函数,会使进程陷入睡眠阻塞。

禁用exit/die,导致进程退出。

全局变量、静态变量、需要自行销毁,特别要注意array类型的值,必要时清理大数组,防止内存溢出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值