RPC核心原理

什么是RPC

当一个系统并的庞大的时候就会对服务进行拆分。假如一个电商系统就会给拆分为用户服务,订单服务,商品服务等。而在给用户提供服务的时候这些服务之间经常会需要协作,需要传递一些数据。有很多种解决方案,而RPC是一种使用非常广的方案。
一句话概括,RPC就是一种解决服务之间协作,用来传递消息的一种技术方案。

RPC通信流程

RPC分为服务提供方和服务调用方。 服务提供方和服务消息方之间传递信息需要通过网络传递。网络中传递信息都是二进制的,因此我们需要在服务提供方将java对象转换成二进制文件,在通过网络传递到服务提供方,服务提供方将二进制文件转换成java对象来进行数据处理。这个将java对象转成二进制叫做序列化,将二进制转成java对象的过程就叫做反序列化。

在这里插入图片描述

RPC中的协议

在数据序列化的过程中,是需要使用协议的。因为服务之间序列化的技术有很多种,如JSON,thrift等等, 服务需要知道使用是哪种技术来将二进制数据转换成java对象。
我们可能还会在协议中放协议长度,协议标示,消息ID,消息类型等等参数。因此我们可以将协议设计成以面的这种方式。
在这里插入图片描述
图中说的魔术位是指这是什么协议,如DUBBO,HTTP,REDIS等等协议。

下图是传递过程
在这里插入图片描述

RPC中的网络通信技术

在服务调用方和服务提供方之间会建立一个长连接,而在java中处理长连接的较好方式就是使用NIO多路复用,java原生的NIO的API并不是很友好,因此大多数的RPC都是采用的netty来实现的。 netty就是对nio进行了封装。

服务之间传输的二进制文件有可能不是一次性传输完成的,因此就需要多次接收然后在拼接。 这个过程是在应用的内存空间进行的,这有可能会造成数据的多次移动,复制等等操作,浪费了服务器资源。 因此netty使用了零拷贝技术。大体过程如下:
在这里插入图片描述

RPC中的动态代理

在我们使用RPC的时候会发现他和普通的接口使用方式是一样的,由其是在配合spring的时候。都是注入一个接口bean然后直接调用方法。 这背后的原理就是动态代理。 RPC会自动给接口生成一个代理类,项目运行过程中实际绑定的是这个接口生成的代理类。这样在接口方法被调用的时候, 它实际上就会被拦截到。这样就可以在生成的代理类中添加远程调用逻辑了。

大家可以看下图,图分两部分, 上部分为开发人员的视角,下部分为rpc的视角。
在这里插入图片描述
动态代理的实现技术有很多,JDK原生就有动态代理。当然也可以使用别的技术如:Byte Buddy。

RPC的架构设计

RPC的架构图
在这里插入图片描述
在这里插入图片描述
主要分为可以扩展和不可扩展的。可扩展的是将所以功能插件化。dubbo也是插件化的,对java自带的插件机制进行了扩展,让其可以自动注入依赖类。

RPC使用的服务发现

注册中心的作用

服务的调用方和服务提供方有可能不是在一台机子上,也有可能一个服务调用方会调用多个服务提供方,那服务调用方怎么获取服务提高方的地址来发起调用呢? 这个时候就需要有注册中心了。

服务注册:在服务提供方启动的时候,将对外暴露的接口注册到注册中心之中,注册中心将这个服务节点的IP和接口保存下来。

服务订阅:在服务调用方启动的时候,去注册中心查找并订阅提供方的IP,然后缓存到本地,并用于后续的远程调用。

在这里插入图片描述

注册中心选择

使用zookeeper做为注册中心一种选择比较广泛的应用,zk+dubbo很多公司都会这么使用。
zk搭建的注册中心集群是强一制性的,就是CP,如果master节点出现问题,集群会重新选举出一个master节点,在这其间集群是没有办法使用的。不能接受请求。

zookeeper除了做为注册中心使用还是可以做为配置中心使用的。
zookeeper还可以实现分布式锁。
zookeeper还是hadoop生态圈中的重要一员。

使用eureka也是一个种选择,他是最终一至性的集群(AP)。 是用java语言写的, 分为服务端和客户端, 有自我保护功能, 如果在短时间内,发现很多节点都无法心跳检查,他会怀疑是网络问题,就不会在注册中心把注册的服务删除掉。 服务调用方可以正常调用。

现在更流程第二种方式,使用最终一致性来做为注册中心。

RPC的健康检查

这里的健康检查是指心跳机制,RPC的服务调用方和服务提供方会建议长连接,调用方会订时给提供方发送请求,查看调用方的状态。

调用方会计算出一个可用率,这个可用率低于一定的值时就会将这个服务提供方的地址在自己的内存中标记为不可用。 调用方会隔一段时间在次检查这个地址, 如果可用率达到标准就会调整为正常状态。 否则进入死亡状态。
可用率的计算是某一个时间窗口内接口调用成功次数的百分比(成功次数/总调用次数)

在这里插入图片描述

RPC中的路由选择

