手把手帶你使用 go-kit(option)


option參數的各種用法

Error對象的處理

主要在 main.go中 httpTransport.NewServer() 函數中的 ServerOption 選傳參數
我們可以看到

// ServerOption設置服務器的可選參數。
type ServerOption func(*Server)

// ServerBefore函數在HTTP請求對象上執行之前
// 請求被解碼
func ServerBefore(before ...RequestFunc) ServerOption {
	return func(s *Server) { s.before = append(s.before, before...) }
}

// 之后,在HTTP響應編寫器上執行ServerAfter函數
// 端點被調用,但沒有任何內容寫入客戶端。
func ServerAfter(after ...ServerResponseFunc) ServerOption {
	return func(s *Server) { s.after = append(s.after, after...) }
}

// ServerErrorEncoder用於將錯誤編碼為http.ResponseWriter
// 只要在處理請求時遇到它們客戶可以
// 使用它來提供自定義錯誤格式和響應代碼默認
// 錯誤將使用DefaultErrorEncoder寫入。
func ServerErrorEncoder(ee ErrorEncoder) ServerOption {
	return func(s *Server) { s.errorEncoder = ee }
}

// ServerErrorLogger用於記錄非終端錯誤默認情況下沒有錯誤
// 被記錄這旨在作為診斷措施更細粒度的控制
// 錯誤處理(包括更詳細的日志記錄)應在
// 自定義ServerErrorEncoder或ServerFinalizer,它們都可以訪問
// 上下文
// 棄用:改用ServerErrorHandler。
func ServerErrorLogger(logger log.Logger) ServerOption {
	return func(s *Server) { s.errorHandler = transport.NewLogErrorHandler(logger) }
}

// ServerErrorHandler用於處理非終端錯誤默認情況下非終端錯誤
// 被忽略這旨在作為診斷措施更細粒度的控制
// 錯誤處理(包括更詳細的日志記錄)應在
// 自定義ServerErrorEncoder或ServerFinalizer,它們都可以訪問
// 上下文
func ServerErrorHandler(errorHandler transport.ErrorHandler) ServerOption {
	return func(s *Server) { s.errorHandler = errorHandler }
}

// ServerFinalizer在每個HTTP請求的末尾執行
// 默認情況下,沒有注冊終結器
func ServerFinalizer(f ...ServerFinalizerFunc) ServerOption {
	return func(s *Server) { s.finalizer = append(s.finalizer, f...) }
}

我們寫一個錯誤處理的demo

// Transport/transport.go
// ErrorEncoder: 自定義服務錯誤處理
func ErrorEncoder(c context.Context, err error, w http.ResponseWriter) {
	contentType, _ := "text/plain; charset=utf-8", []byte(err.Error())
	w.Header().Set("content-type", contentType)
	// 如果出錯返回500
	w.WriteHeader(500)
	w.Write([]byte("500"))
}
// main.go
package main

import (
	EndPoint1 "Songzhibin/go-kit-demo/v0/EndPoint"
	"Songzhibin/go-kit-demo/v0/Server"
	"Songzhibin/go-kit-demo/v0/Tool"
	"Songzhibin/go-kit-demo/v0/Transport"
	"errors"
	"fmt"
	httpTransport "github.com/go-kit/kit/transport/http"
	"github.com/gorilla/mux"
	"net/http"
	"os"
	"os/signal"
	"syscall"
)

// 服務發布

func main() {
	// 1.先創建我們最開始定義的Server/server.go
	s := Server.Server{}

	// 2.在用EndPoint/endpoint.go 創建業務服務

	hello := EndPoint1.MakeServerEndPointHello(s)

	// 加入中間件
	Bye := EndPoint1.MiddleWare(EndPoint1.B)(EndPoint1.MakeServerEndPointBye(s))

	// 3.使用 kit 創建 handler
	// 固定格式
	// 傳入 業務服務 以及 定義的 加密解密方法

	helloServer := httpTransport.NewServer(hello, Transport.HelloDecodeRequest, Transport.HelloEncodeResponse)

	// 新建option
	option := []httpTransport.ServerOption{httpTransport.ServerErrorEncoder(Transport.ErrorEncoder)}
	sayServer := httpTransport.NewServer(Bye, Transport.ByeDecodeRequest, Transport.ByeEncodeResponse, option...)

	//// 使用http包啟動服務
	//go http.ListenAndServe("0.0.0.0:8000", helloServer)
	//
	//go http.ListenAndServe("0.0.0.0:8001", sayServer)
	//select {}

	// https://github.com/gorilla/mux
	r := mux.NewRouter()
	// 注冊路由
	r.Handle("/hello", helloServer)
	r.Handle("/bye", sayServer)
	// 因為這里要做服務發現,所以我們增加一個路由 進行心跳檢測使用
	r.Methods("GET").Path("/health").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-type", "application/json")
		_, _ = w.Write([]byte(`{"status":"ok"}`))
	})
	// 注冊
	errChan := make(chan error)
	sign := make(chan os.Signal)
	go func() {
		err := Tool.RegService("127.0.0.1:8500", "1", "測試", "127.0.0.1", 8000, "5s", "http://10.43.1.106:8000/health", "test")
		if err != nil {
			errChan <- err
		}
		_ = http.ListenAndServe("0.0.0.0:8000", r)
	}()
	go func() {
		// 接收到信號
		signal.Notify(sign, syscall.SIGINT, syscall.SIGTERM)
		<-sign
		errChan <- errors.New("0")
	}()
	fmt.Println(<-errChan)
	Tool.LogOutServer()
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM