本文是对几年前我在公司做的服务框架的梳理 。
本文假设你已经了解了什么是服务化,只阐述针对现有的服务框架所存在的问题,如何根据实际需求去考量并解决对应问题 。
首先,我们先来聊一聊服务框架的核心RPC!
RPCRPC全称是Remote Procedure Call,即远程过程调用 。它和HTTP不是同级的概念 。HTTP是协议,而RPC是一种远程调用方式 。它可以基于HTTP来实现,也可以基于TCP来实现 。
文章插图
乍看之下RPC不就是个客户端调用服务端吗?实际上它确实就是客户端调用服务端而已,只不过,在大部分情况下,RPC在调用时看起来像是在调用本地方法/接口 。
文章插图
注意看上面的Consumer Stub和Provider Stub,这里可以理解为是代理,即
- Consumer和Consumer Stub交互
- Consumer Stub通过RPCLibrary将调用内容序列化,通过网络传输给Provider端
- Provider端反序列化,然后根据传递的内容去调用实际的方法
- 接着再将结果序列化后,通过网络回传给Consumer端
- Consumer端接收到数据后,再反序列化获取到结果,然后进行后续的操作
如下图所示,这里通过Feign定义了一个接口
文章插图
可以直接通过方法调用的方式来调用,看起来和调用普通方法一样没有任何区别 。
文章插图
这里实际上就是进行了上面所述流程的操作,具体的源码流程,可以自行梳理,并不复杂 。如果比较懒,可以等我后面SpringCloud的源码梳理,不过时间未定!
解释完RPC,我们就来看一看服务化框架 。
服务化框架上面所说的RPC还远远达不到框架的程度!
首先,Consumer是需要知道Provider的地址信息的,否则它无法将消息发送给Provider 。这会导致什么问题呢?所有的Consumer都需要维护Provider地址信息 。假设Provider地址信息发生了变化,则所有的Consumer都需要修改对应的配置信息 。
文章插图
其次,Consumer和Provider之间是直连的,假设Provider多了以后,则Consumer与Provider之间的连接将会很多,要人工维护会非常的麻烦 。
文章插图
另外,还有一个问题,Provider地址信息是配置到Consumer中的,那如果Provider挂了该怎么办?如何去除Provider的单点问题呢?
最后,Provider升级后,Consumer该如何处理?
如果你熟悉分布式系统的话,那答案是显而易见的,就是引入注册中心 。
文章插图
- Provider启动后将自己的信息注册到注册中心,注册中心接收到消息后,将新的Provider信息列表推送到已经连接上来的Consumer
- 同时Consumer启动时从注册中心获取Provider注册信息
- Consumer内部实现了负载均衡,通过负载均衡算法,来选择合适的Provider来发送请求
文章插图
实现当初编写这个服务框架实际上是为了解决几个问题:
- 一般服务框架的升级问题
- 服务元数据管理问题
- 模块化服务开发
一般服务升级可以分为两种情况:
- 服务修改保持兼容,也就是说接口不变,实现改变 。
- 另外一种情况是服务修改不兼容,即接口也改变了 。
文章插图