Go – Zero 根本架构图
筹备工作
-
装置
etcd, mysql, redis
go # etcd(这个自己之前装的比拟少, 所以上面会贴出装置步骤, 仅供参考, 自行谷歌) curl -L https://github.com/coreos/etcd/releases/download/v3.2.1/etcd-v3.2.1-linux-amd64.tar.gz -o etcd-v3.2.1-linux-amd64.tar.gz tar xzvf etcd-v3.2.1-linux-amd64.tar.gz mv etcd-v3.2.1-linux-amd64 etcd cd etcd $ ./etcd --version etcd Version: 3.2.1 Git SHA: 61fc123 Go Version: go1.8.3 Go OS/Arch: linux/amd64 # mysql, redis(这两个比拟常见,上面仅贴出启动步骤) sudo service mysql start sudo service redis-server start
-
装置
protoc-gen-go
go get -u github.com/golang/protobuf/[email protected]
-
装置
protoc
wget https://github.com/protocolbuffers/protobuf/releases/download/v3.14.0/protoc-3.14.0-linux-x86_64.zip unzip protoc-3.14.0-linux-x86_64.zip sudo cp bin/protoc /usr/local/bin/ sudo chmod 777 /usr/local/bin/protoc $ protoc --version libprotoc 3.14.0
-
装置
goctl 工具
GO111MODULE=on GOPROXY=https://goproxy.cn/,direct go get -u github.com/zeromicro/go-zero/tools/[email protected]
-
创立工作目录
shorturl
和shorturl/api
mkdir -p shorturl/api && cd shorturl && go mod init shorturl vi go.mod
module shorturl go 1.17 require ( github.com/golang/mock v1.4.3 github.com/golang/protobuf v1.4.2 github.com/zeromicro/go-zero v1.3.0 golang.org/x/net v0.0.0-20200707034311-ab3426394381 google.golang.org/grpc v1.29.1 )
go get github.com/golang/[email protected] go get github.com/golang/[email protected] go get github.com/zeromicro/[email protected] go get golang.org/x/[email protected] go get google.golang.org/[email protected]
编写 API Gateway 代码
-
通过 goctl 生成
api/shorturl.api
$ cd api && goctl api -o shorturl.api
// shorturl.api type ( expandReq {shorten string `form:"shorten"`} expandResp {url string `json:"url"`} ) type ( shortenReq {url string `form:"url"`} shortenResp {shorten string `json:"shorten"`} ) service shorturl-api { @server(handler: ShortenHandler) get /shorten(shortenReq) returns(shortenResp) @server(handler: ExpandHandler) get /expand(expandReq) returns(expandResp) } // service shorturl-api { 这一行定义了 service 名字 // @server 局部用来定义 server 端用到的属性 // handler 定义了服务端 handler 名字 // get /shorten(shortenReq) returns(shortenResp) 定义了 get 办法的路由、申请参数、返回参数等
-
应用 goctl 生成 API Gateway 代码
goctl api go -api shorturl.api -dir . tree
. ├── etc │ └── shorturl-api.yaml // 配置文件 ├── go.mod ├── internal │ ├── config │ │ └── config.go // 定义配置 │ ├── handler │ │ ├── expandhandler.go // 实现 expandHandler │ │ ├── routes.go // 定义路由解决 │ │ └── shortenhandler.go // 实现 shortenHandler │ ├── logic │ │ ├── expandlogic.go // 实现 ExpandLogic │ │ └── shortenlogic.go // 实现 ShortenLogic │ ├── svc │ │ └── servicecontext.go // 定义 ServiceContext │ └── types │ └── types.go // 定义申请、返回构造体 ├── shorturl.api └── shorturl.go // main 入口定义
-
启动 API Gateway 服务,默认侦听在 8888 端口
$ go run shorturl.go -f etc/shorturl-api.yaml Starting server at 0.0.0.0:8888...
-
测试 API Gateway 服务
$ curl -i "http://localhost:8888/shorten?url=test" HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 Traceparent: 00-4ef62e5d271bfe067ff8226f6c88ecd2-c08acfe02ba1abf1-00 Date: Sun, 13 Oct 2022 09:12:58 GMT Content-Length: 4 null
编写 transform rpc 服务 (实现业务逻辑)
# 创立 transform.proto 文件
mkdir -p rpc/transform && cd rpc/transform && goctl rpc template -o transform.proto
// transform.proto
syntax = "proto3";
package transform;
option go_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 protoc transform.proto --go_out=. --go-grpc_out=. --zrpc_out=.
# rpc 目录构造
transform
├── etc
│ └── transform.yaml // 配置文件
├── internal
│ ├── config
│ │ └── config.go // 配置定义
│ ├── logic
│ │ ├── expandlogic.go // expand 业务逻辑在这里实现
│ │ └── shortenlogic.go // shorten 业务逻辑在这里实现
│ ├── server
│ │ └── transformerserver.go // 调用入口, 不须要批改
│ └── svc
│ └── servicecontext.go // 定义 ServiceContext,传递依赖
├── transform
│ ├── transform_grpc.pb.go
│ └── transform.pb.go
├── transformer
│ └── transformer.go // 提供了内部调用办法,无需批改
├── transform.go // rpc 服务 main 函数
└── transform.proto
# 间接运行
$ go run transform.go -f etc/transform.yaml