php redis实现对200w用户的即时推送


Posted in PHP onMarch 04, 2017

怎么实现对200w用户的即时推送,这个推送可以理解为调用第三方的接口,push,sms之类的东西。

当时先写了一个demo 直接读取DB然后单个推送,结果。。可想而知

于是设计一套基于redis+php多进程的方案,用着还不错而去扩展性蛮高的,故分享之。

=============================================

具体的逻辑如下:(无视我的字体)

php redis实现对200w用户的即时推送

其实这里还可以优化的,我的设想是如果用户数据再多一些的话,可以在redis里对数据进行分割采取多List,每一个List对应多个php进程这样会更快。

下面是我实现的具体代码:

主管理脚本:应用时启动这个即可。 

<?php     //push推送配置 注:使用前请确认log文件为空    2016-04-12 
include_once(dirname (__FILE__)."/../../config.inc.php"); 
//if(exec('ps aux | grep redis_push.php | grep -v grep | wc -l') != 0) goto check; 
import('push.class.php'); 
import('Redis.class.php'); 
 
$time =time(); 
$data = array("apikey"=>'xxxx',"secret"=>'xxxx'); 
$push = new Channel($data); 
$redis = new RedisCache($Credis['host'],$Credis['port']); 
if(exec('ps aux | grep redis_push.php | grep -v grep | wc -l') != 0) goto check;//如果有推送任务 直接执行监控代码 
 
/*PUSH配置项*/ 
$config = array( 
 "file"=>"test.txt", 
 "Title"=>"sssss", 
 "Content"=>"ssssssssssssssss", 
 "OpenType"=>"0",  //1是 0否  是否跳转链接 
 "Url"=>"",     //链接地址 
 "num"=>"500",   //每次推送条数 
 "s"=>"1"      //睡眠时间 (单位:秒) 
); 
$num = 15;      //启动进程数量 
$a = $config['OpenType']==1 ? "是" : "否"; 
$c = json_encode($config); 
$info = <<<monkey 
  ************ 请确认信息是否有误*10秒后启动push任务! ************* 
  * 文件名称  : {$config['file']}; 
  * 推送标题  : {$config['Title']}; 
  * 推送内容  : {$config['Content']}; 
  * 是否跳转  : {$config['OpenType']}; 
  * 进程数量  : $num;(如果为单进程无视此项) 
  * 睡眠时间  : {$config['s']}; 
  * 日志目录  : /log; 
  ***************************************************************\n 
monkey; 
echo $info; 
sleep(3); 
$n = 1; 
while($n<=10){ 
 echo (10-$n++),"秒\n"; 
 sleep(1); 
} 
echo "------------------------- 任务已启动 -------------------------\n"; 
if($redis->Scount('push_getchannel_success')){ 
 echo "队列有未完成任务\n"; 
}else{ 
 $res = exec("php redis_getchannel.php {$config['file']}");//写入redis脚本 
 echo $res; 
} 
smtp_mail('xxxx@qq.com','推送任务已开启','请实时监测,5秒后您的手机将接收到测试推送!');//推送监控 实现定时全自动推送  
echo "\n---------------- 5秒后 test 将收到测试推送消息 ----------------\n"; 
sleep(5); 
$re = $push->BaiduPush('xxxx','xxxxx',$config['Content'],$config['Title'],'1',$config['OpenType'],$config['Url'],'xxxxx',$push); 
sleep(1); 
echo "\n---------------- 测试推送已发出!如未收到,请及时终止程序! 10秒后正式推送!!! ----------------\n"; 
$m = 1; 
while($m<=10){ 
 echo (10-$m++),"秒\n"; 
 sleep(1); 
} 
echo "\n---------------- 推送任务已经开始!请耐心等待! ----------------\n"; 
//下面设置是否多进程 
for($i=1;$i<=$num;$i++){ 
exec("php redis_push.php '{$c}' > /dev/null 2>&1 &"); 
} 
 
check: 
while(1){ 
 if(exec('ps aux | grep redis_push.php | grep -v grep | wc -l') == 0){ 
  echo "push 发送完成 用时",time()-$time,"秒"; 
  die(); 
 } 
 echo "当前进程数:",exec('ps aux | grep redis_push.php | grep -v grep | wc -l'),"个","\n"; 
 echo "当前剩余推送数量:".$redis->Scount('push_getchannel_success')."\n"; 
 sleep(10); 
}

至于写入redis和具体的推送脚本这个靠自己的想象里就好了 我就不发了 嘿嘿

我的做法是具体的推送脚本在推送一定数量后会自动终止并调用自己本身。

