← 返回文章列表

Go-Kit 微服務框架

學習 Go-Kit 的分層方式與微服務元件。

go

相關程式碼的GitHub地址:GoKitAddSrv,不同資料夾代表不同章節,直接go run .可執行

寫得比較簡單,能跑就行,一些bug和規範問題見諒!

簡介

go-kit嚴格意義上並不算是一個完整的框架,更像是一個工具箱或者庫的集合,官方描述它為一組包和最佳實踐的集合。

go

它提供了構建微服務所有的標準元件,並且採用整潔架構和洋蔥結構。它不追求開發的速度,而是採用強制三層架構,嚴格分成業務邏輯層(Service)、作為介面卡的端點層(Endpoint)和進行協議處理的傳輸層(Transport),將業務邏輯和網路通訊完全解耦。

核心結構-三層模型

go

Transport

這是最外層的結構,負責處理具體的網路協議,通常是http和rpc,主要功能就是進行編解碼,將外部傳來的請求,比如Json解析成Endpoint能夠讀懂的golang結構體,然後呼叫Endpoint層,再將從Endpoint層獲取的結果進行編碼,傳輸傳送給客戶端。

Endpoint

這是連線業務和網路的中間一層,它負責將Service層中的各種方法強制封裝成一個統一的標準函式簽名,然後交給Transport層呼叫

// Endpoint定义
type Endpoint func(ctx context.Context, request interface{}) (response interface{}, err error)

在這一層,所有的呼叫都會被統一抽象成同一種形式,通常在這一層進行中介軟體的掛載。實現一套中介軟體能應用於所有的介面。

Service

業務邏輯層Service只考慮具體業務邏輯的實現,定義並實現介面即可,不用考慮協議和網路服務。

Demo-實現一個簡單加法器

HTTP

說明

  1. 在Service層定義介面,包含兩個方法

    1. Add實現int型別的的加法

    2. Concat實現string型別的加法

    3. 基本流程就是定義介面,實現介面

  2. 在Endpoint層,定義請求和響應資料的結構體,將Service層的方法進行封裝

    1. 接本流程就是定義結構體,封裝方法
  3. 在Transport層,進行具體協議處理和響應

    1. 實現編解碼

    2. 實現Handler

    3. 定義路由和埠

    4. ……

測試

使用Postman進行測試

go

go

RPC

這裡使用gRpc

說明

  1. 實現proto檔案

    1. 定義proto資料夾

    2. 在資料夾中編寫proto檔案,定義service和message

    3. 執行protoc指令,生成golang檔案

      protoc -I=proto --go_out=proto --go_opt=paths=source_relative --go-grpc_out=proto --go-grpc_opt=paths=source_relative proto/addsrv.proto
  2. 在Service層定義介面,包含兩個方法

    1. Add實現int型別的的加法

    2. Concat實現string型別的加法

    3. 基本流程就是定義介面,實現介面

  3. 在Endpoint層,定義請求和響應資料的結構體,將Service層的方法進行封裝

    1. 接本流程就是定義結構體,封裝方法
  4. 在Transport層,進行具體協議處理和響應

    1. 實現rpc編解碼

    2. 實現Handler

    3. 實現protobuf介面

    4. ……

測試

使用Postman進行測試

go

go

專案結構拆分

根據go-kit設計好的三層結構,我們對原本單獨的三個資料夾進行分層實現,下面是具體的目錄結構

go

中介軟體

日誌

  1. 全域性建立日誌

  2. 在介面實現的時候傳入日誌

  3. 定義日誌介面,在介面中加入應用介面+日誌,然後再實現方法

// go-kit官方设计
type logMiddleware struct {
    logger log.Logger
    next   AddService
}

在專案中加入日誌中介軟體,簡單實現示意

go

限流

加入限流中介軟體,1秒鐘只能請求一次

在實際業務場景中可以針對單個使用者進行更加細粒度的限制

go

在專案中加入限流中介軟體,簡單實現示意

go

指標採集

使用metrics包來記錄關於服務執行時行為的統計資訊,比如計算已處理作業的數量、記錄請求完成後的持續時間以及跟蹤正在執行的操作的數量等等。

在專案中加入指標採集中介軟體,簡單實現示意

go

go

服務呼叫

透過構建結構體,加入當前服務和被呼叫服務(被設定為endpoint.Endpoint型別)實現呼叫

go

簡單實現示意

go

服務發現和負載均衡

關於 Consul 的安裝和使用可以見:Consul。

go-kit提供服務發現和負載均衡的相應機制

  • Go kit 提供了工廠函式Factory, 它是一個將例項字串(例如host:port)轉換為特定端點的函式。提供多個端點的例項需要多個工廠函式。工廠函式還返回一個當例項消失並需要清理時呼叫的io.Closer。

  • Go kit 提供了基本的負載均衡器,也可以自己實現。

  • 重試策略包裝負載均衡器,並返回可用的端點。重試策略將重試失敗的請求,直到達到最大嘗試或超時為止。

// 工厂函数
type Factory func(instance string) (endpoint.Endpoint, io.Closer, error)

//  负载均衡
import "github.com/go-kit/kit/sd/lb"
balancer := lb.NewRoundRobin(endpointer)

// 重试
func Retry(max int, timeout time.Duration, lb Balancer) endpoint.Endpoint
import "github.com/go-kit/kit/sd/lb"
retry := lb.Retry(3, 500*time.Millisecond, balancer)

下面是簡單實現

開了兩個trim_service分別在兩個終端,呼叫的時候會自動輪詢

go

go

參考資料

Go-kit

Gemini老師

Go kit教程01——基礎示例

Go kit教程02——gRPC

Go kit教程03——程式碼分層

Go kit教程04——中介軟體和日誌

Go kit教程05——呼叫其他服務

Go kit教程06——服務發現和負載均衡

關於這篇文章的日期

舊日期 2025-01-16 與文章發布記錄不符,現按舊站可確認的首次發布日 2026-01-18 整理。實際創作日期尚無法確認。

原始日期: 2025-01-16 21:15:06 +0800