公众号|松花皮蛋的黑板报|RPC原理
松花皮蛋的黑板报
  • 分享在京东工作的技术感悟,还有JAVA技术和业内最佳实践,大部分都是务实的、能看懂的、可复现的

扫一扫
关注公众号

RPC原理

博客首页文章列表 松花皮蛋me 2020-03-08 11:44

、RPC的作用

  1. 屏蔽远程调用跟本地调用的区别,让我们感觉就是调用项目内的方法。隐藏底层网络通信的复杂性,让我们更专注于业务逻辑。

二、完整的RPC涉及到的核心


序列化和反序列(编解码)、协议、桩生成(动态代理、反射执行)。


三、RPC使用过程需要注意什么问题


调用超时或者异常如何处理,接口字段添加和减少或者说版本升级时,如何向下兼容。

四、RPC协议


在传输过程中,RPC并不会把请求参数的所有二进制数据整体一下子发送到对端机器上,中间可能会拆分成多个数据包,也有可能合并成其他请求的数据包。RPC协议就是为了”正确进行装包和拆包”而生的,比如使用设定边界的方式。


协议通常包括固定部分、协议头内容和协议体内容。其中,固定部分常包括协议长度、协议标识、序列化方式、消息ID(实现请求跟响应关联)、消息类型,协议头内容用来进行扩展的,保证协议可平滑升级;协议体通常包括请求接口方法、请求的业务参数值和业务扩展属性;协议头内容单独定义出来,是为了避免将其信息放到协议体中,导致协议体负载太重。


五、序列化和反序列化需要注意什么


编解码框架选择时应该考虑安全性、版本升级的兼容性、跨语言支持性、存储空间占用、网络传输效率、可读性。编解码框架应用时需要注意的点,包括尽量使用原生类型、不要使用过深的继承关系或者依赖关系、避免对象过大。


六、动态代理

RPC自动给接口生成一个代理类,当我们在项目中注入接口的时候,运行过程中实际绑定的是这个接口生成的代理类。JDK默认的代理功能是有一定的局限性的,它要求被代理的类只能是接口。原因是因为生成的代理类会继承Proxy类,但Java是不支持多重继承的。


七、如何设计灵活的RPC框架

将变化部分封装在插件里面,才能达到快速灵活扩展的目的,本质就是微内核架构,比如规则引擎架构。


微内核的核心技术点有插件管理、插件连接、插件通信。插件管理也称为插件注册表,用来述插件模块信息、如何加载、加载时机等等;插件连接是指插件按照核心系统的接口规范实现后如何连接到系统上,比如使用依赖注入;插件通信则是用来协调没有关联关系的插件,比如上下文Pipline。


八、服务注册选型

  • 方案一:DNS轮询。解析缓存导致无法及时响应服务提供者的变更。
  • 方案二:DNS负载均衡。需要搭建四层负载均衡器,也就意味着它存在单点压力隐患。而且,现存的负载均衡算法不够灵活,后端的实例节点还需要手动维护。
  • 方案三:Zookeeper节点服务。大量的服务提供者频繁变更会导致Zookeeper服务负载过高甚至宕机。
  • 方案四:基于消息总线的最终一致性的注册中心。某个注册中心节点推送消息到消息总线,消息总线生成新版本号的数据,再通知其他注册中心和服务提供者更新本地缓存,当然也可以是推拉结合。


九、如何识别服务节点存活情况

服务方的状态通常有三种,分别为健康状态、亚健康状态、死亡状态,其中,亚健康状态下连接是成功的但是心跳请求连续失败。不过,心跳探测通常还会结合业务可用率来判断状态,这样可以及时发现心跳探测间歇性失败的问题。

具体的健康检查分类有静态方法和动态方法。

  • (1)、静态方法:基于服务消费者本身调用来判断服务节点是否可用,更加实时更加准确,而且当注册中心或者网络出现问题时,基本不受影响。这种方式使用更加普遍。
  • (2)、动态方法:服务提供者向注册中心上报心跳信息,然后更新注册列表并同步到服务消费者,同时结合心跳开关保护和服务节点摘取保护机制(控制比例)进行存活判断优化。

十、路由策略


路由策略就是制定服务提供者集群列表筛选规则,比如根据来源或者请求参数控制请求,常用于灰度发布的风险控制,还可用于同机房调用优先调度、读写分离、黑白名单控制。

十一、异常重试


当业务具有幂等性保证时才能让RPC框架帮助我们进行重试,通常通过路由策略实现,当连接异常或者业务白名单异常时就进行重试,重新选择一个新的服务节点进行调用,直到重试最大次数门槛,或者已经达到超时时间设定。

十二、优雅关闭


服务对象在关闭过程中,会拒绝新的请求,同时根据引用计数器等待正在处理的请求全部结束之后才会真正关闭。另外,为了避免一直等待造成应用无法正常退出,还需要在整个ShutdownHook里面加上超时控制。

十三、优雅启动


优雅启动是指不要让应用刚启动成功就接收正常的流量请求,此时应用可能还未完全准备好,容易造成请求超时。常见的做法有启动预热和延迟暴露。启动预热的意思就是让路由策略根据实例注册时间动态调整权重,刚启动的应用缓慢放大流量接收的占比。而延迟暴露则是应用启动完成后通过Hook机制执行预热逻辑后再执行注册上报。

十四、路由分组


稳定性保障中很重要的一点就是自适应保护,比如通过隔离失败保证提供给核心服务的接口可用,更具体的落地方案有路由分组,不同级别的系统调用不同的分组,从而达到隔离的目的。不过对于服务使用者来说,可调用的列表减少了,这种情况下RPC框架最好提供主、备分组的逻辑,当主分组全部不可用后,再使用备分组。

十五、异步调用

客户调调用服务端后直接返回的不再是结果,而是CompletableFuture对象。当客户端收到服务端发送过来的响应之后,RPC框架自动地调用先前的CompletableFuture对象的complete方法,也就是将返回值注入到异步模型中,从而完成异步通知。

十六、RPC安全体系


RPC通信一般为内网服务间通信,所以它的安全问题可以简化为认证授权问题、伪造注册问题。针对前者,我们可以通过授权平台管理调用方列表,申请调用权限通过后生成与其标识相对应的令牌。调用方每次调用时都需要携带这些认证参数,提供方进行Hash校验,通过才放行。而针对伪造注册隐患的解决方案是不允许多个应用同时注册服务。