trpc.group/trpc-go/trpc-go@v1.0.3/server/README.zh_CN.md (about) 1 [English](README.md)| 中文 2 3 # tRPC-Go Server 模块 4 5 6 ## 背景 7 8 一个服务进程可能会监听多个端口,在不同端口上提供不同的业务服务。因此 server 模块提出了服务实例(Server)、逻辑服务(Service)和协议服务(proto service)的概念。通常一个进程包含一个服务实例,每个服务实例可以包含一个或者多个逻辑服务。逻辑服务用于名字注册,客户端会使用逻辑服务名进行路由寻址发起网络请求,服务端接收到请求后根据指定的协议服务执行服务端的业务逻辑。 9 10 - `Server`:代表一个服务实例,即一个进程 11 - `Service`:代表一个逻辑服务,即一个真正监听端口的对外服务,与配置文件中的 service 一一对应,一个 server 可能包含多个 service,一个端口一个 service 12 - `Proto service`:代表一个协议服务,protobuf 协议文件里面定义的 service,通常 service 与 proto service 是一一对应的,也可由用户自己通过 Register 任意组合 13 14 ```golang 15 // Server is a tRPC server. One process, one server. 16 // A server may offer one or more services. 17 type Server struct { 18 MaxCloseWaitTime time.Duration 19 } 20 21 // Service is the interface that provides services. 22 type Service interface { 23 // Register registers a proto service. 24 Register(serviceDesc interface{}, serviceImpl interface{}) error 25 // Serve starts serving. 26 Serve() error 27 // Close stops serving. 28 Close(chan struct{}) error 29 } 30 ``` 31 32 ## service 映射关系 33 34 假如协议文件中提供 hello service,如: 35 36 ```protobuf 37 service hello { 38 rpc SayHello(HelloRequest) returns (HelloReply) {}; 39 } 40 ``` 41 42 配置文件写了多个 service,分别提供 trpc 和 http 协议服务如: 43 44 ```yaml 45 server: # 服务端配置 46 app: test # 业务的应用名 47 server: helloworld # 进程服务名 48 close_wait_time: 5000 # 关闭服务时的最小等待时间,用于等待服务反注册完成,单位 ms 49 max_close_wait_time: 60000 # 关闭服务时的最大等待时间,用于等待请求处理完成,单位 ms 50 service: # 业务服务提供两个 service,监听不同的端口提供不同协议的服务 51 - name: trpc.test.helloworld.HelloTrpc # 第一个 service 的路由名称 52 ip: 127.0.0.1 # 服务监听 ip 地址 53 port: 8000 # 服务监听端口 8000 54 protocol: trpc # 提供 trpc 协议服务 55 - name: trpc.test.helloworld.HelloHttp # 另一个 service 的路由名称 56 ip: 127.0.0.1 # 服务监听 ip 地址 57 port: 8080 # 监听端口 8080 58 protocol: http # 提供 http 协议服务 59 ``` 60 61 为不同的逻辑服务注册协议服务 62 63 ```golang 64 type helloImpl struct{} 65 66 func (s *helloImpl) SayHello(ctx context.Context, req *pb.HelloRequest) (*pb.HelloReply, error) { 67 rsp := &pb.HelloReply{} 68 // implement business logic here ... 69 return rsp, nil 70 } 71 72 func main() { 73 s := trpc.NewServer() 74 75 // 推荐:为每个 service 单独注册 proto service 76 pb.RegisterHiServer(s.Service("trpc.test.helloworld.HelloTrpc"), helloImpl) 77 pb.RegisterHiServer(s.Service("trpc.test.helloworld.HelloHttp"), helloImpl) 78 79 // 第二种方式,为 server 中的所有 service 注册同一个 proto service 80 pb.RegisterHelloServer(s, helloImpl) 81 } 82 ``` 83 84 ## 服务端执行流程 85 86 1. 网络层 Accept 到一个新连接启动一个协程处理该连接的数据 87 2. 收到一个完整数据包,解包整个请求 88 3. 查询根据具体的 proto service 名,定位到具体处理函数 89 4. 解码请求体 90 5. 设置消息整体超时 91 6. 解压缩,反序列化请求体 92 7. 调用前置拦截器 93 8. 进入业务处理函数 94 9. 退出业务处理函数 95 10. 调用后置拦截器 96 11. 序列化,压缩响应体 97 12. 打包整个响应 98 13. 回包给上游客户端