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 memcache扩展的三种安装方法
Apr 26 PHP
114啦源码(114la)不能生成地方房产和地方报刊问题4级页面0字节的解决方法
Jan 12 PHP
destoon利用Rewrite规则设置网站安全
Jun 21 PHP
php采用curl实现伪造IP来源的方法
Nov 21 PHP
PHP内核探索:哈希表碰撞攻击原理
Jul 31 PHP
PHP使用缓存即时输出内容(output buffering)的方法
Aug 03 PHP
PHP版本常用的排序算法汇总
Dec 20 PHP
PHP对象的浅复制与深复制的实例详解
Oct 26 PHP
PHP实现验证码校验功能
Nov 16 PHP
PHP封装的分页类与简单用法示例
Feb 25 PHP
php输出反斜杠的实例方法
Sep 19 PHP
PHP网站常见安全漏洞,及相应防范措施总结
Mar 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高自定义性安全验证码代码
2011/11/27 PHP
windows8.1下Apache+Php+MySQL配置步骤
2015/10/30 PHP
cakephp2.X多表联合查询join及使用分页查询的方法
2017/02/23 PHP
PHP实现的mysql主从数据库状态检测功能示例
2017/07/20 PHP
PHPExcel实现表格导出功能示例【带有多个工作sheet】
2018/06/13 PHP
Laravel框架实现文件上传的方法分析
2019/09/29 PHP
对采用动态原型方式无法展示继承机制得思考
2009/12/04 Javascript
Colortip基于jquery的信息提示框插件在IE6下面的显示问题修正方法
2010/12/06 Javascript
jquery插件tooltipv顶部淡入淡出效果使用示例
2013/12/05 Javascript
jQuery之字体大小的设置方法
2014/02/27 Javascript
jQuery中parents()方法用法实例
2015/01/07 Javascript
jQuery.each使用详解
2015/07/07 Javascript
jQuery实现布局高宽自适应的简单实例
2016/05/28 Javascript
NodeJS中的MongoDB快速入门详细教程
2016/11/11 NodeJs
JS基于面向对象实现的拖拽功能示例
2016/12/20 Javascript
jQuery插件ajaxFileUpload使用详解
2017/01/10 Javascript
微信小程序教程系列之视图层的条件渲染(10)
2017/04/19 Javascript
JS去除字符串最后的逗号实例分析【四种方法】
2019/06/20 Javascript
vue+echarts实现动态折线图的方法与注意
2020/09/01 Javascript
关于JavaScript数组去重的一些理解汇总
2020/09/10 Javascript
Python实现Const详解
2015/01/27 Python
python使用TensorFlow进行图像处理的方法
2018/02/28 Python
Django实现分页功能
2018/07/02 Python
python在不同条件下的输入与输出
2020/02/13 Python
快速解决jupyter启动卡死的问题
2020/04/10 Python
python 常见的反爬虫策略
2020/09/27 Python
使用CSS3来匹配横屏竖屏的简单方法
2015/08/04 HTML / CSS
HTML5超文本标记语言的实现方法
2020/09/24 HTML / CSS
附答案的Java面试题
2012/11/19 面试题
求两个数的乘积和商数,该作用由宏定义来实现
2013/03/13 面试题
创伤外科专业推荐信范文
2013/11/19 职场文书
金融管理专业毕业生求职信
2014/03/12 职场文书
MySQL索引篇之千万级数据实战测试
2021/04/05 MySQL
Python使用protobuf序列化和反序列化的实现
2021/05/19 Python
matplotlib画混淆矩阵与正确率曲线的实例代码
2021/06/01 Python
Python还能这么玩之用Python修改了班花的开机密码
2021/06/04 Python