
相關程式碼的GitHub地址:GoKitAddSrv,不同資料夾代表不同章節,直接go run .可執行
寫得比較簡單,能跑就行,一些bug和規範問題見諒!
簡介
go-kit嚴格意義上並不算是一個完整的框架,更像是一個工具箱或者庫的集合,官方描述它為一組包和最佳實踐的集合。

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

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
說明
-
在Service層定義介面,包含兩個方法
-
Add實現int型別的的加法
-
Concat實現string型別的加法
-
基本流程就是定義介面,實現介面
-
-
在Endpoint層,定義請求和響應資料的結構體,將Service層的方法進行封裝
- 接本流程就是定義結構體,封裝方法
-
在Transport層,進行具體協議處理和響應
-
實現編解碼
-
實現Handler
-
定義路由和埠
-
……
-
測試
使用Postman進行測試


RPC
這裡使用gRpc
說明
-
實現proto檔案
-
定義proto資料夾
-
在資料夾中編寫proto檔案,定義service和message
-
執行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
-
-
在Service層定義介面,包含兩個方法
-
Add實現int型別的的加法
-
Concat實現string型別的加法
-
基本流程就是定義介面,實現介面
-
-
在Endpoint層,定義請求和響應資料的結構體,將Service層的方法進行封裝
- 接本流程就是定義結構體,封裝方法
-
在Transport層,進行具體協議處理和響應
-
實現rpc編解碼
-
實現Handler
-
實現protobuf介面
-
……
-
測試
使用Postman進行測試


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

中介軟體
日誌
-
全域性建立日誌
-
在介面實現的時候傳入日誌
-
定義日誌介面,在介面中加入應用介面+日誌,然後再實現方法
// go-kit官方设计
type logMiddleware struct {
logger log.Logger
next AddService
}
在專案中加入日誌中介軟體,簡單實現示意

限流
加入限流中介軟體,1秒鐘只能請求一次
在實際業務場景中可以針對單個使用者進行更加細粒度的限制

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

指標採集
使用metrics包來記錄關於服務執行時行為的統計資訊,比如計算已處理作業的數量、記錄請求完成後的持續時間以及跟蹤正在執行的操作的數量等等。
在專案中加入指標採集中介軟體,簡單實現示意


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

簡單實現示意

服務發現和負載均衡
關於 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分別在兩個終端,呼叫的時候會自動輪詢

