从单体架构迁移到微服务架构,这已经是大势所趋。在这其中,Go 语言高效的性能、简洁的语法、广泛验证的工程效率、极致的部署体验、极低的服务端资源成本,成为了实现微服务框架的首选。然而,如何整合构建一个既易于上手,又功能丰富,且稳定高性能的微服务架构,这并不是一件简单的事情。
简介
Go-zero,是 tal-tech 在 Github 上开源的集成了各种工程实践的 web 和 rpc 框架,目前版本为 v1.1.6。
go-zero 包含极简的 API 定义和生成工具 goctl,可以根据定义的 api 文件一键生成 Go, iOS, Android, Kotlin, Dart, TypeScript, JavaScript 代码,并可直接运行。
go-zero 使用简单,功能强大,兼容性强。相比于其他微服务框架,go-zero 的优势包括:
- 轻松获得支撑千万日活服务的稳定性
- 内建级联超时控制、限流、自适应熔断、自适应降载等微服务治理能力,无需配置和额外代码
- 微服务治理中间件可无缝集成到其它现有框架使用
- 极简的 API 描述,一键生成各端代码
- 自动校验客户端请求参数合法性
- 大量微服务治理和并发工具包
使用
go-zero 是一个集成了各种工程实践的包含 web 和 rpc 框架,有如下主要特点:
- 强大的工具支持,尽可能少的代码编写
- 极简的接口
- 完全兼容 net/http
- 支持中间件,方便扩展
- 高性能
- 面向故障编程,弹性设计
- 内建服务发现、负载均衡
- 内建限流、熔断、降载,且自动触发,自动恢复
- API 参数自动校验
- 超时级联控制
- 自动缓存控制
- 链路跟踪、统计报警等
- 高并发支撑,稳定保障了疫情期间每天的流量洪峰
go-zero 的架构设计如下图所示:
go-zero 分为:客户端、API 端、Service 端、缓存层和数据库,使用服务发现ETCD集群连接 Service端和API端。
API 端使用 HTTP 协议,实现了包括鉴权、加解密、日志记录、异常捕获、监控报警、数据统计、并发控制、链路跟踪、超时控制、自动熔断、自动降载等。
Service 端使用 gRPC 协议,实现了包括调用鉴权等于 API 相近的机制。
go-zero 通过一系列机制,从多个层面保证服务的高可用性:
使用 go-zero,通过 go get 进行安装即可:
GO111MODULE=on GOPROXY=https://goproxy.cn/,direct go get -u github.com/tal-tech/go-zero
我们来看一下如何快速构建一个高并发的微服务。首先,安装 goctl 工具:
GO111MODULE=on GOPROXY=https://goproxy.cn/,direct go get -u github.com/tal-tech/go-zero/tools/goctl
如果使用 go1.16 版本, 可以使用 go install 命令安装:
GOPROXY=https://goproxy.cn/,direct go install github.com/tal-tech/go-zero/tools/goctl@latest
使用 goctl,可以快速生成 api 服务:
goctl api new greet
cd greet
go mod init
go mod tidy
go run greet.go -f etc/greet-api.yaml
服务默认监听 8888 端口,可以通过 curl 请求:
curl -i http://localhost:8888/from/you
返回如下结果:
HTTP/1.1 200 OK
Content-Type: application/json
Date: Thu, 22 Oct 2020 14:03:18 GMT
Content-Length: 14
{"message":""}
至此,我们成功实现了一个简单的 HTTP 服务。
编写业务代码:
- api 文件定义了服务对外暴露的路由,可参考 api 规范。可以在 servicecontext.go 里面传递依赖给 logic,比如 mysql, redis 等
- 在 api 定义的 get/post/put/delete 等请求对应的 logic 里增加业务处理逻辑
可以根据 api 文件生成前端需要的 Java, TypeScript, Dart, JavaScript 代码:
goctl api java -api greet.api -dir greet
goctl api dart -api greet.api -dir greet
...
我们来看一个更为复杂一些的例子,实现一个短链服务。短链服务就是将长的 URL 网址,通过程序计算等方式,转换为简短的网址字符串。
在 shorturl/api 目录下通过 goctl 生成 api/shorturl.api:
goctl api -o shorturl.api
编辑 shortulr.api:
type (
expandReq struct {
shorten string `form:"shorten"`
}
expandResp struct {
url string `json:"url"`
}
)
type (
shortenReq struct {
url string `form:"url"`
}
shortenResp struct {
shorten string `json:"shorten"`
}
)
service shorturl-api {
@server(
handler: ShortenHandler
)
get /shorten(shortenReq) returns(shortenResp)
@server(
handler: ExpandHandler
)
get /expand(expandReq) returns(expandResp)
}
type 用法和 go 一致,service 用来定义 get/post/head/delete 等 api 请求,解释如下:
- service shorturl-api { 这一行定义了 service 名字
- @server 部分用来定义 server 端用到的属性
- handler 定义了服务端 handler 名字
- get /shorten(shortenReq) returns(shortenResp) 定义了 get 方法的路由、请求参数、返回参数等
然后,我们使用 goctl 生成 API Gateway 代码:
goctl api go -api shorturl.api -dir .
启动 API Gateway 服务,默认侦听在 8888 端口:
go run shorturl.go -f etc/shorturl-api.yaml
到此,我们实现了一个简单的网关服务。然后,在 rpc/transform 目录下编写 transform.proto 文件:
syntax = "proto3";
package transform;
message expandReq {
string shorten = 1;
}
message expandResp {
string url = 1;
}
message shortenReq {
string url = 1;
}
message shortenResp {
string shorten = 1;
}
service transformer {
rpc expand(expandReq) returns(expandResp);
rpc shorten(shortenReq) returns(shortenResp);
}
用 goctl 生成 rpc 代码,在 rpc/transform 目录下执行命令:
goctl rpc proto -src transform.proto -dir .
修改配置文件 shorturl-api.yaml,增加如下内容:
Transform:
Etcd:
Hosts:
- localhost:2379
Key: transform.rpc
通过 etcd 自动去发现可用的 transform 服务。修改 internal/config/config.go ,增加 transform 服务依赖:
type Config struct {
rest.RestConf
Transform zrpc.RpcClientConf // 手动代码
}
修改
internal/svc/servicecontext.go:
type ServiceContext struct {
Config config.Config
Transformer transformer.Transformer // 手动代码
}
func NewServiceContext(c config.Config) *ServiceContext {
return &ServiceContext{
Config: c,
Transformer: transformer.NewTransformer(zrpc.MustNewClient(c.Transform)), // 手动代码
}
}
通过 ServiceContext 在不同业务逻辑之间传递依赖。
定义数据表 shorturl.sql:
CREATE TABLE `shorturl`
(
`shorten` varchar(255) NOT NULL COMMENT \'shorten key\',
`url` varchar(255) NOT NULL COMMENT \'original url\',
PRIMARY KEY(`shorten`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
并进行 CRUD 和 Cache 相关代码的生成。最终,我们就能得到一个短链服务。
总结
go-zero 是一个集成了各种工程实践的包含 web 和 rpc 框架,具有强大的工具支持和极简的接口;完全兼容 net/http;支持中间件,方便扩展;高性能;面向故障编程,弹性设计等,使其成为一个优秀的微服务框架。
内容出处:,
声明:本网站所收集的部分公开资料来源于互联网,转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。如果您发现网站上有侵犯您的知识产权的作品,请与我们取得联系,我们会及时修改或删除。文章链接:http://www.yixao.com/share/22386.html