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设计模式中的工厂模式
Jun 12 PHP
PHP提取字符串中的图片地址[正则表达式]
Nov 12 PHP
使用PHP curl模拟浏览器抓取网站信息
Oct 28 PHP
php上传图片到指定位置路径保存到数据库的具体实现
Dec 30 PHP
linux使用crontab实现PHP执行计划定时任务
May 10 PHP
PHP+Memcache实现wordpress访问总数统计(非插件)
Jul 04 PHP
php网站被挂木马后的修复方法总结
Nov 06 PHP
PHP可变变量学习小结
Nov 29 PHP
详谈php ip2long 出现负数的原因及解决方法
Apr 05 PHP
实例分析PHP将字符串转换成数字的方法
Jan 27 PHP
Yii框架where查询用法实例分析
Oct 22 PHP
PHP设计模式之 策略模式Strategy详解【对象行为型】
May 01 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
PHP 并发场景的几种解决方案
2019/06/14 PHP
PHP code 验证码生成类定义和简单使用示例
2020/05/27 PHP
select标记美化--JS式插件、后期加载
2013/04/01 Javascript
jQuery操作checkbox选择(list/table)
2013/04/07 Javascript
jQuery之选择组件的深入解析
2013/06/19 Javascript
JQuery分别取得每行最后一列和最后一行的示例代码
2013/08/18 Javascript
jquery改变disabled的boolean状态的三种方法
2013/12/13 Javascript
AngularJS入门教程(零):引导程序
2014/12/06 Javascript
jQuery的end()方法使用详解
2015/07/15 Javascript
js+flash实现的5图变换效果广告代码(附演示与demo源码下载)
2016/04/01 Javascript
JS控制FileUpload的上传文件类型实例代码
2016/10/07 Javascript
JavaScript html5利用FileReader实现上传功能
2020/03/27 Javascript
Angular.js实现动态加载组件详解
2017/05/28 Javascript
Angular实现点击按钮后在上方显示输入内容的方法
2017/12/27 Javascript
详解vue中点击空白处隐藏div的实现(用指令实现)
2018/04/19 Javascript
Vue+webpack+Element 兼容问题总结(小结)
2018/08/16 Javascript
vue使用原生js实现滚动页面跟踪导航高亮的示例代码
2018/10/25 Javascript
彻底揭秘keep-alive原理(小结)
2019/05/05 Javascript
Vue项目中使用WebUploader实现文件上传的方法
2019/07/21 Javascript
[01:11:46]DOTA2-DPC中国联赛 正赛 iG vs Magma BO3 第一场 2月23日
2021/03/11 DOTA
python之super的使用小结
2018/08/13 Python
Python使用matplotlib绘制随机漫步图
2018/08/27 Python
使用python PIL库实现简单验证码的去噪方法步骤
2019/05/10 Python
使用Nibabel库对nii格式图像的读写操作
2020/07/01 Python
用python获取txt文件中关键字的数量
2020/12/24 Python
CSS3的一个简单导航栏实现
2015/08/03 HTML / CSS
澳大利亚最好的电动自行车:Leon Cycle
2020/12/19 全球购物
上班玩游戏检讨书
2014/02/07 职场文书
授权收款委托书
2014/09/23 职场文书
感谢信怎么写
2015/01/21 职场文书
赔偿协议书
2015/01/27 职场文书
销售辞职信范文
2015/03/02 职场文书
聘任协议书(挂靠)
2015/09/21 职场文书
2016学习依法治国心得体会
2016/01/15 职场文书
python 办公自动化——基于pyqt5和openpyxl统计符合要求的名单
2021/05/25 Python
Python合并pdf文件的工具
2021/07/01 Python