」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > Go 應用程式中的斷路器

Go 應用程式中的斷路器

發佈於2024-09-12
瀏覽:354

如今,我們的應用程式依賴其他應用程式是很常見的,特別是當我們在微服務環境中工作時。我們的應用程式開始報告錯誤是很常見的,在調查時,我們注意到合作夥伴團隊或供應商的某些 API 已關閉。

提高應用程式彈性的一個好做法是切斷與那些處於棄用狀態的應用程式的通訊。觀察其他領域,我們吸收了電機工程中斷路器的概念。其中放置了一個設備或斷路器,如果發生故障,它會自動關閉。這在我們的家裡很常見,如果電網開始變得不穩定,斷路器會自行關閉。

在計算中,我們的斷路器稍微複雜一些,因為我們也定義了中間狀態。下圖更好地解釋了斷路器的工作原理:

Circuit Breaker em aplicações Go

最後,狀態是:

  • open:應用程式之間沒有通訊。達到此狀態後,計時器開始為重置服務留出時間。在計時器結束時,我們過渡到半開。
  • 關閉:應用程式之間存在通訊。對於每個失敗的請求,都會更新計數器。如果達到故障極限,我們會將電路切換為開路。
  • half-open:恢復狀態,直到通訊完全暢通。其中,成功計數器會根據每個請求進行更新。如果達到理想的成功次數,我們會將電路移至閉合狀態。如果請求失敗,我們將轉換回開放狀態。

很酷,對吧?但為了更好地舉例說明這個概念,我們在實踐中該如何做呢?

首先,我們來建構我們的服務A。它將負責接收請求,也就是說,它將是我們的應用程式所依賴的服務,供應商的服務等。為了方便起見,我們將公開兩個端點,一個始終返回 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 社群已經有了實現該模式的 gobreaker 函式庫!首先,我們定義斷路器的屬性:

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
}

雖然該庫允許我們定制更多的東西,但我們將重點放在三個:

  • 超時:電路保持開路狀態的時間。在我們的例子中,時間設定為 5 秒。
  • MaxRequests:關閉前成功請求的數量。在我們的範例中,我們將其定義為 2 個請求。
  • ReadyToTrip:定義從關閉過渡到開啟的條件。為了讓事情變得更容易,我們假設一次失敗就夠了。

然後我們可以初始化斷路器並發出請求:

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!

我們可以注意到 gobreaker 作為函數的包裝器。如果函數傳回錯誤,則會增加錯誤數量,如果沒有,則會增加成功數量。那麼讓我們定義這個函數:

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 發表了一篇關於該主題的精彩文章!

請在評論中告訴我您對這篇文章的看法,這裡有一個問題:您以前使用過斷路器嗎?哦,你也可以在我的個人部落格找到我!

