Go アプリのサーキット ブレーカー
今日、特にマイクロサービス環境で動作する場合、アプリケーションにいくつかの依存関係があることが一般的です。アプリがエラーを報告し、1 つの依存関係がダウンしていることが判明することは珍しくありません。
回復力を向上させるための良い習慣の 1 つは、正常に動作していないアプリとの通信をシャットダウンすることです。他の分野に目を向けると、故障が発生するとスイッチがオフになる回路ブレーカーの概念を電気工学から学びました。ブラジルでは、電力網が不安定になると自動的に停止するスイッチがすべての家にあります。
コンピューターサイエンスでは、サーキットブレーカーは中間状態も持つため、もう少し複雑です。以下の図は、その仕組みを詳しく説明しています:
簡単に言うと、考えられる状態は次のとおりです:
- open: アプリ間の通信はありません。この状態に達すると、タイマーが開始され、依存関係が再確立されるようになります。タイマーが終了すると半開状態に移行します。
- クローズ済み: アプリ間で通信が行われています。リクエストが失敗して完了するたびに、カウンターが更新されます。障害しきい値に達すると、回路がオープンに移行します。
- 半開き:通常通りに仕事ができるようになるまでの治癒状態です。実行中に成功のしきい値に達すると、クローズに移行します。リクエストが失敗し続ける場合は、オープンに戻ります。
かなりクールですね?コンセプトをよりよく説明するには、コンセプトを作成してみてはいかがでしょうか?
まず、サービス A を構築しましょう。サービス A はすべてのリクエストを受信する責任を負います。つまり、メイン アプリが依存するサービスになります。簡略化するために、2 つのエンドポイントを公開します。1 つは常に 200 で応答する /success で、もう 1 つは常に 500 で応答する /failure です。
package main import ( "fmt" "log" "net/http" ) func main() { http.HandleFunc("/success", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) }) http.HandleFunc("/failure", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusInternalServerError) }) fmt.Println("Server is running at http://localhost:8080") log.Fatal(http.ListenAndServe(":8080", nil)) }
サービス B はサービス A を呼び出す責任を負い、サーキット ブレーカーを構築します。 Go コミュニティには、パターンを実装した lib gobreak がすでにあります。まず最初に、ブレーカーのプロパティを定義します。
var st gobreaker.Settings st.Name = "Circuit Breaker PoC" st.Timeout = time.Second * 5 st.MaxRequests = 2 st.ReadyToTrip = func(counts gobreaker.Counts) bool { return counts.ConsecutiveFailures >= 1 }
このライブラリではさらに多くのプロパティをカスタマイズできますが、ここでは次の 3 つのみに焦点を当てます。
- タイムアウト: オープン状態になる時間。この例では、5 秒を選択します。
- MaxRequests: クローズされるまでに成功したリクエストの数。この例では、2 つのリクエストを決定しました。
- ReadyToTrip: クローズからオープンに移行する条件を定義します。単純化すると、失敗は 1 回で十分です。
ここで、ブレーカーを初期化してリクエストを送信します。
cb := gobreaker.NewCircuitBreaker[int](st) url := "http://localhost:8080/success" cb.Execute(func() (int, error) { return Get(url) }) fmt.Println("Circuit Breaker state:", cb.State()) // closed! url = "http://localhost:8080/failure" cb.Execute(func() (int, error) { return Get(url) }) fmt.Println("Circuit Breaker state:", cb.State()) // open! time.Sleep(time.Second * 6) url = "http://localhost:8080/success" cb.Execute(func() (int, error) { return Get(url) }) fmt.Println("Circuit Breaker state:", cb.State()) // half-open! url = "http://localhost:8080/success" cb.Execute(func() (int, error) { return Get(url) }) fmt.Println("Circuit Breaker state:", cb.State()) // closed!
gobreak が関数のラッパーのように動作することがわかります。関数がエラーを返した場合は失敗カウンターが増加し、そうでない場合は成功カウンターが増加します。その関数を定義しましょう:
func Get(url string) (int, error) { r, _ := http.Get(url) if r.StatusCode != http.StatusOK { return r.StatusCode, fmt.Errorf("failed to get %s", url) } return r.StatusCode, nil }
これで、サーキットブレーカーを備えた Go アプリを作成できるようになりました。このパターンを使用すると、依存関係による障害に対するアプリの耐性が高まり、アプリの復元力を高めることができます。また、このライブラリを使用すると複雑さのほとんどが解消され、日常のアプリにこのパターンを採用しやすくなりました。この概念実証のコードを確認したい場合は、ここで確認してください。
他の回復力パターンについてまだ興味がある場合は、Elton Minetto がそれに関する素晴らしいブログ投稿を公開しています!
この記事や他の投稿は私の個人ブログでもご覧いただけます。このブログ投稿についてのご意見と 1 つの質問をコメント欄でお聞かせください。回路ブレーカーを使用したことがありますか?
以上がGo アプリのサーキット ブレーカーの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











Go Language Packのインポート:アンダースコアとアンダースコアなしの違いは何ですか?

MySQLクエリ結果リストをGO言語のカスタム構造スライスに変換する方法は?

GOのジェネリックのカスタムタイプ制約を定義するにはどうすればよいですか?

GOでテスト用のモックオブジェクトとスタブを書くにはどうすればよいですか?

トレースツールを使用して、GOアプリケーションの実行フローを理解するにはどうすればよいですか?
