ホームページ  >  記事  >  バックエンド開発  >  php+redis を共有して 200 万人のユーザーにインスタント プッシュ サービスを実装

php+redis を共有して 200 万人のユーザーにインスタント プッシュ サービスを実装

藏色散人
藏色散人転載
2020-10-28 16:49:355002ブラウズ

推奨: 「PHP ビデオ チュートリアル

200 万ユーザーへのインスタント プッシュを実装する方法。このプッシュは次のように理解できます。最初のスリーパーティ インターフェイス、プッシュ、SMS などの呼び出し。

当時は、まず DB を直接読み込んで結果を個別にプッシュするデモを書きました。 。 。 。

##ということで、redis+phpマルチプロセスをベースにしたソリューションを設計してみました。悪くはありませんが、スケーラビリティが高いので共有します。

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

具体的なロジックは次のとおりです: (フォントを無視してください)

実際、ここで最適化できます。私の考えは、より多くのユーザー データがある場合です。その場合は、redis でデータを分割し、複数のリストを使用すると、各リストが複数の 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 スクリプトを長時間実行することは避けています。時間。

また、ユーザーは決して固定の 200 万ユーザーではありません。毎日増加します。私の計画では、時間指定スクリプトを使用してユーザーの増加を自分で設計したユーザー テーブルに整理し、管理することです。それは私自身です。

ps: すべてのスクリプトを小さな PHP ネイティブ フレームワークに入れて、一元管理できるようにまとめました。しばらくしてから送信します。


修正は大歓迎です、ありがとうございます。

以上がphp+redis を共有して 200 万人のユーザーにインスタント プッシュ サービスを実装の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcsdn.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。