二、微服务:go-kit中间件

1、简介

​ 没有监控,日志等信息是不可能在投入生产环境的。在go-kit中,以中间件的形式添加这些附属服务。其实就是增加新的Endpoint(服务端点),使用go-kit可以很容易的增加你需要的组件。

2、实践

go-kitMiddleware(中间件)的定义如下。

1
type Middleware func(Endpoint) Endpoint

原理很简单,假设传进去一个A_Endpoint,返回一个新的B_Endpoint,新返回的B_Endpoint其实包裹着A_Endpoint,在B_Endpoint中添加我们想要加载的组件。

2.1 统一加载入口

设计一个统一的入口,为每一个rpc接口添加Middleware。并且支持每一个该中间件不添加到制定rpc接口中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
func (e *Endpoints) WrapAllExcept(middleware endpoint.Middleware, excluded ...string) {
//包含所有rcp服务
included := map[string]struct{}{
"TimedTask": struct{}{},
}

//剔除制定rpc服务对
for _, ex := range excluded {
if _, ok := included[ex]; !ok {
log.Println("excluded endpoint ", ex, " does not exist")
}
delete(included, ex)
}
//包裹制定的Endpoint
for incKey := range included {
if incKey == "TimedTask" {
e.TimeTaskEndpoint = middleware(e.TimeTaskEndpoint)
}
}

}

2.2、添加log组件

根据以下定义

1
type Middleware func(Endpoint) Endpoint

定义log中间件,使用gokit中的log组件

1
2
3
4
5
6
7
8
9
10
11
import "github.com/go-kit/kit/log"

func LogMiddleware(next endpoint.Endpoint) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
w := log.NewSyncWriter(os.Stderr)
logger := log.NewLogfmtLogger(w)
logger.Log("req",request)
resp,err := next(ctx,request)
return resp,err
}
}

2.3 添加instrumentation

定义instrumentation组件,使用gokit中的metrics去试试记录服务的行为统计信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import "github.com/go-kit/kit/metrics"

func InstrumentingMiddleware(next endpoint.Endpoint) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
var dur metrics.Histogram = prometheus.NewSummaryFrom(stdprometheus.SummaryOpts{
Namespace: "myservice",
Subsystem: "api",
Name: "request_duration_seconds",
Help: "Total time spent serving requests.",
}, []string{})

defer func(begin time.Time) { dur.Observe(time.Since(begin).Seconds()) }(time.Now())
resp,err := next(ctx,request)
return resp,err
}
}

3、总结

​ 利用中间件来添加需要的服务,围绕Endpoint来构建, 包括 断路器, 限流器,日志, Metrics, 请求追踪, 服务发现和负载均衡.使用起来还是挺方便的。