首頁  >  文章  >  後端開發  >  分享php+redis實現對200w用戶的即時推播服務

分享php+redis實現對200w用戶的即時推播服務

藏色散人
藏色散人轉載
2020-10-28 16:49:355000瀏覽

推薦:《PHP視訊教學

#怎麼實現對200w用戶的即時推送,這個推送可以理解為呼叫第三方的接口,push,sms之類的東西。

當時先寫了一個demo 直接讀取DB然後單一推送,結果。 。 。 。可想而知

於是設計一套基於redis+php多進程的方案,用著還不錯而去擴展性蠻高的,故分享之。

======================= ===== =

具體的邏輯如下:(無視我的字體)

其實這裡還可以優化的,我的設想是如果用戶資料再多一些的話,可以在redis裡對資料進行分割採取多List,每一個List對應多個php進程這樣會更快。

下面是我實現的具體程式碼:

主管理腳本:應用程式時啟動這個即可。

<?php          //push推送配置  注:使用前请确认log文件为空       2016-04-12
include_once(dirname (__FILE__)."/../../config.inc.php");
//if(exec(&#39;ps aux | grep redis_push.php | grep -v grep | wc -l&#39;) != 0) goto check;
import(&#39;push.class.php&#39;);
import(&#39;Redis.class.php&#39;);

$time  =time();
$data  = array("apikey"=>&#39;xxxx&#39;,"secret"=>&#39;xxxx&#39;);
$push  = new Channel($data);
$redis = new RedisCache($Credis[&#39;host&#39;],$Credis[&#39;port&#39;]);
if(exec(&#39;ps aux | grep redis_push.php | grep -v grep | wc -l&#39;) != 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[&#39;OpenType&#39;]==1 ? "是" : "否";
$c = json_encode($config);
$info = <<<monkey
   ************ 请确认信息是否有误*10秒后启动push任务! *************
   * 文件名称   : {$config[&#39;file&#39;]};
   * 推送标题   : {$config[&#39;Title&#39;]};
   * 推送内容   : {$config[&#39;Content&#39;]};
   * 是否跳转   : {$config[&#39;OpenType&#39;]};
   * 进程数量   : $num;(如果为单进程无视此项)
   * 睡眠时间   : {$config[&#39;s&#39;]};
   * 日志目录   : /log;
   ***************************************************************\n
monkey;
echo $info;
sleep(3);
$n = 1;
while($n<=10){
  echo (10-$n++),"秒\n";
  sleep(1);
}
echo "------------------------- 任务已启动 -------------------------\n";
if($redis->Scount(&#39;push_getchannel_success&#39;)){
  echo "队列有未完成任务\n";
}else{
  $res = exec("php redis_getchannel.php {$config[&#39;file&#39;]}");//写入redis脚本
  echo $res;
}
smtp_mail(&#39;xxxx@qq.com&#39;,&#39;推送任务已开启&#39;,&#39;请实时监测,5秒后您的手机将接收到测试推送!&#39;);//推送监控 实现定时全自动推送 
echo "\n---------------- 5秒后 test 将收到测试推送消息 ----------------\n";
sleep(5);
$re = $push->BaiduPush(&#39;xxxx&#39;,&#39;xxxxx&#39;,$config[&#39;Content&#39;],$config[&#39;Title&#39;],&#39;1&#39;,$config[&#39;OpenType&#39;],$config[&#39;Url&#39;],&#39;xxxxx&#39;,$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  &#39;{$c}&#39; > /dev/null 2>&1 &");
}

check:
while(1){
  if(exec(&#39;ps aux | grep redis_push.php | grep -v grep | wc -l&#39;) == 0){
    echo "push 发送完成 用时",time()-$time,"秒";
    die();
  }
  echo "当前进程数:",exec(&#39;ps aux | grep redis_push.php | grep -v grep | wc -l&#39;),"个","\n";
  echo "当前剩余推送数量:".$redis->Scount(&#39;push_getchannel_success&#39;)."\n";
  sleep(10);
}

至於寫入redis和具體的推送腳本這個靠自己的想像裡就好了我就不發了嘿嘿

我的做法是具體的推送腳本在推送一定數量後會自動終止並呼叫自己本身。

因為在實際應用程式中發現php腳本在長時間運行之後會發生假死(可能是因為上下文切換的問題),

所以我都是避免讓php腳本長時間運行。

還有就是用戶肯定不是固定的200w用戶 每天都會有一個增量,我的方案是透過定時腳本每天把增量的用戶整理進我自己設計的一個用戶表自己管理。

ps:我把所有的腳本弄到了一個我自己整理的小的php原生框架統一管理,過段時間我發出來。

歡迎指正,謝謝。

以上是分享php+redis實現對200w用戶的即時推播服務的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:csdn.net。如有侵權,請聯絡admin@php.cn刪除