版本聲明 本文轉載於:https://dev.to/mfbmina/circuit-breaker-em-aplicacoes-go-4hnn?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 如何使用 JSTL 迭代 HashMap 中的 ArrayList?
    如何使用 JSTL 迭代 HashMap 中的 ArrayList?
    使用JSTL 迭代HashMap 中的ArrayList在Web 開發中,JSTL(JavaServer Pages 標準標記庫)提供了一組標記來簡化JSP 中的常見任務( Java 伺服器頁面)。其中一項任務是迭代資料結構。 要迭代 HashMap 及其中包含的 ArrayList,可以使用 JS...
    程式設計 發佈於2024-11-05
  • Encore.ts — 比 ElysiaJS 和 Hono 更快
    Encore.ts — 比 ElysiaJS 和 Hono 更快
    几个月前,我们发布了 Encore.ts — TypeScript 的开源后端框架。 由于已经有很多框架,我们想分享我们做出的一些不常见的设计决策以及它们如何带来卓越的性能数据。 性能基准 我们之前发布的基准测试显示 Encore.ts 比 Express 快 9 倍,比 Fasti...
    程式設計 發佈於2024-11-05
  • 為什麼使用 + 對字串文字進行字串連接失敗?
    為什麼使用 + 對字串文字進行字串連接失敗?
    連接字串文字與字串在 C 中,運算子可用於連接字串和字串文字。但是,此功能存在限制,可能會導致混亂。 在問題中,作者嘗試連接字串文字「Hello」、「,world」和「!」以兩種不同的方式。第一個例子:const string hello = "Hello"; const str...
    程式設計 發佈於2024-11-05
  • React 重新渲染:最佳效能的最佳實踐
    React 重新渲染:最佳效能的最佳實踐
    React高效率的渲染機制是其受歡迎的關鍵原因之一。然而,隨著應用程式複雜性的增加,管理元件重新渲染對於最佳化效能變得至關重要。讓我們探索優化 React 渲染行為並避免不必要的重新渲染的最佳實踐。 1. 使用 React.memo() 作為函數式元件 React.memo() 是...
    程式設計 發佈於2024-11-05
  • 如何實作條件列建立:探索 Pandas DataFrame 中的 If-Elif-Else?
    如何實作條件列建立:探索 Pandas DataFrame 中的 If-Elif-Else?
    Creating a Conditional Column: If-Elif-Else in Pandas給定的問題要求將新列新增至DataFrame 中基於一系列條件標準。挑戰在於在實現這些條件的同時保持程式碼效率和可讀性。 使用函數應用程式的解決方案一種方法涉及創建一個將每一行映射到所需結果的函...
    程式設計 發佈於2024-11-05
  • 介紹邱!
    介紹邱!
    我很高興地宣布發布 Qiu – 一個嚴肅的 SQL 查詢運行器,旨在讓原始 SQL 再次變得有趣。老實說,ORM 有其用武之地,但當您只想編寫簡單的 SQL 時,它們可能會有點不知所措。我一直很喜歡寫原始 SQL 查詢,但我意識到我需要練習——大量的練習。這就是Qiu發揮作用的地方。 有了 Qiu...
    程式設計 發佈於2024-11-05
  • 為什麼 CSS 中的 Margin-Top 百分比是根據容器寬度計算的?
    為什麼 CSS 中的 Margin-Top 百分比是根據容器寬度計算的?
    CSS 中的 margin-top 百分比計算CSS 中的 margin-top 百分比計算當對元素應用 margin-top 百分比時,必須了解計算方式執行。與普遍的看法相反,邊距頂部百分比是根據包含塊的寬度而不是其高度來確定的。 W3C 規範解釋:W3C 規範解釋:根據W3C 規範,“百分比是根...
    程式設計 發佈於2024-11-05
  • 如何解決 CSS 轉換期間 Webkit 文字渲染不一致的問題?
    如何解決 CSS 轉換期間 Webkit 文字渲染不一致的問題?
    解決CSS 轉換期間的Webkit 文本渲染不一致在CSS 轉換期間,特別是縮放元素時,Webkit 中可能會出現文本渲染不一致的情況瀏覽器。這個問題源自於瀏覽器嘗試優化渲染效能。 一種解決方案是透過添加以下屬性來強制對過渡元素的父元素進行硬體加速:-webkit-transform: transl...
    程式設計 發佈於2024-11-05
  • 使用 Reactables 簡化 RxJS
    使用 Reactables 簡化 RxJS
    介紹 RxJS 是一個功能強大的庫,但眾所周知,它的學習曲線很陡峭。 這個函式庫龐大的 API 介面,再加上向反應式程式設計的典範轉移,可能會讓新手不知所措。 我創建了 Reactables API 來簡化 RxJS 的使用並簡化開發人員對反應式程式設計的介紹。 ...
    程式設計 發佈於2024-11-05
  • 如何在 Pandas 中找到多列的最大值?
    如何在 Pandas 中找到多列的最大值?
    找出 Pandas 中多列的最大值要確定 pandas DataFrame 中多列的最大值,可以採用多種方法。以下是實現此目的的方法:對指定列使用max() 函數此方法涉及明確選擇所需的列並應用max() 函數: df[["A", "B"]] df[[&quo...
    程式設計 發佈於2024-11-05
  • CI/CD 入門:自動化第一個管道的初學者指南(使用 Jenkins)
    CI/CD 入門:自動化第一個管道的初學者指南(使用 Jenkins)
    目錄 介紹 什麼是 CI/CD? 持續整合(CI) 持續交付(CD) 持續部署 CI/CD 的好處 更快的上市時間 提高程式碼品質 高效率協作 提高自動化程度和一致性 如何建立您的第一個 CI/CD 管道 第 1 步:設定版本控制 (GitHub) 步驟 2: 選擇 CI/CD ...
    程式設計 發佈於2024-11-05
  • TypeScript 如何讓 JavaScript 在大型專案中更加可靠。
    TypeScript 如何讓 JavaScript 在大型專案中更加可靠。
    介绍 JavaScript 广泛应用于 Web 开发,现在也被应用于不同行业的大型项目中。然而,随着这些项目的增长,管理 JavaScript 代码变得更加困难。数据类型不匹配、运行时意外错误以及代码不清晰等问题可能会导致查找和修复错误变得困难。 这就是TypeScript介入的地...
    程式設計 發佈於2024-11-05
  • 如何使用PHP的password_verify函數安全地驗證使用者密碼?
    如何使用PHP的password_verify函數安全地驗證使用者密碼?
    使用 PHP 解密加密密碼許多應用程式使用密碼雜湊等加密演算法安全地儲存使用者密碼。然而,在驗證登入嘗試時,將輸入密碼與加密的儲存版本進行比較非常重要。 加密問題password_hash 使用 Bcrypt,一元加密演算法方式雜湊演算法,表示加密的密碼無法逆轉或解密。這是一項安全功能,可確保即使資...
    程式設計 發佈於2024-11-05
  • 學習 Vue 部分 建立天氣應用程式
    學習 Vue 部分 建立天氣應用程式
    深入研究 Vue.js 就像在 DIY 工具包中發現了一個新的最喜歡的工具——直觀、靈活,而且功能強大得驚人。我接觸 Vue 的第一個副業專案是一個天氣應用程序,它教會了我很多關於框架功能以及一般 Web 開發的知識。這是我到目前為止所學到的。 1. Vue 入門:簡單與強大 Vu...
    程式設計 發佈於2024-11-05
  • NFT 預覽卡組件
    NFT 預覽卡組件
    ?剛剛完成了我的最新專案:使用 HTML 和 CSS 的「NFT 預覽卡元件」! ?查看並探索 GitHub 上的程式碼。歡迎反饋! ? GitHub:[https://github.com/khanimran17/NFT-preview-card-component] ?現場示範:[https:...
    程式設計 發佈於2024-11-05

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3