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的header和asp中的redirect比较
Oct 09 PHP
其他功能
Oct 09 PHP
安装PHP可能遇到的问题“无法载入mysql扩展” 的解决方法
Apr 16 PHP
微盾PHP脚本加密专家php解密算法
Sep 13 PHP
深入解析php中的foreach函数
Aug 31 PHP
PHP中使用localhost连接Mysql不成功的解决方法
Aug 20 PHP
Laravel实现用户注册和登录
Jan 23 PHP
php返回字符串中所有单词的方法
Mar 09 PHP
PHP使用内置函数file_put_contents写入文件及追加内容的方法
Dec 07 PHP
CodeIgniter多语言实现方法详解
Jan 20 PHP
Yii2针对游客、用户防范规则和限制的解决方法分析
Oct 08 PHP
遍历echsop的region表形成缓存的程序实例代码
Nov 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获取服务器端mac和客户端mac的地址支持WIN/LINUX
2014/05/15 PHP
PHP中strlen()和mb_strlen()的区别浅析
2014/06/19 PHP
php文档工具PHP Documentor安装与使用方法
2016/01/25 PHP
PHP中Cookie的使用详解(简单易懂)
2017/04/28 PHP
Gird事件机制初级读本
2007/03/10 Javascript
基于Jquery插件开发之图片放大镜效果(仿淘宝)
2011/11/19 Javascript
面向对象的Javascript之一(初识Javascript)
2012/01/20 Javascript
javascript 禁用IE工具栏,导航栏等等实现代码
2013/04/01 Javascript
javascript中全局对象的isNaN()方法使用介绍
2013/12/19 Javascript
SWFObject基本用法实例分析
2015/07/20 Javascript
实例详解jQuery表单验证插件validate
2016/01/18 Javascript
jQuery实现多级联动下拉列表查询框
2016/01/18 Javascript
为什么JavaScript没有块级作用域
2016/05/22 Javascript
js实现楼层效果的简单实例
2016/07/15 Javascript
jquery 判断selection range 是否在容器中的简单实例
2016/08/02 Javascript
Vue列表页渲染优化详解
2017/07/24 Javascript
SeaJS中use函数用法实例分析
2017/10/10 Javascript
vue组件实现弹出框点击显示隐藏效果
2020/10/26 Javascript
Vue通过for循环随机生成不同的颜色或随机数的实例
2019/11/09 Javascript
在vue中实现清除echarts上次保留的数据(亲测有效)
2020/09/09 Javascript
关于JavaScript数组去重的一些理解汇总
2020/09/10 Javascript
vue中是怎样监听数组变化的
2020/10/24 Javascript
python抓取某汽车网数据解析html存入excel示例
2013/12/04 Python
对Django外键关系的描述
2019/07/26 Python
应用OpenCV和Python进行SIFT算法的实现详解
2019/08/21 Python
python数组循环处理方法
2019/08/26 Python
python 利用已有Ner模型进行数据清洗合并代码
2019/12/24 Python
python传到前端的数据,双引号被转义的问题
2020/04/03 Python
Linux如何命名文件--使用文件名时应注意
2012/01/22 面试题
软件测试工程师面试问题精选
2016/10/28 面试题
Java基础面试题
2014/07/19 面试题
入党自我鉴定范文
2013/10/04 职场文书
实习生求职自荐信
2014/02/07 职场文书
投标承诺书范本
2014/03/27 职场文书
环保倡议书格式范文
2014/05/14 职场文书
教师节感想
2015/08/11 职场文书