适宜读者人群
- Golang 开发者
文章目录
-
Go-kit 简述
-
Go-kit 组件
-
Go-kit 更便捷的使用方式
Go-kit 简述
曾经听说过两种对立的说法, "go-kit 很轻量" 和 "go-kit 太笨重, 太繁琐", 下面就来看看通过go-kit如何解决微服务架构中的常见问题, 以及Go-kit便捷的开发姿势
微服务架构设计关注点
-
Rate Limiter 限流器
-
Trasport 数据传输(序列化和反序列化)
-
Logging 日志
-
Metrics 指标
-
Circuit breaker 断路器
-
Request tracing 请求追踪
-
Service Discovery 服务发现
Go-kit
go-kit本身不是一个框架,而是一套微服务工具集, 它可以用来解决分布式系统开发中的大多数常见问题. 所以你可以专注于你的业务逻辑中.
Go-kit 当前集成的组件
功能 | 组件 |
---|---|
circuit breaker断路器 | hystrix-go gobreaker handy breaker |
Metrics 指标 | prometheus, dogstatsd, influx,graphite 等多个平台 |
服务发现 | consul, dnssrv, etcd, eureka, lb, zookeeper |
Request Tracing | Opentracing, LightStep, AppDash, Zipkin |
另外日志和限流器组件, 可轻松与常见的日志库集成, 如zap, logrus 等
Go-kit 技术细节
go-kit 使用一个抽象Endpoint 来表示每一个服务提供的方法. Endpoint通过被一个service进行实现, 或是被一个client调用.
go-kit 组件围绕Endpoint来构建, 包括 断路器, 限流器,日志, Metrics, 请求追踪, 服务发现和负载均衡. 比如你可以使用etcd, consul, zookeeper实现你的服务注册, 甚至如果你的团队之前使用的是用的Spring Cloud家族的Eureka, go-kit 也提供支持;
Endpoint
以下就是Endpoint的实现, 其他go-kit组件全部通过装饰者模式注入
type Endpoint func(ctx context.Context, request interface{}) (response interface{}, err error)
type Middleware func(Endpoint) Endpoint
如日志中间件, 仅需实现gokit的Logger interface即可
type Endpoint func(ctx context.Context, request interface{}) (response interface{}, err error)
func(log Logger, in endpoint.Endpoint) endpoint.Endpoint {
return func(ctx context.Context, req interface{}) (interface{}, error) {
logger.Log("input", toJSON(req))
resp, err := in(ctx, req)
logger.Log("output", toJSON(resp), "err", err)
return resp, err
}
}
Go-kit Transport
go-kit 的传输层目前支持grpc,thrift,http,net/rpc, 个人倾向于grpc作为传输层
对于传输层, 看过github中的example的同学可能会觉得过于繁琐. 需要对每个方法编写Encode/Decode, 导致可能实现一个接口, 来来回回业务代码都没写多少, encode来decode去, 开发者已经复制粘贴到手酸了.
下面我们来看看如何解决这个问题
Go-kit 更便捷的使用方式
我们使用Go-kit 代码生成工具 truss, 通过truss你可以快速编写Go-kit中繁杂的代码, 并生成支持http和grpc两种调用方式的服务
truss 目前支持grpc,http, 它通过.proto文件定义你的服务
Github: https://github.com/tuneinc/truss
使用帮助: https://github.com/tuneinc/truss/blob/master/USAGE.md
教程: https://github.com/tuneinc/truss/blob/master/TUTORIAL.md
注意事项: https://github.com/tuneinc/truss/wiki/Levels-of-support-for-different-truss-usecases
truss使用方式
-
编写.proto文件来定义你的服务
syntax = "proto3"; // 定义你的包名 package echo; import "https://github.com/tuneinc/truss/deftree/googlethirdparty/annotations.proto"; // 定义你的服务名 service Echo { // 定义一个方法Echo,输入 EchoRequest ,输出 EchoResponse // EchoRequest 和EchoResponse 在下面的代码中定义 rpc Echo (EchoRequest) returns (EchoResponse) { option (google.api.http) = { // http接口使用GET方法路由至/echo, 所有的字段都会放到query string中 get: "/echo" }; } // 定义一个方法Louder,输入 LouderRequest ,输出 EchoResponse rpc Louder (LouderRequest) returns (EchoResponse) { option (google.api.http) = { // http接口使用POST方法路由至/louder/{Loudness} post: "/louder/{Loudness}" // 所有字段都会被从Body中以http/json方式获取 body: "*" }; } } message EchoRequest { string In = 1; } message LouderRequest { // In is the string to echo back string In = 1; // Loudness is the number of exclamations marks to add to the echoed string int32 Loudness = 2; } message EchoResponse { string Out = 1; }
-
执行truss命令
image.pngtruss *.proto
, 生成你的服务, 生成出来的代码目录结构如下图:
-
在handlers中注入你所需要的中间件, 如日志, 服务发现, 负载均衡, Metrics, 限流器, 断路器等
image.png -
在
handlers/handlers.go
文件中实现服务的业务逻辑 -
Run Your Service , 你已经同时实现了grpc和http的接口,如果需要的话, 还可以使用grpc生态中的grpc-gateway生成swagger
友情链接
- https://github.com/tmrts/go-patterns/blob/master/structural/decorator.md
- https://github.com/go-kit/kit
- https://www.youtube.com/watch?v=NX0sHF8ZZgw
- https://github.com/ru-rocker/gokit-playground
- https://github.com/go-kit/kit/issues/70
- http://www.itdks.com/eventlist/detail/969
- https://blog.heroku.com/microservices_in_go_using_go_kit
网友评论
�[33mWARN�[0m[0000] No valid service is defined; exiting now.
�[36mINFO�[0m[0000] .pb.go generation with protoc-gen-go was successful.