o-Zero:集成了各种工程实践的Web和RPC微服务框架

从单体架构迁移到微服务架构,这已经是大势所趋。在这其中,Go 语言高效的性能、简洁的语法、广泛验证的工程效率、极致的部署体验、极低的服务端资源成本,成为了实现微服务框架的首选。然而,如何整合构建一个既易于上手,又功能丰富,且稳定高性能的微服务架构,这并不是一件简单的事情。

Go-Zero - 集成了各种工程实践的 Web 和 RPC 微服务框架

go-zero

简介

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

使用

go-zero 是一个集成了各种工程实践的包含 web 和 rpc 框架,有如下主要特点:

  • 强大的工具支持,尽可能少的代码编写
  • 极简的接口
  • 完全兼容 net/http
  • 支持中间件,方便扩展
  • 高性能
  • 面向故障编程,弹性设计
  • 内建服务发现、负载均衡
  • 内建限流、熔断、降载,且自动触发,自动恢复
  • API 参数自动校验
  • 超时级联控制
  • 自动缓存控制
  • 链路跟踪、统计报警等
  • 高并发支撑,稳定保障了疫情期间每天的流量洪峰

go-zero 的架构设计如下图所示:

Go-Zero - 集成了各种工程实践的 Web 和 RPC 微服务框架

go-zero

go-zero 分为:客户端、API 端、Service 端、缓存层和数据库,使用服务发现ETCD集群连接 Service端和API端。

API 端使用 HTTP 协议,实现了包括鉴权、加解密、日志记录、异常捕获、监控报警、数据统计、并发控制、链路跟踪、超时控制、自动熔断、自动降载等。

Service 端使用 gRPC 协议,实现了包括调用鉴权等于 API 相近的机制。

go-zero 通过一系列机制,从多个层面保证服务的高可用性:

Go-Zero - 集成了各种工程实践的 Web 和 RPC 微服务框架

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 网址,通过程序计算等方式,转换为简短的网址字符串。

Go-Zero - 集成了各种工程实践的 Web 和 RPC 微服务框架

go-zero

在 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

发表评论

登录后才能评论