「go-zero 系列」zRPC 使用示例

1,643 阅读2分钟

💬

谁来剪月光。

💻

最近开始学习 go-zero 开始使用此框架来进行项目开发,(可能很多人都知道这个现在比较盛行的框架了)。接下来先从最简单的 rpc sample 说起,体验一下 goctl 生成通用代码的能力,以及后续的展望。

环境安装

1、安装 go 环境,可以考虑使用 gvm 来做 go 多版本环境管理

2、开启 go module,配置 goproxy

go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.io # 也可以使用 goproxy.cn

3、安装 goctl

go get -u github.com/tal-tech/go-zero/tools/goctl
# 正常安装成功之后 二进制程序会在 $GOPATH/bin 目录下 可通过 goctl -v 查看版本进行安装结果验证

4、安装 protoc & protoc-gen-go

  • protoc

进入 releases 页面下载对应系统的压缩包

PROTOC_ZIP=protoc-3.15.6-linux-x86_64.zip
curl -OL https://github.com/protocolbuffers/protobuf/releases/download/v3.15.6/$PROTOC_ZIP 
unzip $PROTOC_ZIP
mv bin/protoc $GOPATH/bin
# protoc --version
  • 安装 protoc-gen-go
go get -u github.com/golang/protobuf/protoc-gen-go@v1.3.2

示例开发

  • 初始化项目
cd Documents
mkdir go-zero-sample & cd go-zero-sample
go mod init go-zero-sample
go get -u github.com/tal-tech/go-zero
  • 生成 proto 模版
goctl rpc template -o=hello.proto
# ashing @ ashing-virtual-machine in ~/Documents/go-zero-sample [0:57:41] C:1
$ cat hello.proto 
syntax = "proto3";
​
package hello;
​
message Request {
  string ping = 1;
}
​
message Response {
  string pong = 1;
}
​
service Hello {
  rpc Ping(Request) returns(Response);
}
  • 根据 proto 文件生成 rpc 服务的相应文件
goctl rpc proto -src hello.proto -dir .

目录结构如下

# ashing @ ashing-virtual-machine in ~/Documents/go-zero-sample [0:51:07] 
$ tree 
.
├── etc
│   └── hello.yaml
├── go.mod
├── go.sum
├── hello
│   └── hello.pb.go
├── helloclient
│   └── hello.go
├── hello.go
├── hello.proto
└── internal
    ├── config
    │   └── config.go
    ├── logic
    │   └── pinglogic.go
    ├── server
    │   └── helloserver.go
    └── svc
        └── servicecontext.go8 directories, 11 files
  • 基础设施配置

服务注册发现依赖于 etcd,所以本地需要先启动一个 etcd 服务端

wget https://github.com/etcd-io/etcd/releases/download/v3.2.32/etcd-v3.2.32-linux-amd64.tar.gz
tar -zxvf etcd-v3.2.32-linux-amd64.tar.gz
cd etcd-v3.2.32-linux-amd64
./etcd

并使用 etcdctl watch 前缀为 hello.rpc 的 key

ETCDCTL_API=3 etcdctl watch hello.rpc --prefix
  • 业务逻辑修改
// internal/logic/pinglogic.go
func (l *PingLogic) Ping(in *hello.Request) (*hello.Response, error) {
  return &hello.Response{
    Pong: fmt.Sprintf("hello: %s", in.Ping),
  }, nil
}
  • 启动服务
# 在项目根目录执行
go run hello.go

image-20210330012126883.png

可以发现服务已经注册上 etcd

  • 客户端请求测试
package helloclient
​
import (
  "context"
  "github.com/tal-tech/go-zero/core/discov"
  "github.com/tal-tech/go-zero/zrpc"
  "testing"
)
​
func TestPing(t *testing.T)  {
​
  client := zrpc.MustNewClient(zrpc.RpcClientConf{
    Etcd:      discov.EtcdConf{
      Hosts: []string{"127.0.0.1:2379"},
      Key:   "hello.rpc",
    },
  })
​
  h := NewHello(client)
  resp, err :=h.Ping(context.TODO(), &Request{
    Ping:                 "ashing",
  })
  if err != nil {
    t.Error(err)
    return
  }
​
  t.Log(resp.GetPong())
}
# ashing @ ashing-virtual-machine in ~/Documents/go-zero-sample/helloclient [1:36:20] C:2
$ go test -v -test.run TestPing       
=== RUN   TestPing
2021/03/30 01:36:45 {"@timestamp":"2021-03-30T01:36:45.648+08","level":"stat","content":"p2c - conn: 127.0.0.1:8989, load: 824, reqs: 1"}
    hello_test.go:28: hello: ashing
--- PASS: TestPing (0.01s)
PASS
ok      go-zero-sample/helloclient      0.014s
  • 小结

至此,一个使用 go-zero 搭建的 rpc demo 已完成,可以看到主要的工作在于 proto 文件的编写以及业务逻辑的编写,goctl 会生成相关的代码,当然这是理想情况,例如我们需要使用其他的一些中间件数据库配置那么应该怎么办呢,其实就涉及到一些对应的修改。之后继续补充。

🎸

所以暂时将你眼睛闭了起来

🌞

嗯 那么早点睡~

写于 2021-03-30 凌晨