本文聊聊游戏服务器中常见的通信模型和对比,讨论下常见的实现方案,最后分享下我们当前的实践。
常见的交互语义
在实践中,节点交互中常用的点对点通信方式,对应用层而言,可以大概分为以下几种:
- 同步RPC
- 同步请求
- 异步消息
- 异步请求
- 发布订阅
在本文中,我将围绕一个简单的例子,来聊聊对这几种交互语义的个人理解。
该例子为: 作为client端的A需要执行(x+y)*z
操作,但其中的x+y
,是由server端B实现的,A需要请求B得到x+y
的结果,再将其*z
完成业务逻辑。
同步RPC
RPC库通常有现成的轮子,比如gRPC、thrift等,以golang gRPC为例:
1 2 3 4 5 6 7 8 9 10 11 12 13
| func handle (x,y,z int) int { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() req := &AddReq{X: x, Y: y} ack, err := grpcClient.Add(ctx, req) return ack.Result * z }
func (b *B) Add(ctx context.Context, req *AddReq) (*AddAck, error) { return &AddAck{Result: req.X+req.Y}, nil }
|
代码简洁明了,远程请求和本地函数调用一样方便,这种写法应该是开发者最喜欢的方式。诸如超时,错误传递,甚至负载均衡等,gRPC都已经处理好了。同步RPC的缺点在后面讨论同步异步以及具体RPC框架的时候会讨论。