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
PHP生成静态页
Nov 25 PHP
让PHP更快的提供文件下载的代码
Jun 13 PHP
php上传图片存入数据库示例分享
Mar 11 PHP
php简单实现MVC
Feb 05 PHP
ThinkPHP模板循环输出Volist标签用法实例详解
Mar 23 PHP
php仿微信红包分配算法的实现方法
May 13 PHP
zen cart实现订单中增加paypal中预留电话的方法
Jul 12 PHP
laravel中命名路由的使用方法
Feb 24 PHP
详解php命令注入攻击
Apr 06 PHP
PHP基础之输出缓冲区基本概念、原理分析
Jun 19 PHP
PHP getID3类的使用方法学习笔记【附getID3源码下载】
Oct 18 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中文字母数字验证码实现代码
2008/04/25 PHP
Javascript 中文字符串处理额外注意事项
2009/11/15 Javascript
超级简单的jquery操作表格方法
2014/12/15 Javascript
jQuery源码解读之removeAttr()方法分析
2015/02/20 Javascript
jQuery实现网页抖动的菜单抖动效果
2015/08/07 Javascript
基于Echarts 3.19 制作常用的图形(非静态)
2016/05/19 Javascript
jQuery监听文件上传实现进度条效果的方法
2016/10/16 Javascript
javaScript中定义类或对象的五种方式总结
2016/12/04 Javascript
JS获取鼠标位置距浏览器窗口距离的方法示例
2017/04/11 Javascript
微信小程序 选项卡的简单实例
2017/05/24 Javascript
微信小程序 Buffer缓冲区的详解
2017/07/06 Javascript
微信小程序 转发功能的实现
2017/08/04 Javascript
JS实现在文本指定位置插入内容的简单示例
2017/12/22 Javascript
Webpack devServer中的 proxy 实现跨域的解决
2018/06/15 Javascript
vue使用Font Awesome的方法步骤
2019/02/26 Javascript
利用js canvas实现五子棋游戏
2020/10/11 Javascript
Python重新引入被覆盖的自带function
2014/07/16 Python
Python端口扫描简单程序
2016/11/10 Python
python中利用Future对象异步返回结果示例代码
2017/09/07 Python
Python实现将doc转化pdf格式文档的方法
2018/01/19 Python
Python面向对象之继承代码详解
2018/01/29 Python
详解Python 装饰器执行顺序迷思
2018/08/08 Python
python版大富翁源代码分享
2018/11/19 Python
python 实现分页显示从es中获取的数据方法
2018/12/26 Python
Python编程flask使用页面模版的方法
2018/12/28 Python
在django模板中实现超链接配置
2019/08/21 Python
澳大利亚第一旅行车和房车配件店:Caravan RV Camping
2020/12/26 全球购物
中学教师自我鉴定
2014/02/07 职场文书
生产车间标语
2014/06/11 职场文书
教师批评与自我批评
2014/10/15 职场文书
2014最新预备党员思想汇报范文:中国梦,我的梦
2014/10/25 职场文书
《我的伯父鲁迅先生》教学反思
2016/02/16 职场文书
2019年XX公司的晨会制度及流程!
2019/07/23 职场文书
写给医护人员的一封感谢信
2019/09/16 职场文书
Go语言 go程释放操作(退出/销毁)
2021/04/30 Golang
python 命令行传参方法总结
2021/05/25 Python