? Warum benötigen Sie eine Timeout-Kontrolle?
Ein häufiges Problem in vielen kaskadierenden Fehlerszenarien besteht darin, dass der Server viele Ressourcen verbraucht, um Anforderungen zu verarbeiten, die die Frist des Clients bereits überschritten haben. Das Ergebnis ist, dass der Server viele Ressourcen verbraucht, ohne wertvolle Arbeit zu leisten Die Antwort ist abgelaufen. Die Anfrage ergibt keinen Sinn. Man kann sagen, dass die Timeout-Kontrolle eine wichtige Verteidigungslinie ist, um die Stabilität des Dienstes zu gewährleisten. Eine gute Timeout-Kontrollstrategie kann Anfragen mit hoher Latenz so schnell wie möglich löschen und Ressourcen so schnell wie möglich freigeben die Anhäufung von Anfragen.
Zeitüberschreitung bei der Zustellung zwischen Diensten
Wenn eine Anfrage mehrere Phasen umfasst, z. B. eine Reihe von RPC-Aufrufen, sollte unser Dienst die Frist vor Beginn jeder Phase überprüfen, um verschwendete Arbeit zu vermeiden, d. h. prüfen, ob dies der Fall ist Es verbleibt noch genügend Zeit, um die Anfrage zu bearbeiten. Ein häufiger Implementierungsfehler besteht darin, in jedem RPC-Dienst ein festes Zeitlimit festzulegen. Das Zeitlimit kann auf der obersten Ebene des Dienstaufrufs festgelegt und der gesamte RPC durch die erste Anforderung ausgelöst werden Baum wird die gleiche absolute Frist festlegen. Stellen Sie das Zeitlimit beispielsweise auf 3 Sekunden ein. Dienst A fordert Dienst B an. Dienst B benötigt dann 1 Sekunde, um Dienst C anzufordern. Zu diesem Zeitpunkt beträgt die Zeitüberschreitung weiterhin 2 Sekunden Die Ausführungszeit beträgt 1 Sekunde. Wenn Dienst C dann Dienst D anfordert, dauert die Ausführung von Dienst D 500 ms usw. Im Idealfall wird in der gesamten Aufrufkette derselbe Timeout-Zustellungsmechanismus verwendet.
Wenn der Timeout-Zustellungsmechanismus nicht verwendet wird, tritt die folgende Situation auf:
Service A sendet eine Anfrage an Service B und das eingestellte Timeout beträgt 3 Sekunden.
Service B benötigt 2 Sekunden, um die Anfrage zu verarbeiten wird weiterhin angefordert. Dienst C
- Wenn die Timeout-Zustellung verwendet wird, sollte die Timeout-Zeit von Dienst C 1 Sekunde betragen, aber die Timeout-Zustellung wird hier nicht verwendet, daher ist die Timeout-Zeit in der Konfiguration fest auf 3 Sekunden festgelegt.
- Die fortgesetzte Ausführung von Dienst C Tatsächlich dauert dies 2 Sekunden. Wenn das von der obersten Ebene festgelegte Timeout abgelaufen ist, ist die folgende Anfrage bedeutungslos
- Fahren Sie mit der Anforderung von Service D fort
- Wenn Service B den Timeout-Zustellungsmechanismus übernimmt, sollte die Anfrage sofort abgebrochen werden Service C, da die Frist erreicht ist. Möglicherweise hat der Kunde einen Fehler gemeldet. Wenn wir die Timeout-Zustellung festlegen, verkürzen wir die Zustellungsfrist normalerweise ein wenig, z. B. 100 Millisekunden, um die Netzwerkübertragungszeit und die Verarbeitungszeit nach Erhalt der Antwort durch den Client zu berücksichtigen.
-
In-Prozess-Timeout-Übertragung
Es ist nicht nur eine Timeout-Übertragung zwischen Diensten erforderlich, sondern auch eine Timeout-Übertragung innerhalb des Prozesses. Beispielsweise werden MySQL, Redis und Dienst B seriell in einem Prozess aufgerufen und die Gesamtanforderung Die Zeit ist auf 3 Sekunden eingestellt und fordert dann erneut Redis an. Die Redis-Ausführung dauert 500 ms und fordert dann Dienst B an. Das Zeitlimit beträgt 1,5 Sekunden, da jede unserer Middleware oder Dienste einen festen Wert in der Konfiguration festlegt Für die Timeout-Zeit müssen wir den Mindestwert der verbleibenden Zeit und die eingestellte Zeit nehmen.
Kontext implementiert Timeout-Bereitstellung
Das Prinzip des Kontexts ist sehr einfach, aber seine Funktion ist sehr leistungsstark. Die Standardbibliothek von Go hat auch Unterstützung für Kontext implementiert, und verschiedene Open-Source-Frameworks haben auch Unterstützung für Kontext implementiert. Der Kontext ist zum Standard geworden, und die Timeout-Bereitstellung hängt auch vom Kontext ab. Normalerweise legen wir den Anfangskontext oben im Dienst für die Timeout-Kontrollübertragung fest, zum Beispiel setzen wir das Timeout auf 3s
ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)defer cancel()
Nach dem Login kopieren
Wenn der Kontext übertragen wird, wie zum Beispiel das Anfordern von Redis in der obigen Abbildung, erhalten Sie die verbleibende Zeit Gehen Sie wie folgt vor: Vergleichen Sie die von Redis festgelegte Zeitüberschreitung und wählen Sie eine kleinere Zeit. Die Zeitüberschreitungsübertragung zwischen Diensten bezieht sich hauptsächlich auf die Zeitüberschreitungsübertragung beim Aufruf von RPC. Für gRPC selbst ist keine zusätzliche Verarbeitung erforderlich Timeout-Übertragung. Prinzip Ähnlich wie oben wird es über Metadaten weitergeleitet und schließlich in den Wert von grpc-timeout umgewandelt, wie im folgenden Code gezeigt
dl, ok := ctx.Deadline()
Nach dem Login kopieren
Die Timeout-Übertragung ist eine wichtige Verteidigungslinie, um die Dienststabilität sicherzustellen Das Prinzip und die Implementierung sind sehr einfach. Ist die Timeout-Lieferung im Framework implementiert? Wenn nicht, handeln Sie schnell.
Timeout-Zustellung in Go-Zero
Go-Zero kann die Dienste api Gateway
und rpc
über den Timeout
in der Konfigurationsdatei konfigurieren Timeout und wird automatisch zwischen Diensten weitergegeben. Timeout
配置 api gateway
和 rpc
服务的超时,并且会在服务间自动传递。
之前的 一文搞懂如何实现 Go 超时控制 里面有讲解超时控制如何使用。
参考
《SRE:Google运维解密》
项目地址
github.com/zeromicro/go-zero
欢迎使用 go-zero
Der vorherige Artikel versteht, wie man die Go-Timeout-Kontrolle implementiert
, in dem erklärt wird, wie man die Timeout-Kontrolle verwendet.
"SRE: Decryption of Google Operations and Maintenance"🎜🎜Projektadresse🎜🎜github.com/zeromicro/go-zero🎜🎜Willkommen bei der Verwendung von
go-zero
Und 🎜star/fork🎜 unterstützt uns! 🎜🎜Empfohlen: „🎜🎜Golang-Tutorial🎜🎜“🎜
Das obige ist der detaillierte Inhalt vonEin Artikel zum Verständnis der Timeout-Bereitstellung von Microservices. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!