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 和 MYSQL
Oct 09 PHP
PHP如何解决网站大流量与高并发的问题
Jun 25 PHP
PHP imagecreatefrombmp 从BMP文件或URL新建一图像
Jul 16 PHP
php调整gif动画图片尺寸示例代码分享
Dec 05 PHP
zf框架的registry(注册表)使用示例
Mar 13 PHP
谈谈你对Zend SAPIs(Zend SAPI Internals)的理解
Nov 10 PHP
php 从一个数组中随机的取出若干个不同的数实例
Dec 31 PHP
Thinkphp事务操作实例(推荐)
Apr 01 PHP
利用PHP_XLSXWriter代替PHPExcel的方法示例
Jul 16 PHP
PHP使用 Pear 进行安装和卸载包的方法详解
Jul 08 PHP
laravel 修改.htaccess文件 重定向public的解决方法
Oct 12 PHP
Laravel框架源码解析之反射的使用详解
May 14 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新手上路(八)
2006/10/09 PHP
php 定界符格式引起的错误
2011/05/24 PHP
php数组函数序列之array_slice() - 在数组中根据条件取出一段值,并返回
2011/11/07 PHP
PHP实现自动登入google play下载app report的方法
2014/09/23 PHP
PHP实现检测客户端是否使用代理服务器及其匿名级别
2015/01/07 PHP
在openSUSE42.1下编译安装PHP7 的方法
2015/12/24 PHP
Laravel框架使用Seeder实现自动填充数据功能
2018/06/13 PHP
Mootools 1.2教程 类(一)
2009/09/15 Javascript
来自qq的javascript面试题
2010/07/24 Javascript
Jquery下attr和removeAttr的使用方法
2010/12/28 Javascript
JQuery实现当鼠标停留在某区域3秒后自动执行
2014/09/09 Javascript
JavaScript事件委托实例分析
2015/05/26 Javascript
javascript实现网页端解压并查看zip文件
2015/12/15 Javascript
jQuery中Find选择器用法示例
2016/09/21 Javascript
jQuery扩展实现text提示还能输入多少字节的方法
2016/11/28 Javascript
Node.js Mongodb 密码特殊字符 @的解决方法
2017/04/11 Javascript
基于bootstrap写的一点localStorage本地储存
2017/11/21 Javascript
nodejs中密码加密处理操作详解
2018/03/20 NodeJs
Vue2.0+Vux搭建一个完整的移动webApp项目的示例
2019/03/19 Javascript
react实现复选框全选和反选组件效果
2020/08/25 Javascript
JavaScript中的执行环境和作用域链
2020/09/04 Javascript
[02:08]我的刀塔不可能这么可爱 胡晓桃_1
2014/06/20 DOTA
对TensorFlow的assign赋值用法详解
2018/07/30 Python
Python计算信息熵实例
2020/06/18 Python
解决tensorflow 释放图,删除变量问题
2020/06/23 Python
需要知道的CSS3动画技术
2010/01/01 HTML / CSS
美国知名的女性服饰品牌:LOFT(洛芙特)
2016/08/05 全球购物
迪卡侬比利时官网:Decathlon比利时
2019/12/28 全球购物
经管应届生求职信
2013/11/17 职场文书
《翻越远方的大山》教学反思
2014/04/13 职场文书
六一亲子活动总结
2014/07/01 职场文书
领导班子遵守党的政治纪律情况对照检查材料
2014/09/26 职场文书
2014年文明创建工作总结
2014/11/25 职场文书
天下第一关导游词
2015/02/06 职场文书
单位实习介绍信
2015/05/05 职场文书
2016秋季运动会前导词
2015/11/25 职场文书