最近では、特にマイクロサービス環境で作業している場合、アプリケーションが他のアプリケーションに依存することが非常に一般的です。アプリケーションがエラーを報告し始めることはよくあります。調査すると、パートナー チームまたはサプライヤーの一部の API がダウンしていることに気づきます。
アプリケーションの復元力を高めるための良い方法は、非推奨状態にあるアプリケーションとの通信を遮断することです。他の分野を観察しながら、電気工学からサーキットブレーカーの概念を吸収します。その中には機器、つまり回路ブレーカーが設置されており、障害が発生すると自動的にオフになります。これは私たちの家庭では非常に一般的で、電気網が不安定になり始めると自動的にオフになる回路ブレーカーが設置されています。
コンピューティングでは、中間状態も定義するため、サーキット ブレーカーはもう少し複雑です。以下の図は、サーキット ブレーカーがどのように機能するかをよりよく説明しています:
最後に、州は次のとおりです:
かなりクールですね?しかし、この概念をよりよく例示するために、実際にそれを行ってみてはどうでしょうか?
まず、サービス A を構築しましょう。サービス A はリクエストの受信を担当します。つまり、アプリケーションが依存するサービス、サプライヤーのサービスなどになります。簡単にするために、2 つのエンドポイント、常に 200 を返す /success と常に 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 コミュニティには、このパターンを実装する 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 つに焦点を当てます。
その後、ブレーカーを初期化してリクエストを行うことができます。
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 がこのトピックに関する素晴らしい投稿を公開しています!
この投稿についてどう思うかコメント欄で教えてください。質問があります: これまでにサーキットブレーカーを使用したことがありますか?ああ、私の個人ブログでも私を見つけることができます!
以上がGo アプリケーションのサーキット ブレーカーの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。