Heim  >  Artikel  >  Backend-Entwicklung  >  Das RPC-Framework in PHP implementiert ein Flusskontrollsystem basierend auf Redis

Das RPC-Framework in PHP implementiert ein Flusskontrollsystem basierend auf Redis

小云云
小云云Original
2018-03-15 14:03:363116Durchsuche


Wir haben ein gewisses Maß an Microservice-Transformation am Projektmodul durchgeführt. Zuvor wurden alle Module in einem Projekt (einem großen Ordner) abgelegt, und das Gleiche galt für Online-Bereitstellung wie folgt Die Mängel liegen auf der Hand. Später haben wir es entsprechend den Geschäftsfunktionen in Untermodule aufgeteilt und dann über das RPC-Framework auf die Untermodule zugegriffen. Jedes Untermodul verfügt über einen eigenen unabhängigen Online-Maschinencluster, MySQL, Redis und andere Speicherressourcen Problem mit einem solchen Untermodul Es hat keine Auswirkungen auf andere Module und ist wartbarer und skalierbarer.

Aber in Wirklichkeit sind die Servicefähigkeiten jedes Untermoduls unterschiedlich, wie im Architekturdiagramm nach der Aufteilung nach Untermodul dargestellt. Nehmen Sie an, dass die QPS, die Modul A erreicht, 100 beträgt und A von B abhängt. Gleichzeitig beträgt jeder Anforderungs-QPS von Modul A zu Modul B ebenfalls 100, aber die maximale QPS-Fähigkeit, die Modul B bereitstellen kann, beträgt 50. Wenn es keine Verkehrsbeschränkung gibt, akkumuliert Modul B den Verkehr aufgrund der Überlastung. Dadurch wird das gesamte System nicht verfügbar. Das Steuerungssystem besteht darin, die beste Servicefähigkeit des Untermoduls zu finden, dh den Datenverkehr von Modul A zu Modul B auf 50 QPS zu begrenzen, wodurch sichergestellt wird, dass zumindest einige davon nicht verfügbar sind Anfragen können normal verarbeitet werden, ohne dass das gesamte System heruntergefahren wird, weil ein Unterdienst hängen bleibt.

Unser RPC-Framework ist ein PHP-implementiertes Framework, das hauptsächlich den HTTP-Protokollzugriff unterstützt. Für ein Front-End-A-Modul und für das Back-End-B-Modul muss das B-Modul zuerst als Dienst konfiguriert und dann entsprechend dem Dienstnamen referenziert und darauf zugegriffen werden. Die allgemeine Form der Dienstkonfiguration lautet wie folgt folgt:

