RPC调用过程

RPC调用过程

RPC五大核心组成

  • server(provider) :服务提供者
  • server-stub(provider-stub) :服务端的本地存根。进行类型和参数转换,“翻译员”
  • user(consumer):服务消费者
  • user-stub(consumer-stub) :消费端的本地存根
  • RPCRuntime:RPC通信者。负责传输数据包,服务端/消费端均存在一个RPCRuntime,负责两边的通信image-20230923122825047

完整的RPC中隐藏了许多细节,比方服务发现、序列化等等。RPC框架则能屏蔽这些细节,让使用者无感地调用RPC

RPC框架的主要问题

  • 服务发现:各服务如何互知对方地址(注册中心)
  • 通讯协议:调用方和服务方如何通信(TCP/HTTP)
  • 序列化:通信消息如何解压缩(文本型Json/XML;二进制型)
  • 代理:调用方如何像调用本地API一样无感调用RPC

服务发现

服务可以通过固定的IP或者DNS域名解析来发现其他服务的地址,但这些除扩展性差外,对服务上下线状态也不敏感
注册中心的服务注册表可以记录各个微服务实例的信息,服务启动时主动将信息注册到服务中心,用于调用方查询,同时提供服务检查,如果心跳探测不到实例则会将服务移出注册表

注意,注册中心只提供服务发现功能,并不转发客户端的调用请求

通讯协议

gRPC采用HTTP2协议,Dubbo采用TCP协议。
传输数据格式有文本格式如JSON、XML;也有二进制格式如JDK原生序列化。二进制方式数据包小,传输速率块,但对于异构型语言并不友好,主要因为二进制不好被反编码到其他语言。

(NOTE) 异构型语言解决方案

  • 规定各语言以相同的机制序列化,如Hession、Json
  • 采用IDL作为标准描述语言,如Thrift、ProtoBuf

路由

  • 测试场景下,客户端的测试实例需要路由到特定服务实例上
  • 流量隔离场景下,将流量隔离到不同服务实例上
  • 灰度发布时,新服务只会接受少量的请求
  • 路由规则由注册中心下发给客户端

负载均衡算法

 轮询算法:按照服务节点列表的顺序轮流发送请求
 随机算法:随机选取服务节点中的一个服务节点发送请求
 加权随机算法:按权重随机服务节点,权重大的被选中概率更大
 最少活跃数算法:对每个服务节点设置活跃数,每发送一个请求活跃数加1,每完成一个请求活跃数减1,服务运行一段时间后,性能相对较高的节点处理请求更快,活跃数下降得快,因此消费者只需要选择活跃数最小的节点发送请求
 一致性hash算法:使用hash计算,尽可能将请求均匀分配到后端服务,并且同一个用户的请求总
是访问到同一个服务器

熔断机制

 服务实例在一段时间内出现故障导致响应过慢或者出现错误过多,实例就会被熔断
 服务中某个实例被熔断后,调用者的请求会被转发给剩余正常的实例

优雅启动和优雅宕机

在微服务架构中,服务的频繁上下线,系统的扩缩容都是常见现象,这些现象发生时应当对整个系统是无损的

优雅启动

新服务完全启动后,通过Hook自动将信息发布到注册中心。新服务还不能承担全体流量。应随着时间的增加逐渐提升自身权重,最后与旧服务持平。

优雅宕机

宕机时先在注册中心注销,不被客户端发现。随后处理完已接受的请求,再关闭服务。期间如果有新请求则返回错误码,让客户端转发到其他客户端重试

gRPC

HTTP2

HTTP/1.x的性能存在问题,主要因为同一连接同一时间只能处理一个请求,其他请求的多数时间浪费在了阻塞等待上。

image-20230923122806232

HTTP/1.1管道化解决了请求的阻塞问题,但队头阻塞依然存在,且返回也要按照请求顺序,否则会被阻塞。

image-20230923122748588

HTTP/2以流的方式分组,能够多路复用同一个TCP连接。

image-20230923122737388

protobuf

protobuf支持多语言,在使用前通过预先定义的Schema来下序列化各种语言代码,保证传输出去的数据包格式一致。
protobuf工作时,先将.proto“一式两分”地转为客户端存根供客户端调用,另一个作为服务基类嵌入服务器中。此后,客户端直接调用存根即可调用启用服务,就像是调用本地API一样。

image-20230923122727281

RPC模式

  • 一元RPC:一次请求对应一次响应
  • 服务端流模式:一次请求,服务器返回连续的数据流
  • 客户端流模式:客户端源源不断发送数据流,而在发送结束后,服务端返回一个响应
  • 双向流模式:客户端与服务端都可以向对方发送数据,实现实时交互

gRPC缺点

  • 不提供服务发现、负载均衡

  • protobuf可读性差

  • 不支持动态Schema


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!