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数据库信息代码
Mar 12 PHP
php strstr查找字符串中是否包含某些字符的查找函数
Jun 03 PHP
Notice: Undefined index: page in E:\PHP\test.php on line 14
Nov 02 PHP
php 计划任务 检测用户连接状态
Mar 29 PHP
php shell超强免杀、减少体积工具实现代码
Oct 16 PHP
php设计模式小结
Feb 15 PHP
php ci框架中加载css和js文件失败的解决方法
Mar 03 PHP
PHP删除数组中空值的方法介绍
Apr 14 PHP
浅谈php自定义错误日志
Feb 13 PHP
PHP+Ajax实现验证码的实时验证
Jul 20 PHP
PHPExcel在linux环境下导出报500错误的解决方法
Jan 26 PHP
php ActiveMQ的安装与使用方法图文教程
Feb 23 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写出自己的BLOG系统 2
2010/04/12 PHP
PHP分页函数代码(简单实用型)
2010/12/02 PHP
分享自定义的几个PHP功能函数
2015/04/15 PHP
laravel5创建service provider和facade的方法详解
2016/07/26 PHP
js的event详解。
2006/09/06 Javascript
javascript编程起步(第三课)
2007/02/27 Javascript
IE和Mozilla的兼容性汇总event
2007/08/12 Javascript
js电信网通双线自动选择技巧
2008/11/18 Javascript
关于javascript 回调函数中变量作用域的讨论
2009/09/11 Javascript
在模板页面的js使用办法
2010/04/01 Javascript
Ajax请求在数据量大的时候出现超时的解决方法
2014/02/27 Javascript
jQuery实现手机号码输入提示功能实例
2015/04/30 Javascript
百度地图API之本地搜索与范围搜索
2015/07/30 Javascript
JavaScript实现自动消除按钮功能的方法
2015/08/05 Javascript
基于Three.js插件制作360度全景图
2016/11/29 Javascript
微信小程序实现顶部选项卡(swiper)
2020/06/19 Javascript
React Native预设占位placeholder的使用
2017/09/28 Javascript
Angular实现的敏感文字自动过滤与提示功能示例
2017/12/29 Javascript
完美解决mui框架off-canvas侧滑超出部分隐藏无法滚动的问题
2018/01/25 Javascript
彻底理解js面向对象之继承
2018/02/04 Javascript
Vue2.0结合webuploader实现文件分片上传功能
2018/03/09 Javascript
webpack@v4升级踩坑(小结)
2018/10/08 Javascript
JQuery常用简单动画操作方法回顾与总结
2019/12/07 jQuery
javascript Canvas动态粒子连线
2020/01/01 Javascript
antd Select下拉菜单动态添加option里的内容操作
2020/11/02 Javascript
python将图片文件转换成base64编码的方法
2015/03/14 Python
浅谈MySQL中的触发器
2015/05/05 Python
python3编码问题汇总
2016/09/06 Python
Python实现一个Git日志统计分析的小工具
2017/12/14 Python
详解CSS3 rem(设置字体大小) 教程
2017/11/21 HTML / CSS
英国骑行、跑步、游泳、铁人三项运动装备专卖店:Wiggle
2016/08/23 全球购物
化石印度尼西亚在线商店:Fossil Indonesia
2019/03/11 全球购物
公司业务主管岗位职责
2013/12/07 职场文书
一份报关员的职业规划范文
2014/01/08 职场文书
我的五年职业生涯规划
2014/01/23 职场文书
食品安全责任书范本
2015/05/09 职场文书