框架的总体设计思路是分层 + 针对接口编程,以达到不变的是流程,变化的都是细节的效果。
- 分层是指框架规定了一个 rpc 的处理流程。例如客户端想调用服务端的一个函数,需要经过服务发现、负载均衡、序列化参数、网络传输等步骤;服务端接收到一个请求包后,需要经过反序列化、调用服务、返回响应等步骤。每个步骤有自己的职责,例如服务发现要找到某个服务的可用节点,负载均衡决定这个请求要发往哪个节点。
- 针对接口编程是指每一层之间的交互都是通过接口进行的,不涉及到具体实现。也就是说,每一层的具体实现可以有多个,并且这些实现之间互相替换不需要修改上层代码。例如,我们实现了多种负载均衡算法,包括轮询、随机、哈希取余、动态权重等,但是流程使用的是同一个接口
SelectServer,具体实现是通过依赖注入的。这种做法也给框架提供了一定的扩展性:如果用户需要实现自己的负载均衡算法,只要实现SelectServer接口,并将其注册到指定地方即可。
除此之外,框架还遵循了以下原则:
-
控制反转。在实现服务发现功能时,发现了一个现象:不管是本地配置文件还是远程的注册中心,为了获知节点变化,都存在两种模式:主动轮询和被动通知。为了同时支持这两种模式,我们把控制权交给用户,由用户在节点变化时,调用接口通知我们,而不是框架主动获取。
-
尽量保证接口的易用性,这很大程度上关系到用户愿不愿意用你的框架。现在我们想调用远程的某个函数,只需要指定服务名、方法名、方法参数和可选的回调函数。实际上,框架内部有很多参数可配置,但是我们都尽量给了合理的默认值。如果你对框架比较熟悉,可以通过接口支持的一些关键字参数来控制框架的行为,例如设置超时时间、重试次数以及重试策略等。总的来说,我们希望框架对普通用户很容易上手,对高级用户有一定的可玩性。