社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
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本身不是一个框架,而是一套微服务工具集, 它可以用来解决分布式系统开发中的大多数常见问题. 所以你可以专注于你的业务逻辑中.
功能 | 组件 |
---|---|
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 使用一个抽象Endpoint 来表示每一个服务提供的方法. Endpoint通过被一个service进行实现, 或是被一个client调用.
go-kit 组件围绕Endpoint来构建, 包括 断路器, 限流器,日志, Metrics, 请求追踪, 服务发现和负载均衡. 比如你可以使用etcd, consul, zookeeper实现你的服务注册, 甚至如果你的团队之前使用的是用的Spring Cloud家族的Eureka, go-kit 也提供支持;
以下就是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 的传输层目前支持grpc,thrift,http,net/rpc, 个人倾向于grpc作为传输层
对于传输层, 看过github中的example的同学可能会觉得过于繁琐. 需要对每个方法编写Encode/Decode, 导致可能实现一个接口, 来来回回业务代码都没写多少, encode来decode去, 开发者已经复制粘贴到手酸了.
下面我们来看看如何解决这个问题
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
编写.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命令truss *.proto
, 生成你的服务, 生成出来的代码目录结构如下图:
在handlers中注入你所需要的中间件, 如日志, 服务发现, 负载均衡, Metrics, 限流器, 断路器等
在handlers/handlers.go
文件中实现服务的业务逻辑
Run Your Service , 你已经同时实现了grpc和http的接口,如果需要的话, 还可以使用grpc生态中的grpc-gateway生成swagger
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!