Le framework RPC en PHP implémente un système de contrôle de flux basé sur Redis

小云云
Libérer: 2023-03-21 14:14:01
original
3127 Les gens l'ont consulté


Nous avons effectué un certain degré de transformation des microservices sur le module projet. Auparavant, tous les modules étaient placés dans un seul projet (un grand dossier), et il en était de même pour. déploiement en ligne, comme celui-ci Les lacunes sont évidentes. Plus tard, nous l'avons divisé en sous-modules en fonction des fonctions métier, puis avons accédé aux sous-modules via le framework RPC. Chaque sous-module possède son propre cluster de machines en ligne indépendant, mysql, redis et d'autres ressources de stockage. problème avec un tel sous-module Cela n'affectera pas les autres modules, et il est plus maintenable et évolutif.

Mais en réalité, les capacités de service de chaque sous-module sont différentes, comme le montre le schéma d'architecture après division par sous-modules. Supposons que le QPS atteignant le module A soit de 100 et que A dépend de B. Dans le même temps, chaque requête QPS du module A au module B est également de 100, mais la capacité QPS maximale que le module B peut fournir est de 50. S'il n'y a pas de limite de trafic, le module B accumulera du trafic en raison du dépassement de la charge et l'ensemble du système sera indisponible.Notre trafic dynamique Le système de contrôle consiste à trouver la meilleure capacité de service du sous-module, c'est-à-dire à limiter le trafic du module A au module B à 50 QPS, ce qui garantira qu'au moins une partie des les requêtes peuvent être traitées normalement sans ralentir l'ensemble du système car un sous-service raccroche.

Notre framework RPC est un framework implémenté en PHP qui prend principalement en charge l'accès au protocole http. Pour un module front-end A, pour le module back-end B dont il dépend, le module B doit d'abord être configuré en tant que service, puis référencé et accessible en fonction du nom du service. La forme générale de configuration du service est la suivante. suit :

[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字段传给后端
Copier après la connexion

Pour qu'un module de service soit accessible, il est généralement déployé en tant que cluster. Nous devons configurer toutes les IP du cluster de machines. Bien sûr, s'il existe un service DNS interne, celui-ci. peut également être équipé du nom de domaine du cluster.

Pour un framework RPC, les fonctions de base incluent l'équilibrage de charge, le contrôle de santé, le déclassement et la limitation de courant, etc. Notre contrôle du trafic est destiné à la fonction de déclassement et de limitation de courant. Avant de l'introduire en détail, parlons-en. Tout d'abord, la manière dont l'équilibrage de charge et la vérification de l'état sont mis en œuvre constitue la base de la mise en œuvre du contrôle de flux.

Nous avons implémenté des algorithmes aléatoires et d'interrogation pour l'équilibrage de charge. L'algorithme aléatoire peut être implémenté en sélectionnant aléatoirement une parmi toutes les IP, ce qui est relativement facile à mettre en œuvre. Pour l'algorithme d'interrogation, nous sommes basés sur des algorithmes autonomes. interrogation, et la sélection précédente est Le numéro de série IP est enregistré dans la mémoire locale à l'aide de l'extension apcu pour faciliter la recherche du prochain numéro de série IP à utiliser.

La machine accédée peut échouer. Nous enregistrons l'adresse IP de la demande ayant échoué dans Redis et analysons le journal des échecs enregistré pour déterminer si une adresse IP de machine doit être supprimée, c'est-à-dire que la machine avec cette adresse IP est considérée comme morte. . , le service ne peut pas être fourni normalement. Il s'agit de la fonction de contrôle de santé. Nous introduisons les fonctions spécifiques du contrôle de santé via les éléments de configuration du service associés :

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记录失败日志,容量有限,我们要设定一个记录的最大日志数量,多余的日志自动删除。
Copier après la connexion

Dans notre implémentation de code, en plus de la normale. Configuration IP du service, nous maintenons également une liste des IP défaillantes, de sorte que lors de la sélection de l'IP via l'algorithme, nous devons d'abord supprimer les IP défaillantes et enregistrer les IP défaillantes dans un fichier. En même temps, nous utilisons le cache mémoire apcu pour. accélérer l'accès, afin que toutes nos opérations soient essentiellement basées sur l'accès à la mémoire, il n'y aura aucun problème de performances.

Nous n'enregistrerons la connexion dans Redis que lorsque la requête échoue. Quand connaîtrons-nous l'adresse IP défaillante ? Cela implique d'interroger tous les journaux d'échecs dans la liste Redis et de compter les échecs. . Notre implémentation est un moyen pour plusieurs processus PHP de saisir le verrou, celui qui le saisit effectuera des opérations d'analyse et enregistrera l'adresse IP défaillante dans un fichier. Étant donné qu’un seul processus effectuera l’opération d’analyse, il n’y aura aucun impact sur les requêtes normales. Dans le même temps, le verrou ne sera préempté qu'en cas d'échec. Dans des circonstances normales, il n'y aura pratiquement aucune interaction avec Redis et il n'y aura aucune perte de performances.

Notre bilan de santé repose sur un service Redis centralisé. Et s'il se bloque ? S'il est déterminé que le service Redis lui-même est en panne, le framework RPC arrêtera automatiquement le service de vérification de l'état et n'interagira plus avec Redis. Cela n'affectera au moins pas la fonction RPC normale.

Sur la base de la mise en œuvre du contrôle de santé, nous pouvons mettre en œuvre un contrôle de flux, c'est-à-dire que lorsque nous constatons que la plupart ou la totalité des adresses IP échouent, nous pouvons en déduire que le service backend ne peut pas répondre en raison d'un trafic excessif et que la requête échoue. À ce stade, nous devrions limiter le trafic avec une certaine stratégie. La mise en œuvre générale consiste à supprimer directement tout le trafic, ce qui est un peu grossier. Notre mise en œuvre consiste à réduire progressivement le trafic jusqu'à ce que la proportion d'IP défaillantes chute à une certaine valeur. , puis essayez d'augmenter progressivement le trafic. L'augmentation et la diminution peuvent être un processus cyclique, c'est-à-dire un contrôle dynamique du flux, et nous finirons par trouver une valeur de flux optimale. Introduisons la fonction de contrôle de flux via une configuration pertinente :

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 ; 降级时返回值

降级时我们不会再去访问后端服务,而是直接给调用方返回一个配置的值。
Copier après la connexion

Le diagramme d'état du contrôle de flux est décrit comme suit :
Le framework RPC en PHP implémente un système de contrôle de flux basé sur Redis

Comment contrôler le débit à un certain rapport ? Par sélection aléatoire, par exemple obtenir un nombre aléatoire et juger s'il se situe dans une certaine plage. En limitant le débit à une valeur optimale, la plupart des demandes peuvent fonctionner normalement avec le moins d'impact sur les utilisateurs. En même temps, le contrôle de débit coopère avec la surveillance et l'alarme. Il s'avère que le rapport de contrôle de débit d'un certain module est inférieur à 1. indiquant que le module concerné constitue un goulot d'étranglement à l'échelle du système, la prochaine étape devrait être d'augmenter les ressources matérielles ou d'optimiser les performances de notre programme.

Recommandations associées :

Explication détaillée des exemples de framework RPC

Explication détaillée du code pour les appels à distance PHP et le framework RPC (image )

Utilisation simple de PHPRPC

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!