im-cloud分布式ミドルウェア分析(四)-logicノード実装


github:
http://github.com/brewlin/im-...
  • im-cloud swoole原生コヒーレンスに基づいて分布式プッシュミドルウェアを構築
  • im-cloud分散ミドルウェアのインストール導入
  • im-cloud<>goim分布式中間部品同時圧力測定比較
  • im-cloud分布式ミドルウェア分析(一)-通信プロトコル
  • im-cloud分布式ミドルウェア分析(二)-cloudノード実装
  • im-cloud分布式ミドルウェア分析(三)-jobノード実装
  • im-cloud ( )-logic

  • 1.概要
    logicノードは生産者とclient端として、業務ノードとしてpushプッシュresetapiインタフェースを提供し、複数のノードを拡張してnginx負荷等化を行うことができる.
    图片描述
    2.@Producer
    デフォルトでは10個のメッセージキュー接続プールが起動し、taskプロセスで各人物に対してコヒーレント非同期生産タスクを作成します.
    非同期taskタスク
    直接コンポーネントtaskインタフェースを呼び出してtaskプロセスに配信実行を行い、task配信は非ブロック操作であり、実行が完了すると直接戻り、workerが同時要求を処理する能力を大幅に向上させた.唯一の影響は、複数のtaskプロセスの消費能力がworkerの配信速度に及ばなければworkerの処理能力にも影響を与えるため、取捨選択が必要である
  • 特定のメッセージキュー生成taskプロセスで実行する
  • .
  • taskプロセスでは、送信された各タスクに対してデフォルトで1つのコラボレーション
  • が作成されるコラボレーションモードが有効になります.
    use Task\Task;
    /**
    * @var LogicPush
    */
    Task::deliver(LogicPush::class,"pushMids",[(int)$arg["op"],$arg["mids"],$arg["msg"]]);
  • 関連非同期タスクは、ネーミングスペースApp\Taskの下
  • に格納される.
    そうかんさいてきか
    ようきか
    単一のリクエスト・プロセスで実行されるライフサイクルでは、最大10個以上のオブジェクトの生成が呼び出されます.コンカレントが大きい場合はGCがほぼ最初に切られ、待ち時間がかかるのでnewオブジェクトにも最適化の余地があります
    プロジェクトは初期化、すなわちメインプロセスの起動中に関連コードをスキャンし、注釈があれば収集し、コンテナcontainerにインスタンス化し、後で何度も使用するときに直接コードを多重化し、newオブジェクトを何度も必要とせず、スペースと時間を大幅に節約します.以下の図では、タスクを実行するために、関連オブジェクトをコンテナから取得します.
    Co::create(function ()use($op,$mids,$msg){
        /** @var RedisDao $servers */
        $servers = \container()->get(RedisDao::class)->getKeysByMids($mids);
        $keys = [];
        foreach($servers as $key => $server){
            $keys[$server][] = $key;
        }
        foreach($keys as $server => $key){
            //        , job   
            \container()->get(QueueDao::class)->pushMsg($op,$server,$key,$msg);
        }
    
    },true);
    //      true     Context::waitGroup()         

    上の図に示すように、コンポーネントが提供する複数のメソッドを呼び出してコンテナオブジェクトを取得できます.
  • container()->get(class)
  • bean(class)
  • 両方ともコンテナオブジェクトを取得できます.

  • 同時性の向上
    主要な時間のかかるタスクをtaskプロセスで実行しても、workerプロセスでは少量の待ち時間があります.現在は、要求が来たときにデータを取得した後、直接返信して現在の接続を終了し、タスクを継続することで、taskタスクを送信してから現在の接続を終了する必要がなくなり、同時能力が大幅に向上します.時間のかかるパフォーマンスに大きな変化はないかもしれませんが、同時性が大幅に向上します.次のようになります.
        /**
         * @return \Core\Http\Response\Response|static
         */
        public function mids()
        {
            Context::get()->getResponse()->end();
            $post  = Context::get()->getRequest()->input();
            if(empty($post["operation"]) || empty($post["mids"]) ||empty($post["msg"])){
                return $this->error("    ");
            }
            $arg = [
                "op" => $post["operation"],
                "mids" => is_array($post["mids"])?$post["mids"]:[$post["mids"]],
                "msg" => $post["msg"]
            ];
            Log::debug("push mids post data:".json_encode($arg));
            /**
             * @var LogicPush
             */
            Task::deliver(LogicPush::class,"pushMids",[(int)$arg["op"],$arg["mids"],$arg["msg"]]);
        }
  • 上の図のようにContext::get()->getResponse()->end();を直接使用して、reponseオブジェクトをコモンコンテキストで取得する現在の接続を直接終了し、現在のタスクを継続して実行し、メモリ
  • を解放する.