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压缩html网页代码(清除空格,换行符,制表符,注释标记)
Apr 02 PHP
PHP 正则表达式之正则处理函数小结(preg_match,preg_match_all,preg_replace,preg_split)
Oct 05 PHP
json的键名为数字时的调用方式(示例代码)
Nov 15 PHP
php+mysql实现用户注册登陆的方法
Jan 03 PHP
php实现ip白名单黑名单功能
Mar 12 PHP
Yii2中datetime类的使用
Dec 17 PHP
PHP编程 SSO详细介绍及简单实例
Jan 13 PHP
Yii框架使用魔术方法实现跨文件调用功能示例
May 20 PHP
详解Yaf框架PHPUnit集成测试方法
Dec 27 PHP
PHP实现转盘抽奖算法分享
Apr 15 PHP
PHP使用XMLWriter读写xml文件操作详解
Jul 31 PHP
PHP使Laravel为JSON REST API返回自定义错误的问题
Oct 16 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 url地址栏传中文乱码解决方法集合
2010/06/25 PHP
分享一个PHP数据流应用的简单例子
2012/06/01 PHP
动态表单验证的操作方法和TP框架里面的ajax表单验证
2017/07/19 PHP
AutoSave/自动存储功能实现
2007/03/24 Javascript
jquery 全局AJAX事件使用代码
2010/11/05 Javascript
dotopAlert 提示用户需安装播放器的代码
2012/09/17 Javascript
javascript里模拟sleep(两种实现方式)
2013/01/25 Javascript
Javascript 实现复制(Copy)动作方法大全
2014/06/20 Javascript
多个checkbox被选中时如何判断是否有自己想要的
2014/09/22 Javascript
jquery中checkbox全选失效的解决方法
2014/12/26 Javascript
Jquery实现纵向横向菜单
2016/01/24 Javascript
Bootstrap基本组件学习笔记之分页(12)
2016/12/08 Javascript
Nodejs--post的公式详解
2017/04/29 NodeJs
JavaScript中splice与slice的区别
2017/05/09 Javascript
微信小程序实现tab和swiper切换结合效果
2020/07/17 Javascript
vue页面加载闪烁问题的解决方法
2018/03/28 Javascript
详解Vue 匿名、具名和作用域插槽的使用方法
2019/04/22 Javascript
JS遍历树层级关系实现原理解析
2020/08/31 Javascript
python通过cookie模拟已登录状态的初步研究
2016/11/09 Python
Python统计python文件中代码,注释及空白对应的行数示例【测试可用】
2018/07/25 Python
python读文件的步骤
2019/10/08 Python
Python多线程正确用法实例解析
2020/05/30 Python
python opencv 实现读取、显示、写入图像的方法
2020/06/08 Python
Python astype(np.float)函数使用方法解析
2020/06/08 Python
Python 读取位于包中的数据文件
2020/08/07 Python
HTML5中的强制下载属性download使用实例解析
2016/05/12 HTML / CSS
捷克玩具商店:Bambule
2019/02/23 全球购物
大学生毕业自我评价范文分享
2013/11/07 职场文书
家长通知书家长评语
2014/04/17 职场文书
大学生毕业求职信
2014/06/12 职场文书
暑期培训班策划方案
2014/08/26 职场文书
小学元宵节活动总结
2015/02/06 职场文书
2015年反洗钱工作总结
2015/04/25 职场文书
家庭经济困难证明
2015/06/23 职场文书
如何书写授权委托书?
2019/06/25 职场文书
一篇文章了解正则表达式的替换技巧
2022/02/24 Javascript