从RPC到服务化框架

本文是对几年前我在公司做的服务框架的梳理 。
本文假设你已经了解了什么是服务化,只阐述针对现有的服务框架所存在的问题,如何根据实际需求去考量并解决对应问题 。
首先,我们先来聊一聊服务框架的核心RPC!
RPCRPC全称是Remote Procedure Call,即远程过程调用 。它和HTTP不是同级的概念 。HTTP是协议,而RPC是一种远程调用方式 。它可以基于HTTP来实现,也可以基于TCP来实现 。

从RPC到服务化框架

文章插图
 
乍看之下RPC不就是个客户端调用服务端吗?实际上它确实就是客户端调用服务端而已,只不过,在大部分情况下,RPC在调用时看起来像是在调用本地方法/接口 。
从RPC到服务化框架

文章插图
 
注意看上面的Consumer Stub和Provider Stub,这里可以理解为是代理,即
  • Consumer和Consumer Stub交互
  • Consumer Stub通过RPCLibrary将调用内容序列化,通过网络传输给Provider端
  • Provider端反序列化,然后根据传递的内容去调用实际的方法
  • 接着再将结果序列化后,通过网络回传给Consumer端
  • Consumer端接收到数据后,再反序列化获取到结果,然后进行后续的操作
一个具体的例子可以看SpringCloud套件中Feign的使用 。
如下图所示,这里通过Feign定义了一个接口
从RPC到服务化框架

文章插图
 
可以直接通过方法调用的方式来调用,看起来和调用普通方法一样没有任何区别 。
从RPC到服务化框架

文章插图
 
这里实际上就是进行了上面所述流程的操作,具体的源码流程,可以自行梳理,并不复杂 。如果比较懒,可以等我后面SpringCloud的源码梳理,不过时间未定!
解释完RPC,我们就来看一看服务化框架 。
服务化框架上面所说的RPC还远远达不到框架的程度!
首先,Consumer是需要知道Provider的地址信息的,否则它无法将消息发送给Provider 。这会导致什么问题呢?所有的Consumer都需要维护Provider地址信息 。假设Provider地址信息发生了变化,则所有的Consumer都需要修改对应的配置信息 。
从RPC到服务化框架

文章插图
 
其次,Consumer和Provider之间是直连的,假设Provider多了以后,则Consumer与Provider之间的连接将会很多,要人工维护会非常的麻烦 。
从RPC到服务化框架

文章插图
 
另外,还有一个问题,Provider地址信息是配置到Consumer中的,那如果Provider挂了该怎么办?如何去除Provider的单点问题呢?
最后,Provider升级后,Consumer该如何处理?
如果你熟悉分布式系统的话,那答案是显而易见的,就是引入注册中心 。
从RPC到服务化框架

文章插图
 
  • Provider启动后将自己的信息注册到注册中心,注册中心接收到消息后,将新的Provider信息列表推送到已经连接上来的Consumer
  • 同时Consumer启动时从注册中心获取Provider注册信息
  • Consumer内部实现了负载均衡,通过负载均衡算法,来选择合适的Provider来发送请求
服务框架的功能上图的Consumer,Provider和Registry实际上就是一个服务框架所需要的三个必要组件 。而一个较为完善的服务框架,需要至少提供如下功能:
从RPC到服务化框架

文章插图
 
实现当初编写这个服务框架实际上是为了解决几个问题:
  • 一般服务框架的升级问题
  • 服务元数据管理问题
  • 模块化服务开发
我们从「服务升级」这个场景开始!服务升级应该算是服务化里最基本的功能了,我们以dubbo为例,看看使用dubbo框架的情况下,如何进行服务升级?
一般服务升级可以分为两种情况:
  • 服务修改保持兼容,也就是说接口不变,实现改变 。
  • 另外一种情况是服务修改不兼容,即接口也改变了 。
我们先看第一种情况,当服务保持兼容的情况下,我们的升级流程大致是什么样的!以下图为例,我们有三个服务节点和两个客户端:
从RPC到服务化框架

文章插图