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 相关文章推荐
使用网络地址转换实现多服务器负载均衡
Oct 09 PHP
windows下PHP APACHE MYSQ完整配置
Jan 02 PHP
基于initPHP的框架介绍
Apr 18 PHP
php pki加密技术(openssl)详解
Jul 01 PHP
PHP随机生成随机个数的字母组合示例
Jan 14 PHP
phpmyadmin出现Cannot start session without errors问题解决方法
Aug 14 PHP
PHP常用正则表达式集锦
Aug 17 PHP
PHP获取数组的键与值方法小结
Jun 13 PHP
PHP.vs.JAVA
Apr 29 PHP
php pdo oracle中文乱码的快速解决方法
May 16 PHP
PHP微信API接口类
Aug 22 PHP
php array_walk_recursive 使用自定的函数处理数组中的每一个元素
Nov 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
oracle资料库函式库
2006/10/09 PHP
PHP 字符截取 解决中文的截取问题,不用mb系列
2009/09/29 PHP
一个典型的PHP分页实例代码分享
2011/07/28 PHP
第三章 php操作符与控制结构代码
2011/12/30 PHP
php实现图片上传并进行替换操作
2016/03/15 PHP
treepanel动态加载数据实现代码
2012/12/15 Javascript
javascript中的onkeyup和onkeydown区别介绍
2013/04/28 Javascript
JavaScript的setAttribute兼容性问题解决方法
2013/11/11 Javascript
Google (Local) Search API的简单使用介绍
2013/11/28 Javascript
JavaScript获取图片的原始尺寸以宽度为例
2014/05/04 Javascript
Node.js模块加载详解
2014/08/16 Javascript
JavaScript中合并数组的N种方法
2014/09/16 Javascript
javascript上下方向键控制表格行选中并高亮显示的方法
2015/02/13 Javascript
jquery 表单验证之通过 class验证表单不为空
2015/11/02 Javascript
WordPress 单页面上一页下一页的实现方法【附代码】
2016/03/10 Javascript
基于jquery插件实现拖拽删除图片功能
2020/08/27 Javascript
对javascript继承的理解
2016/10/11 Javascript
SVG动画vivus.js库使用小结(实例代码)
2017/09/14 Javascript
js前端导出Excel的方法
2017/11/01 Javascript
webpack4 css打包压缩问题的解决
2018/05/18 Javascript
Fetch超时设置与终止请求详解
2019/05/18 Javascript
Vue切换组件实现返回后不重置数据,保留历史设置操作
2020/07/21 Javascript
如何管理Vue中的缓存页面
2021/02/06 Vue.js
python 图片验证码代码分享
2012/07/04 Python
Python 爬虫的工具列表大全
2016/01/31 Python
利用Python批量生成任意尺寸的图片
2016/08/29 Python
Python3生成手写体数字方法
2018/01/30 Python
Python3中的json模块使用详解
2018/05/05 Python
Python 读取某个目录下所有的文件实例
2018/06/23 Python
利用pandas读取中文数据集的方法
2018/07/25 Python
python绘制多个子图的实例
2019/07/07 Python
Django中使用CORS实现跨域请求过程解析
2019/08/05 Python
基于Python和PyYAML读取yaml配置文件数据
2020/01/13 Python
接口自动化多层嵌套json数据处理代码实例
2020/11/20 Python
活着观后感
2015/06/03 职场文书
销区经理年终述职报告模板
2019/11/28 职场文书