RPC内部可以配置规则, 调用方发起请求的时候,可以根据请求参数的规则来判断选择哪一个提供方。
可以通过注册中心将规则下发到调用方。 在这里插入图片描述
RPC路由功能的一个典型应用场景就是灰度发布,我们可以通过路由功能完成定点调用,黑名单白名单等等功能。

RPC中的负载均衡

RPC中的负载均衡是放在调用方的,每一次发起RPC调用,服务调用者都会通过配置的负载均衡插件,自主选择一个服务节点,发起RPC调用。
在这里插入图片描述

RPC调用方会有一个打分机制, 通过心跳机制将调用方的系统的基础信息获取到。如负载指标 ,CPU核心数,内存大小,请求处理的耗时,节点的健康状态等等。根据这些信息就可以判断选择一个调用方。还可以一个百分比的值, 得分高的就分配流量多一些,得分低的就分配流量低一些,还可以单纯的随机,轮循。
在这里插入图片描述

RPC中的异常重试

RPC的异常重试功能仍然是在调用方实现的,用户可以自行设置是否开启重试以及重试次数。
在这里插入图片描述
RPC会捕捉特定的异常,如:网络超时异常,网络连接异常等等。一定捕捉了这个异常就会重新调用请求。 当然,服务提供方的接口一定要做好幂等性,哪果没有做好幂等性就会造成脏数据。
RPC还有一个请求超时的概念,如果服务提供方的接口性能特别慢,虽然可以影响但是超过时间了RPC的调用方也不会等待而是直接返回一个请求超时的异常。

如果我们把请求超时时间设置为5s,请求重试次数是3次,每一次都耕时两秒,是不是会导致请求超时,虽然第三次可以正常返回结果,但是服务调用方仍然会返回一个超时异常。
为了解决这个问题, 我们可每一次重试的时候都会把这次请求的时间重置为0。 也就是说请求超时时间计算的请求成功的一次时间,而不是重试的所有请求的时间。

RPC关闭服务

RPC在关闭服务的时候,是不可以直接强制关闭的,因为如果有还没有处理完的请求还需要处理完,同时不能在接受新的请求了。 Runtime.addShutdownHook方法。
下面这个图就是关闭服务的流程,不只是RPC的关闭流程是这样的, 一些中间件如消息队列和缓存的关闭流程大体都是这样的。
在这里插入图片描述

一般实现这种功能的方式都是使用java自带的关闭服务的勾子。

RPC启动流程

有一个叫做启动预热的概念:简单来说,就是让刚启动的服务提供方的流程减少,被调用的次数随着时间增加慢慢增长到正常值。

RPC调用方可以通过注册中心拿到服务提供方的注册时间,然后根据这个启动时间来计算一个权重,刚刚启动的时候流量低。这个实现可以添加到负载均衡当中。也可以独立出来。
在这里插入图片描述

如果RPC和spring一起使用的时候,也许会发现启动的速度会有一些慢, 如果这个时间先启动了rpc,就会信息注册到注册中心了,就会接到请求。实际上这个时候spring还没有完成启动, 这个时候就需要延时暴露,只有当服务完成启动的时候才会将信息注册到注册中心。

我们可以在服务提供方应用启动后,接口注册到注册中心前,预留一个Hook过程 ,让用户可实现可扩展的Hook逻辑。用户可以在Hook里面模拟调用逻辑,从而使用jvm指令能够预热起来。并且启用可以在Hook里面事先预加载一些资源。只有等资源都加载完成后,最后才把接口注册到注册中心。
在这里插入图片描述

引用

以上内容为极客时间《RPC实战与核心原理》的学习所得。

交个朋友好吗?

以上内容均为读书所得, 更多有趣有料的科技资讯请关注公众号。(交个朋友)
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Netty是一个基于NIO的高性能网络通信框架,它的核心原理是通过事件驱动和异步处理机制来实现高效的网络传输。其特点是可扩展、可重用、易于维护、性能卓越。 RPC(Remote Procedure Call)是一种基于网络通信的分布式计算模型,通过这种模型,客户端调用服务端的远程方法就像调用本地方法一样简单。在RPC实践过程中,使用Netty框架可以有效提升RPC的性能和稳定性。 Netty的核心原理是基于事件驱动的模型,它的主要组成部分包括NioEventLoop、Channel、Buffer、Codec等。NioEventLoop是Netty中的核心组件之一,它是一个事件循环线程,通过不断遍历注册在它上面的Channel监听器,来处理网络传输过程中的事件,从而实现网络的异步非阻塞传输。 在RPC实践中,Netty通过对协议进行编解码,来实现远程方法的调用和响应过程。通常情况下,客户端与服务端之间需要使用一种协议来进行通信,需要对协议进行编解码处理,这个过程需要在客户端和服务端都实现一遍,使用Netty框架可以简化这个过程,使得开发人员只需要实现协议的编解码策略即可。 总之,Netty作为高性能网络通信框架,其核心原理是基于事件驱动的机制实现的。在RPC实践中,Netty可以高效地实现协议的编解码,提升RPC的性能和稳定性,因此在分布式计算中得到了广泛的应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值