[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字段传给后端

Damit auf ein Dienstmodul zugegriffen werden kann, wird es normalerweise als Cluster bereitgestellt. Wenn es einen internen DNS-Dienst gibt, müssen wir natürlich alle IPs des Maschinenclusters konfigurieren. Es kann auch mit dem Domänennamen des Clusters ausgestattet werden.

Zu den Grundfunktionen eines RPC-Frameworks gehören Lastausgleich, Gesundheitsprüfung, Downgrade und Strombegrenzung usw. Unsere Verkehrskontrolle dient der Downgrade- und Strombegrenzungsfunktion. Bevor wir sie im Detail vorstellen, wollen wir darüber sprechen Erstens ist die Implementierung des Lastausgleichs und der Gesundheitsprüfung die Grundlage für die Implementierung der Flusskontrolle.

Wir haben Zufalls- und Abfragealgorithmen für den Lastausgleich implementiert. Der Zufallsalgorithmus kann durch zufällige Auswahl einer unter allen IPs implementiert werden, was relativ einfach zu implementieren ist. Für den Abfragealgorithmus basieren wir auf Stand-Alone Die vorherige Auswahl lautet: Die IP-Seriennummer wird mithilfe der Apcu-Erweiterung im lokalen Speicher aufgezeichnet, um das Auffinden der nächsten zu verwendenden IP-Seriennummer zu erleichtern.

Die Maschine, auf die zugegriffen wird, fällt möglicherweise aus. Wir zeichnen die IP der fehlgeschlagenen Anforderung in Redis auf und analysieren das aufgezeichnete Fehlerprotokoll, um festzustellen, ob eine Maschinen-IP entfernt werden muss, d. h. die Maschine mit dieser IP gilt als ausgefallen . Der Dienst kann nicht normal bereitgestellt werden. Wir führen die spezifischen Funktionen der Gesundheitsprüfung über die entsprechenden Dienstkonfigurationselemente ein:

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

In unserer Code-Implementierung Bei der Service-IP-Konfiguration führen wir auch eine Liste der fehlgeschlagenen IPs, sodass wir bei der IP-Auswahl über den Algorithmus zunächst die fehlgeschlagenen IPs entfernen und die fehlgeschlagenen IPs in einer Datei aufzeichnen müssen. Gleichzeitig verwenden wir den Apcu-Speichercache Beschleunigen Sie den Zugriff, sodass alle unsere Vorgänge grundsätzlich auf dem Speicherzugriff basieren. Es treten keine Leistungsprobleme auf.

Wir zeichnen das Protokoll in Redis nur auf, wenn die Anfrage fehlschlägt. Wann werden wir die fehlgeschlagene IP herausfinden? Dies beinhaltet die Abfrage aller Fehlerprotokolle in der Redis-Liste und die Nummerierung ist ein komplexerer Vorgang . Unsere Implementierung ist eine Möglichkeit für mehrere PHP-Prozesse, die Sperre zu ergreifen. Wer auch immer sie beschlagnahmt, führt Analysevorgänge durch und zeichnet die fehlerhafte IP in einer Datei auf. Da nur ein Prozess den Analysevorgang ausführt, hat dies keine Auswirkungen auf normale Anforderungen. Gleichzeitig wird die Sperre nur dann aufgehoben, wenn sie fehlschlägt. Unter normalen Umständen findet grundsätzlich keine Interaktion mit Redis statt und es kommt zu keinem Leistungsverlust.

Unser Gesundheitscheck basiert auf einem zentralen Redis-Dienst. Was passiert, wenn er hängt? Wenn festgestellt wird, dass der Redis-Dienst selbst ausgefallen ist, fährt das RPC-Framework den Gesundheitsprüfungsdienst automatisch herunter und interagiert nicht mehr mit Redis. Dies hat zumindest keine Auswirkungen auf die normale RPC-Funktion.

Basierend auf der Implementierung der Gesundheitsprüfung können wir eine Flusskontrolle implementieren. Das heißt, wenn wir feststellen, dass die meisten oder alle IPs ausfallen, können wir daraus schließen, dass der Backend-Dienst aufgrund übermäßigen Datenverkehrs nicht antworten kann und die Anfrage fehlschlägt. Zu diesem Zeitpunkt sollten wir den Datenverkehr mit einer bestimmten Strategie begrenzen. Die allgemeine Implementierung besteht darin, den gesamten Datenverkehr direkt zu entfernen. Unsere Implementierung besteht darin, den Datenverkehr schrittweise zu reduzieren, bis der Anteil der ausgefallenen IPs auf einen bestimmten Wert sinkt Versuchen Sie dann, den Datenverkehr schrittweise zu erhöhen und zu verringern. Dies kann ein zyklischer Prozess sein, dh eine dynamische Flusssteuerung, und schließlich werden wir einen optimalen Flusswert finden. Lassen Sie uns die Funktion der Flusskontrolle durch entsprechende Konfiguration vorstellen:

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

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

Das Statusdiagramm der Flusskontrolle wird wie folgt beschrieben:
Das RPC-Framework in PHP implementiert ein Flusskontrollsystem basierend auf Redis

Wie kann man die Durchflussrate bei einem bestimmten Verhältnis steuern? Durch zufällige Auswahl, z. B. Erhalten einer Zufallszahl und Beurteilen, ob sie in einen bestimmten Bereich fällt. Durch die Begrenzung des Flusses auf einen optimalen Wert können die meisten Anfragen normal funktionieren und die geringsten Auswirkungen auf die Benutzer haben. Gleichzeitig wird festgestellt, dass das Flusskontrollverhältnis eines bestimmten Moduls unter 1 liegt. Da das entsprechende Modul einen systemweiten Engpass darstellt, sollte der nächste Schritt darin bestehen, die Hardwareressourcen zu erhöhen oder die Leistung unseres Programms zu optimieren.

Verwandte Empfehlungen:

Detaillierte Erläuterung von Beispielen des RPC-Frameworks

Detaillierte Erläuterung des Codes für PHP-Remote-Aufrufe und RPC-Framework (Bild )

Einfache Verwendung von PHPRPC

Das obige ist der detaillierte Inhalt vonDas RPC-Framework in PHP implementiert ein Flusskontrollsystem basierend auf Redis. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn