RPC 核心,万变不离其宗(下)

简介: RPC 核心,万变不离其宗(下)

所以协议其实就定义了到底如何构造和解析这些二进制数据。

我们的参数肯定比上面的复杂,因为参数值长度是不定的,而且协议常常伴随着升级而扩展,毕竟有时候需要加一些新特性,那么协议就得变了。

一般 RPC 协议都是采用协议头+协议体的方式。

协议头放一些元数据,包括:魔法位、协议的版本、消息的类型、序列化方式、整体长度、头长度、扩展位等。

协议体就是放请求的数据了。

通过魔法位可以得知这是不是咱们约定的协议,比如魔法位固定叫 233 ,一看我们就知道这是 233 协议。

然后协议的版本是为了之后协议的升级。

从整体长度和头长度我们就能知道这个请求到底有多少位,前面多少位是头,剩下的都是协议体,这样就能识别出来,扩展位就是留着日后扩展备用。

贴一下 Dubbo 协议:


image.png


可以看到有 Magic 位,请求  ID, 数据长度等等。


网络传输


组装好数据就等着发送了,这时候就涉及网络传输了。

网络通信那就离不开网络 IO 模型了。

image.png


网络 IO 分为这四种模型,具体以后单独写文章分析,这篇就不展开了。

一般而言我们用的都是 IO 多路复用,因为大部分 RPC 调用场景都是高并发调用,IO 复用可以利用较少的线程 hold 住很多请求。

一般 RPC 框架会使用已经造好的轮子来作为底层通信框架。

例如 Java 语言的都会用 Netty ,人家已经封装的很好了,也做了很多优化,拿来即用,便捷高效。


小结


RPC 通信的基础流程已经讲完了,看下图:


image.png


响应返回就没画了,反正就是倒着来。

我再用一段话来总结一下:

服务调用方,面向接口编程,利用动态代理屏蔽底层调用细节将请求参数、接口等数据组合起来并通过序列化转化为二进制数据,再通过 RPC 协议的封装利用网络传输到服务提供方。

服务提供方根据约定的协议解析出请求数据,然后反序列化得到参数,找到具体调用的接口,然后执行具体实现,再返回结果。

这里面还有很多细节。

比如请求都是异步的,所以每个请求会有唯一 ID,返回结果会带上对应的 ID, 这样调用方就能通过 ID 找到对应的请求塞入相应的结果。

有人会问为什么要异步,那是为了提高吞吐。

当然还有很多细节,会在之后剖析 Dubbo 的时候提到,结合实际中间件体会才会更深。


真正工业级别的 RPC


以上提到的只是 RPC 的基础流程,这对于工业级别的使用是远远不够的。

生产环境中的服务提供者都是集群部署的,所以有多个提供者,而且还会随着大促等流量情况动态增减机器。

因此需要注册中心,作为服务的发现。

调用者可以通过注册中心得知服务提供者们的 IP 地址等元信息,进行调用。

调用者也能通过注册中心得知服务提供者下线。

还需要有路由分组策略,调用者根据下发的路由信息选择对应的服务提供者,能实现分组调用、灰度发布、流量隔离等功能。

还需要有负载均衡策略,一般经过路由过滤之后还是有多个服务提供者可以选择,通过负载均衡策略来达到流量均衡。

当然还需要有异常重试,毕竟网络是不稳定的,而且有时候某个服务提供者也可能出点问题,所以一次调用出错进行重试,较少业务的损耗。

还需要限流熔断,限流是因为服务提供者不知道会接入多少调用者,也不清楚每个调用者的调用量,所以需要衡量一下自身服务的承受值来进行限流,防止服务崩溃。

而熔断是为了防止下游服务故障导致自身服务调用超时阻塞堆积而崩溃,特别是调用链很长的那种,影响很大。

比如A=>B=>C=>D=>E,然后 E 出了故障,你看ABCD四个服务就傻等着,慢慢的资源就占满了就崩了,全崩。

image.png


大致就是以上提到的几点,不过还能细化,比如负载均衡的各种策略、限流到底是限制总流量还是根据每个调用者指定限流量,还是上自适应限流等等。

这个在之后分析 Dubbo 的时候都会提到,等着哈。


最后


我之前面过一个同学,两年经验,简历写着熟悉 Spring Cloud Alibaba 然后了解 Dubbo 。

我问他 RPC 的调用原理,他问我什么是 RPC,没听过这个名词。

这就太浮在表面了。

理解原理还是很重要的,像我上面提到的动态代理也不是一定是要的,像 C++ 就没有动态代理, gRPC 框架用的是代码生成。

反正最终只要能屏蔽调用细节,不需要使用者关心即可,至于用什么方式达到这个目的,影响不大。

还有上面提到面向接口,其实有时候就是没接口,例如一些服务网关,暴露出 HTTP 调用的方式给调用者来调用后端 RPC 服务。


image.png


网关是要接入很多后端服务的,所以不可能依赖后端的接口,不然就不灵活了。

这里就有个泛化调用的概念。

其实只要你理解了请求方无非就是告知服务提供方我要调哪个方法,参数都是哪些,你就能很容易的理解什么叫泛化调用。

也就能理解其实不需要接口我们也能进行 RPC 调用。

具体泛化调用是什么之后写  Dubbo 会提到。

所以听起来好像很高级的玩意,如果你理解了本质,其实也就这么点东西。

万变不离其宗。


相关文章
|
JSON 网络协议 Dubbo
RPC框架(技术总结)
RPC框架(技术总结)
RPC框架(技术总结)
|
24天前
|
自然语言处理 负载均衡 API
gRPC 一种现代、开源、高性能的远程过程调用 (RPC) 可以在任何地方运行的框架
gRPC 是一种现代开源高性能远程过程调用(RPC)框架,支持多种编程语言,可在任何环境中运行。它通过高效的连接方式,支持负载平衡、跟踪、健康检查和身份验证,适用于微服务架构、移动设备和浏览器客户端连接后端服务等场景。gRPC 使用 Protocol Buffers 作为接口定义语言,支持四种服务方法:一元 RPC、服务器流式处理、客户端流式处理和双向流式处理。
|
1月前
|
自然语言处理 Dubbo Java
RPC基础
RPC基础
38 0
|
1月前
|
网络协议 算法
RPC为何比较高效?
RPC为何比较高效?
58 0
|
4月前
|
分布式计算 负载均衡 数据安全/隐私保护
什么是RPC?有哪些RPC框架?
RPC(Remote Procedure Call,远程过程调用)是一种允许运行在一台计算机上的程序调用另一台计算机上子程序的技术。这种技术屏蔽了底层的网络通信细节,使得程序间的远程通信如同本地调用一样简单。RPC机制使得开发者能够构建分布式计算系统,其中不同的组件可以分布在不同的计算机上,但它们之间可以像在同一台机器上一样相互调用。
160 8
|
6月前
|
Dubbo 网络协议 Java
性能基础之常见RPC框架浅析
【4月更文挑战第23天】性能基础之常见RPC框架浅析
252 1
性能基础之常见RPC框架浅析
|
存储 搜索推荐 API
如何设计 RPC 接口
如何设计 RPC 接口
246 0
|
消息中间件 XML JSON
一文就读懂RPC远程调用核心原理
rpc的全称是Remote Procedure Call,即远程过程调用,是分布式系统的常用通信方法。 Remote,简单来说的话就是两个不同的服务之间,两个服务肯定是两个不同的进程。因此,我们就从跨进程进行访问的角度去理解就行了。 Procedure,意思是一串可执行的代码,我们写Java的方法,就是一段课程行的代码。 Call,即调用,调用的就是跨了进程的方法。
376 0
一文就读懂RPC远程调用核心原理
|
数据采集 网络协议 算法
RPC框架整体架构
RPC就是把拦截到的方法参数,转成可以在网络中传输的二进制,并保证在服务提供方能正确地还原出语义,最终实现像调用本地一样地调用远程的目的。
240 0
|
缓存 运维 监控
下一篇
无影云桌面