go-kit
是一個(gè)分布式的開發(fā)工具集溢吻,在大型的組織(業(yè)務(wù))中可以用來構(gòu)建微服務(wù)铆铆。其解決了分布式系統(tǒng)中的大多數(shù)常見問題建车,因此俺夕,使用者可以將精力集中在業(yè)務(wù)邏輯上裳凸。
go-kit的架構(gòu)如圖分為三層結(jié)構(gòu):Transport層,Endpoint層劝贸,Service層姨谷。
Transport
層主要負(fù)責(zé)與傳輸協(xié)議HTTP,GRPC映九,THRIFT等相關(guān)的邏輯菠秒;
Endpoint
層主要負(fù)責(zé)request/response格式的轉(zhuǎn)換,以及公用攔截器相關(guān)的邏輯氯迂;
Service
層則專注于業(yè)務(wù)邏輯践叠,就是我們的業(yè)務(wù)類、接口等相關(guān)信息存放嚼蚀。
go-kit除了經(jīng)典的分層架構(gòu)外禁灼,還在endpoint層提供了很多公用的攔截器,如log轿曙,metric弄捕,tracing僻孝,circuitbreaker,rate-limiter等守谓,來保障業(yè)務(wù)系統(tǒng)的可用性穿铆。
go-kit demo(一)基于http訪問
目錄結(jié)構(gòu)
UserEndPoint.go
package myEndPoints
import (
"context"
"example.com/myServices"
"github.com/go-kit/kit/endpoint"
)
//定義Request、Response格式斋荞,并可以使用裝飾器(閉包)包裝函數(shù),以此來實(shí)現(xiàn)各個(gè)中間件嵌套
type UserRequest struct {
Id int `json:"id"`
}
type UserResponse struct {
Name string `json:"name"`
}
func MakeServerEndPointGetName(s myServices.IUserService) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
r,ok := request.(UserRequest)
if !ok{
return response,nil
}
return UserResponse{Name: s.GetName(r.Id)},nil
}
}
UserService.go
package myServices
//這里就是我們的業(yè)務(wù)類荞雏、接口等相關(guān)信息存放
type IUserService interface {
GetName(userId int) string
}
type UserService struct {
}
func (s UserService) GetName(uid int) string {
if uid == 10{
return "wangqiang"
}
return "xiaoqiang"
}
UserTransport.go
package myTransports
import (
"context"
"encoding/json"
"errors"
"example.com/myEndPoints"
"net/http"
"strconv"
)
//Transport層主要負(fù)責(zé)與傳輸協(xié)議HTTP,GRPC平酿,THRIFT等相關(guān)的邏輯凤优;
func GetNameDecodeRequest (c context.Context,r *http.Request) (interface{}, error){
id := r.URL.Query().Get("id")
if id ==""{
return nil,errors.New("無效參數(shù)")
}
intid, err := strconv.Atoi(id)
if err != nil{
return nil,errors.New("無效參數(shù)")
}
return myEndPoints.UserRequest{Id: intid},nil
}
func GetNameEncodeResponse(c context.Context,w http.ResponseWriter,res interface{}) error {
w.Header().Set("Content-Type", "application/json;charset=utf-8")
return json.NewEncoder(w).Encode(res)
}
main.go
package main
import (
"example.com/myEndPoints"
"example.com/myServices"
"example.com/myTransports"
"github.com/go-kit/kit/transport/http"
"log"
sthttp "net/http"
)
func main() {
//業(yè)務(wù)接口服務(wù)
s := myServices.UserService{}
//使用myEndPoints創(chuàng)建業(yè)務(wù)服務(wù)
getName := myEndPoints.MakeServerEndPointGetName(s)
//使用 kit 創(chuàng)建 handler
// 固定格式
// 傳入 業(yè)務(wù)服務(wù) 以及 定義的 加密解密方法
server := http.NewServer(getName, myTransports.GetNameDecodeRequest, myTransports.GetNameEncodeResponse)
//監(jiān)聽服務(wù)
log.Println(sthttp.ListenAndServe(":8080", server))
}
啟動(dòng)程序