2023 年底腾讯统一的 RPC 框架 tRPC 正式开源。遍观全网,似乎大部份是对 tRPC 概念上的宣传、架构上的设计,而如何开发、如何部署的文章凤毛麟角。于是笔者小试牛刀撰此文,或许会成为一系列,希望能抛砖引玉。
系列文章
- 腾讯 tRPC-Go 教学——(1)搭建服务
- 腾讯 tRPC-Go 教学——(2)trpc HTTP 能力
- 腾讯 tRPC-Go 教学——(3)微服务间调用
- 腾讯 tRPC-Go 教学——(4)tRPC 组件生态和使用
- ……还有更多,敬请期待……
tRPC 简介
我们先知道一点,tRPC 可以实现两个功能:
- 服务之前使用 protobuf 互相进行网络 RPC 调用
- 给 web 前端提供 API 接口
好了,剩下的我现在不想废话,我们先直接上代码,建服务!然后再来好好介绍 tRPC 的好处。
本文件不打算将服务的目录结构应怎么设计,这是各个团队内部按照自己风格需要去统一规范的事情。此外,本文也假定读者已经懂得使用 go.mod 组织和进行仓库和版本控制。
制订协议
我们先尝试一下给 web 前端提供一个 API 接口。首先,我们定义一个简单的协议 (GitHub 代码),假设命名为 echo.proto
:
syntax = "proto3";
package demo.simplest;
option go_package = "github.com/Andrew-M-C/trpc-go-demo/proto/simplest";
message HelloRequest {
string greeting = 1;
}
message HelloResponse {
int32 err_code = 1;
string err_msg = 2;
string response = 3;
double timestamp = 4;
}
service HelloWorld {
rpc Hello(HelloRequest) returns (HelloResponse); // @alias=/demo/Hello
}
很好理解,经典的 echo 功能,外加一个时间戳。我们这就定义好了一个非常简单的服务。接下来,我们需要把这个服务转换成 trpc 桩代码。为此,我们需要借助 trpc 的一个工具来实现。
其中有一个比较特别的是 // @alias=/demo/Hello
。我以后会讲解它的作用。
trpc 工具链安装
首先,trpc 工具是基于 protoc 实现的,所以,我们首先需要安装 protoc
。假设我们的开发环境是 Linux,那么可以执行以下命令安装(可能需要 sudo):
wget https://github.com/protocolbuffers/protobuf/releases/download/v25.1/protoc-25.1-linux-x86_64.zip
7z x protoc-25.1-linux-x86_64.zip -o/usr/local -y
rm protoc-25.1-linux-x86_64.zip*
chmod +x /usr/local/bin/protoc
protoc --version
上面的命令,读者可以对应我的 demo 项目中 Makefile 文件的 installpb
规则。
接着把 trpc 工具安装了:
go install trpc.group/trpc-go/trpc-cmdline/trpc@latest
trpc version
这个则对应 Makefile 的 make installtrpc
规则。
生成桩代码
安装了工具链之后,我们就可以进入前面我们定义的 proto 文件所在的目录,执行以下命令:
trpc create -f --protofile=echo.proto --protocol=trpc --rpconly --nogomod --mock=false
这串命令可以对应 Makefile 的 make pb
规则。我个人觉得用上面这个参数组合是最舒服最方便的。读者可以先不用管这些参数的意思,先照着用就可以了。随着 trpc 输出一串卖萌的提示之后:
[create] Create tRPC project `echo` post process: succeed! (〃'▽'〃)
可以看到,在目录下生成了 echo.pb.go
和 echo.trpc.go
两个文件。其中前者定义的是在 proto 文件中定义的各种数据类型;而后者则是 trpc 工具链的关键功能:HelloWorld 的客户端和服务端。
撰写业务逻辑
我们就按照最最简单的模式,一个 main package 搞定一切(当然正式的业务肯定要做好功能划分)。我们新建一个 simplest_main.go 文件,输入以下内容:
package main
import (
"context"
"fmt"
"time"
// proto package 的路径请读者自行调整
"github.com/Andrew-M-C/trpc-go-demo/proto/simplest"
"trpc.group/trpc-go/trpc-go"
)
func main() {
s := trpc.NewServer()
simplest.RegisterHelloWorldService(s, helloWorldImpl{})
_ = s.Serve()
}
type helloWorldImpl struct{}
func (helloWorldImpl) Hello(ctx context.Context, req *simplest.HelloRequest) (*simplest.HelloResponse, error) {
rsp := &simplest.HelloResponse{}
rsp.Response = fmt.Sprintf("%s to you, too", req.Greeting)
rsp.TimestampMsec = time.Now().UnixMilli()
return rsp, nil
}
逻辑很简单,我就不废话了。
启动服务
单纯编译上面的代码之后,还不足以实现一个完整的服务。trpc 服务还需要搭配一个配置文件,这个文件我们通常命名为 trpc_go.yaml
。对于咱们这个服务,这个配置文件的内容为:
server:
service:
- name: demo.simplest.HelloWorld
nic: eth0
# ip: 127.0.0.1
port: 8000
network: tcp
protocol: http
timeout: 1800
然后,咱们就可以启动服务了:
go run . -conf conf/trpc_go.yaml
可以看到 trpc 在标准输出输出以下文字:
2024-01-14 14:28:09.886 INFO client/client_linux.go:35 client is empowered with tnet!
2024-01-14 14:28:09.887 DEBUG maxprocs/maxprocs.go:47 maxprocs: Leaving GOMAXPROCS=4: CPU quota undefined
2024-01-14 14:28:09.888 INFO server/service.go:167 process:19556, http service:demo.simplest.HelloWorld launch success, tcp:172.17.0.4:8000, serving ...
这个时候,我们可以执行以下请求:
curl http://172.17.0.4:8000/demo/Hello?greeting=Morning
得到响应:
{"err_code":0, "err_msg":"", "response":"Morning to you, too", "timestamp":1705243778.669}
就这样,一个简单的基于 URL query 的 http 服务,搭建完成了。
难道只能支持 URL query 吗?我们换一个调用方式:
curl http://172.17.0.4:8000/demo/Hello --header 'Content-Type:application/json'\
-d '{"greeting":"Good afternoon"}'
依然得到响应:
{"err_code":0, "err_msg":"", "response":"Good afternoon to you, too", "timestamp":1705243811.625}
下一步
由于笔者最近比较忙,文章先写到这,给读者一个敲门砖。下一篇文章笔者会介绍一下,咱们启动了的这到底是个什么样的服务,究竟支持哪些能力?配置项里面的那些代表了什么?实际业务中,腾讯人是怎么做的?不急不急,请容我歇一会儿,慢慢道来。
下一篇:《手把手 tRPC-Go 教学——(2)trpc HTTP 能力》
推荐阅读
本文章采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。
原作者: amc,原文发布于腾讯云开发者社区,也是本人的博客。欢迎转载,但请注明出处。
原文标题:《手把手 tRPC-Go 教学——(1)搭建服务》
发布日期:2024-01-14