ホームページ >バックエンド開発 >PHPチュートリアル >PHP の RPC フレームワークは、Redis に基づいたフロー制御システムを実装します。
以前は、すべてのモジュールが 1 つのプロジェクト (大きなフォルダー) に配置されていましたが、これの欠点は明らかです。 その後、ビジネス機能に応じてサブモジュールに分割し、各サブモジュールには独自の独立したオンライン マシン クラスター、mysql、redis、およびその他のストレージ リソースが存在します。このようなサブモジュールの問題は、他のモジュールに影響を与えず、保守性と拡張性がより高くなります。
しかし、実際には、各サブモジュールのサービス能力は異なります。サブモジュールごとに分割した後のアーキテクチャ図に示されているように、モジュール A に到達する QPS が 100 であり、A は B に依存し、各 A モジュールが到達すると仮定します。 B. モジュールの要求 QPS も 100 ですが、モジュール B が提供できる最大 QPS 能力は 50 です。トラフィック制限がない場合、モジュール B は負荷を超えてトラフィックを蓄積し、システム全体が使用できなくなります。動的フロー制御システムは、サブモジュールの最適なサービス機能を、モジュール A からモジュール B へのトラフィックを 50QPS に制限することです。これにより、要求の少なくとも一部が、システム全体の負荷を低下させることなく正常に処理できるようになります。 1 つのサブサービスの障害が発生した場合。
私たちの RPC フレームワークは、主に http プロトコル アクセスをサポートする PHP 実装フレームワークです。フロントエンド A モジュールの場合、それが依存するバックエンド B モジュールの場合、B モジュールを最初にサービス構成し、次にサービス名に従って参照およびアクセスする必要があります。サービス構成の一般的な形式は次のとおりです。 :
[MODULE-B] ; 服务名字 protocol = "http" ;交互协议 lb_alg = "random" ; 负载均衡算法 conn_timeout_ms = 1000 ; 连接超时,所有协议使用, 单位为ms read_timeout_ms = 3000 ; 读超时 write_timeout_ms = 3000 ; 写超时 exe_timeout_ms = 3000 ; 执行超时 host.default[] = "127.0.0.1" ; ip或域名 host.default[] = "127.0.0.2" ; ip或域名 host.default[] = "127.0.0.3" ; ip或域名 port = 80 ; 端口 domain = 'api.abc.com' ; 域名配置,不作真正解析,作为header host字段传给后端
サービスにアクセスするには、通常、モジュールはクラスターとしてデプロイされ、マシンクラスターのすべての IP を構成する必要があります。もちろん、内部 DNS サービスがある場合は、ドメインを装備することもできます。クラスターの名前。
RPC フレームワークの基本機能には、ロード バランシング、ヘルス チェック、ダウングレードと電流制限などが含まれます。トラフィック制御は、ダウングレードと電流制限機能のためのものです。詳細を紹介する前に、ロード バランシングとヘルスについて説明しましょう。検査がどのように実装されるかは、フロー制御実装の基礎です。
負荷分散のためにランダム アルゴリズムとポーリング アルゴリズムを実装しました。ランダム アルゴリズムは、すべての IP から 1 つをランダムに選択することで実装できます。ポーリング アルゴリズムは、スタンドアロン ポーリングに基づいており、最後に選択された IP シリアル番号。apcu 拡張子は、次に使用する IP シリアル番号を見つけやすくするためにローカル メモリに記録されます。
アクセスされたマシンは失敗する可能性があります。失敗したリクエスト IP を Redis に記録し、記録された失敗ログを分析して、マシン IP を削除する必要があるかどうかを判断します。つまり、この IP を持つマシンはハングアップしていると見なされ、提供できません。通常のサービス。これはヘルス チェックの機能です。関連するサービス設定項目を通じてヘルス チェックの特定の機能を紹介します。
ip_fail_sample_ratio = 1 ; 采样比例 失败IP记录采样比例,我们将失败的请求记录在redis中,为防止太多的redis请求,我们可以配一个失败采样比例 ip_fail_cnt_threshold = 10; IP失败次数 ip_fail_delay_time_s = 2 ; 时间区间 ip_fail_client_cnt = 3 ; 失败的客户端数 不可能一个IP失败一次就将其从健康IP列表中去掉,只有在有效的ip_fail_delay_time_s 时间范围内,请求失败了 ip_fail_cnt_threshold 次,并且失败的客户端达到ip_fail_client_cnt 个, 才认为其是不健康的IP。 为什么要添加 ip_fail_client_cnt 这样一个配置,因为如果只是某一台机器访问后端某个服务IP失败,那不一定是服务IP的问题,也可能是访问客户端的问题,只有当大多数客户端都有失败记录时才认为是后端服务IP的问题 我们将失败日志记录在redis的list表中,并带上时间戳,就比较容易统计时间区间内的失败次数。 ip_retry_delay_time_s = 30 ; 检查失败IP是否恢复间隔时间 某个失败的IP有可能在一定时间内恢复,我们间隔 ip_retry_delay_time_s 长的时间去检查,如果请求成功,则从失败的IP列表中去除 ip_retry_fail_cnt = 10; 失败IP如果检查失败,记录的失败权重值 ip_log_ttl_s = 60000; 日志有效期时间 一般来说只有最近的失败日志才有意义,对于历史的日志我们将其自动删除。 ip_log_max_cnt = 10000; 记录的最大日志量 我们用redis记录失败日志,容量有限,我们要设定一个记录的最大日志数量,多余的日志自动删除。
コードの実装では、通常のサービス IP 設定に加えて、障害が発生した IP も維持します。このように、アルゴリズムを通じて IP を選択するときは、まず失敗した IP を削除し、失敗した IP をファイルに記録し、apcu メモリ キャッシュを使用してアクセスを高速化する必要があります。そのため、すべての操作は基本的にメモリ アクセスに基づいています。パフォーマンス上の問題は発生しません。
リクエストが失敗した場合にのみ、失敗した IP を Redis に記録します。これには、Redis リスト内のすべての失敗ログをクエリし、同時により複雑な操作をカウントする必要があります。私たちの実装は、複数の PHP プロセスがロックを奪取する方法であり、ロックを奪取した者は分析操作を実行し、失敗した IP をファイルに記録します。分析操作を実行するプロセスは 1 つだけであるため、通常のリクエストには影響しません。 同時に、ロックは失敗した場合にのみプリエンプトされ、通常の状況では基本的に Redis との対話は行われず、パフォーマンスの低下はありません。
私たちのヘルスチェックは一元化された Redis サービスに依存していますが、それがハングしたらどうなりますか? Redis サービス自体がダウンしていると判断された場合、rpc フレームワークはヘルス チェック サービスを自動的にシャットダウンし、redis と対話しなくなります。これは、少なくとも通常の RPC 機能には影響しません。
ヘルスチェックの実装に基づいて、フロー制御を実装できます。つまり、ほとんどまたはすべての IP が失敗したことが判明した場合、過剰なトラフィックによりバックエンド サービスが応答できず、リクエストが失敗したと推測できます。一般的な実装は、すべてのトラフィックを直接削除することですが、これは少し大雑把ですが、失敗した IP の割合が一定の値に低下するまで徐々にトラフィックを減らします。可能性を増減させるためにトラフィックを徐々に増加させてみてください。これは循環的なプロセス、つまり動的フロー制御であり、最終的には最適なフロー値が見つかります。関連する設定を通じてフロー制御の機能を紹介しましょう:
degrade_ip_fail_ratio = 1 ; 服务开始降级时失败IP比例 即失败的IP比例达到多少时开始降级,即开始减少流量 degrade_dec_step = 0.1 ; 每次限流增加多少 即每次减少多少比例的流量 degrade_stop_ip_ratio = 0.5; 在失败的IP已降到多少比例时开始停止减少流量,并尝试增加流量 degrade_stop_ttl_s = 10; 停止等待多长时间开始尝试增加流量 degrade_step_ttl_s = 10 流量增加或减少需要等待的时间。 每一次流量增加或减少后,下一步如何做是根据当时失败的IP比例来决定的,而且会保持当前流量值一段时间,而不是立即做决定。 degrade_add_step = 0.1 每次增加流量增加的比例值 degrade_return = false ; 降级时返回值 降级时我们不会再去访问后端服务,而是直接给调用方返回一个配置的值。
フロー制御の状態図は次のように説明されます:
流量を特定の比率で制御するにはどうすればよいですか? 乱数を取得し、それが一定の範囲内にあるかどうかを判断するなどのランダムな選択によって。 フローを最適な値に制限することで、ほとんどのリクエストはユーザーへの影響を最小限に抑えながら正常に動作します。同時に、フロー制御は、特定のモジュールのフロー制御率が 1 未満であることがわかります。関連するモジュールがシステム全体のボトルネックであることを示している場合、次のステップはハードウェア リソースを増やすか、プログラムのパフォーマンスを最適化することです。
関連する推奨事項:
RPC フレームワークの PHP リモート呼び出しとコードの詳細 (図)
以上がPHP の RPC フレームワークは、Redis に基づいたフロー制御システムを実装します。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。