因为在实际应用中发现php脚本在长时间运行之后会发生假死(可能是因为上下文切换的问题),所以我都是避免让php脚本长时间运行。

还有就是用户肯定不是固定的200w用户 每天都会有一个增量,我的方案是通过定时脚本每天把增量的用户整理进我自己设计的一个用户表自己管理。

ps:我把所有的脚本弄到了一个我自己整理的小的php原生框架统一管理,过段时间我发出来。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
PHP 5.3.1 安装包 VC9 VC6不同版本的区别是什么
Jul 04 PHP
PHP类的静态(static)方法和静态(static)变量使用介绍
Feb 19 PHP
php array的学习笔记
May 10 PHP
php计算整个mysql数据库大小的方法
Jun 19 PHP
PHP中strnatcmp()函数“自然排序算法”进行字符串比较用法分析(对比strcmp函数)
Jan 07 PHP
Symfony2学习笔记之插件格式分析
Mar 17 PHP
微信支付开发维权通知实例
Jul 12 PHP
php车辆违章查询数据示例
Oct 14 PHP
php arsort 数组降序排序详细介绍
Nov 17 PHP
PHP检测一个数组有没有定义的方法步骤
Jul 20 PHP
PHP使用gearman进行异步的邮件或短信发送操作详解
Feb 27 PHP
php输出形式实例整理
May 05 PHP
php获取目录中所有文件名及判断文件与目录的简单方法
Mar 04 #PHP
PHP redis实现超迷你全文检索
Mar 04 #PHP
浅谈php中变量的数据类型判断函数
Mar 04 #PHP
PHP检测数据类型的几种方法(总结)
Mar 04 #PHP
php redis实现文章发布系统(用户投票系统)
Mar 04 #PHP
PHP获取当前执行php文件名的代码
Mar 02 #PHP
PHP两种实现无级递归分类的方法
Mar 02 #PHP
You might like
DEDE采集大师官方留后门的删除办法
2011/01/08 PHP
10个实用的PHP代码片段
2011/09/02 PHP
PHP实现文件下载断点续传详解
2014/10/15 PHP
php可应用于面包屑导航的递归寻找家谱树实现方法
2015/02/02 PHP
对象特征检测法判断浏览器对javascript对象的支持
2009/07/25 Javascript
javascript 触发事件列表 比较不错
2009/09/03 Javascript
firefox下对ajax的onreadystatechange的支持情况分析
2009/12/14 Javascript
jquery命令汇总,方便使用jquery的朋友
2012/06/26 Javascript
浅谈JavaScript中定义变量时有无var声明的区别
2014/08/18 Javascript
jQuery解析Json实例详解
2015/11/24 Javascript
基于JS实现省市联动效果代码分享
2016/06/06 Javascript
JavaScript 冒泡排序和选择排序的实现代码
2016/09/03 Javascript
微信小程序实现给嵌套template模板传递数据的方式总结
2017/12/18 Javascript
详解vue+vuex+koa2开发环境搭建及示例开发
2018/01/22 Javascript
AngularJs的UI组件ui-Bootstrap之Tooltip和Popover
2018/07/13 Javascript
微信小程序实现收藏与取消收藏切换图片功能
2018/08/03 Javascript
jQuery中使用validate插件校验表单功能
2019/05/24 jQuery
jquery插件开发模式实例详解
2019/07/20 jQuery
js如何实现元素曝光上报
2019/08/07 Javascript
nodejs环境使用Typeorm连接查询Oracle数据
2019/12/05 NodeJs
JavaScript简易计算器制作
2020/01/17 Javascript
[16:19]教你分分钟做大人——风暴之灵
2015/03/11 DOTA
[00:32]DOTA2上海特级锦标赛 Ehome战队宣传片
2016/03/03 DOTA
[01:00:12]2018DOTA2亚洲邀请赛 4.7 淘汰赛 VP vs LGD 第一场
2018/04/09 DOTA
python字符串str和字节数组相互转化方法
2017/03/18 Python
利用python库在局域网内传输文件的方法
2018/06/04 Python
HTML5 canvas基本绘图之图形组合
2016/06/27 HTML / CSS
美国在线印刷公司:PsPrint
2017/10/12 全球购物
Under Armour安德玛德国官网:美国高端运动科技品牌
2019/03/09 全球购物
付款委托书范本
2014/04/04 职场文书
《故乡》教学反思
2014/04/10 职场文书
班主任个人工作反思
2014/04/28 职场文书
毕业生学校推荐信范文
2014/05/21 职场文书
学校中秋节活动总结
2015/03/23 职场文书
民事调解协议书
2016/03/21 职场文书
创业计划书之健康营养产业
2019/10/15 职场文书