手把手带你使用 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()
}