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(3)
Oct 09 PHP
PHP脚本的10个技巧(2)
Oct 09 PHP
使用php统计字符串中中英文字符的个数
Jun 23 PHP
彻底删除thinkphp3.1案例blog标签的方法
Dec 05 PHP
php使用cookie保存登录用户名的方法
Jan 26 PHP
PHP读书笔记_运算符详解
Jul 01 PHP
PHP实现表单提交数据的验证处理功能【防SQL注入和XSS攻击等】
Jul 21 PHP
Laravel如何使用Redis共享Session
Feb 23 PHP
php设计模式之装饰模式应用案例详解
Jun 17 PHP
php常用日期时间函数实例小结
Jul 04 PHP
php和nginx交互实例讲解
Sep 24 PHP
TP5框架实现签到功能的方法分析
Apr 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
php数据库连接时容易出错的特殊符号问题
2010/09/01 PHP
PHP中函数rand和mt_rand的区别比较
2012/12/26 PHP
解析PHP留言本模块主要功能的函数说明(代码可实现)
2013/06/25 PHP
JQuery 动画卷页 返回顶部 动画特效(兼容Chrome)
2010/02/15 Javascript
JavaScript编程开发中的五个实用小技巧
2010/07/22 Javascript
javascript闭包的理解和实例
2010/08/12 Javascript
最佳的addEvent事件绑定是怎样诞生的
2011/10/24 Javascript
js 可拖动列表实现代码
2011/12/13 Javascript
一个JQuery操作Table的代码分享
2012/03/30 Javascript
jQuery.holdReady()使用方法
2014/05/20 Javascript
js动态往表格的td中添加图片并注册事件
2014/06/12 Javascript
JSONP之我见
2015/03/24 Javascript
javascript事件冒泡实例分析
2015/05/13 Javascript
JavaScript中数组去除重复的三种方法
2016/04/22 Javascript
window.onload绑定多个事件的两种解决方案
2016/05/15 Javascript
JQuery学习总结【二】
2016/12/01 Javascript
vuex进阶知识点巩固
2018/05/20 Javascript
VUE2.0中Jsonp的使用方法
2018/05/22 Javascript
监控Nodejs的性能实例代码
2019/07/02 NodeJs
[02:28]DOTA2英雄基础教程 狼人
2013/12/23 DOTA
Python实现处理管道的方法
2015/06/04 Python
儿童python练习实例
2018/05/27 Python
python2 与 python3 实现共存的方法
2018/07/12 Python
Python访问MongoDB,并且转换成Dataframe的方法
2018/10/15 Python
Python实现计算字符串中出现次数最多的字符示例
2019/01/21 Python
python去重,一个由dict组成的list的去重示例
2019/01/21 Python
浅谈pandas.cut与pandas.qcut的使用方法及区别
2020/03/03 Python
python 装饰器的基本使用
2021/01/13 Python
CSS3+HTML5+JS 实现一个块的收缩与展开动画效果
2020/11/17 HTML / CSS
美国购买汽车零件网站:Buy Auto Parts
2018/04/02 全球购物
人力资源主管岗位职责
2014/01/29 职场文书
客户服务经理岗位职责
2014/01/29 职场文书
淘宝活动总结范文
2014/06/26 职场文书
小学生安全教育广播稿
2014/10/20 职场文书
P站美图推荐——变身女主角特辑
2022/03/20 日漫
Go gorilla securecookie库的安装使用详解
2022/08/14 Golang