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 相关文章推荐
第十三节 对象串行化 [13]
Oct 09 PHP
php面向对象全攻略 (二) 实例化对象 使用对象成员
Sep 30 PHP
php 生成随机验证码图片代码
Feb 08 PHP
php计算十二星座的函数代码
Aug 21 PHP
json的键名为数字时的调用方式(示例代码)
Nov 15 PHP
thinkphp模板的包含与渲染实例分析
Nov 26 PHP
PHP读取文本文件并逐行输出该行使用最多的字符与对应次数的方法
Nov 25 PHP
PHP + plupload.js实现多图上传并显示进度条加删除实例代码
Mar 06 PHP
php微信公众号开发之图片回复
Oct 20 PHP
python进程与线程小结实例分析
Nov 11 PHP
使用composer 安装 laravel框架的方法图文详解
Aug 02 PHP
PHP强制转化的形式整理
May 22 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
Smarty模板快速入门
2007/01/04 PHP
php实现斐波那契数列的简单写法
2014/07/19 PHP
ThinkPHP框架表单验证操作方法
2017/07/19 PHP
PHP getID3类的使用方法学习笔记【附getID3源码下载】
2019/10/18 PHP
PHP实现随机发扑克牌
2020/04/22 PHP
两个数组去重的JS代码
2013/12/04 Javascript
Javascript实现禁止输入中文或英文的例子
2014/12/09 Javascript
png在IE6 下无法透明的解决方法汇总
2015/05/21 Javascript
纯JavaScript实现的分页插件实例
2015/07/14 Javascript
Node.js巧妙实现Web应用代码热更新
2015/10/22 Javascript
javascript实现一个网页加载进度loading
2017/01/04 Javascript
jQuery插件HighCharts绘制的2D堆柱状图效果示例【附demo源码下载】
2017/03/14 Javascript
Javascript循环删除数组中元素的几种方法示例
2017/05/18 Javascript
vue2.0全局组件之pdf详解
2017/06/26 Javascript
JS实现的抛物线运动效果示例
2018/01/30 Javascript
json字符串传到前台input的方法
2018/08/06 Javascript
详解VUE Element-UI多级菜单动态渲染的组件
2019/04/25 Javascript
产制造追溯系统之通过微信小程序实现移动端报表平台
2019/06/03 Javascript
你不知道的 TypeScript 高级类型(小结)
2020/08/28 Javascript
python 实现归并排序算法
2012/06/05 Python
python操作CouchDB的方法
2014/10/08 Python
Python算法应用实战之队列详解
2017/02/04 Python
python使用knn实现特征向量分类
2018/12/26 Python
python使用for循环计算0-100的整数的和方法
2019/02/01 Python
使用Pytorch来拟合函数方式
2020/01/14 Python
Python利用PyPDF2库获取PDF文件总页码实例
2020/04/03 Python
HTML5实现视频直播功能思路详解
2017/11/16 HTML / CSS
英国电子产品购物网站:Tech in the basket
2019/11/08 全球购物
介绍一下XMLHttpRequest对象的常用方法和属性
2013/05/24 面试题
老公给老婆的道歉信
2014/01/10 职场文书
学生打架检讨书
2014/02/14 职场文书
期终自我鉴定
2014/02/17 职场文书
竞选大队委员演讲稿
2014/04/28 职场文书
2014年保密工作总结
2014/11/22 职场文书
2014年民主评议党员工作总结
2014/12/02 职场文书
Java实现注册登录跳转
2022/06/16 Java/Android