RPC框架设计与分析

学习网址:https://juejin.cn/course/bytetech/7142811324462923783/section/7142809631831228429

一、RPC框架分层实现

1、基本概念

远程函数调用(RPC-remote Procedure Calls),例如网上商城服务和支付服务部署在不同的机器上,中间隔着网络。

RPC需要解决的问题

1、函数映射 -- 网上商城如何告诉支付服务要调用付款这个服务

2、数据转换成字节流 -- 网上商城如何把参数告诉远程

3、网络传输 -- 怎么在网络上高效稳定的传输数据

RPC概念模型:

RPC的过程由5个模型组成,User、User-Stub、Server、Server-Stub、RPC-Runtime

RPC调用过程:

Caller machine指的是调用端,Callee machine指的是被调用端,首先User模块发起一个本地调用,调用User-Stub,将参数打包,打包后交给RPC Runtime,RPC Runtime把数据传送给对端,接收后交给Server-Stub解压数据,之后调用真正的业务逻辑server,server处理完逻辑之后,返回,返回的时候将返回结果打包,再通过网络传输到对端的RPC-Runtime,User-Stub将数据解压出来,再返回。

一次RPC的完整过程:

相关概念:

(1)IDL文件

相对于本地函数调用,我们不知道远程函数有什么方法,也不知道参数是什么样的,所以需要一种方式描述和声明有哪些方法,有哪些参数,按照约定来调用,约定的描述文件叫做IDL文件。

IDL通过一种中立的方式来描述接口,使得在不同平台上的对象和不同语言编写的程序可以相互通信。

(2)生成代码

通过约定的规范进行调用的,双方依赖于相同的IDL文件,需要相应的工具生成代码,在具体调用的时候用户代码直接依赖生成代码,可以把用户代码和生成代码看成一个整体。 

(3)编解码

从内存中表示到字节序列的转换称为编码,反之为解码,解决了跨语言的数据交互格式。

(4)通信协议

规范数据在网络中的传输内容和格式,除了携带必须的请求或响应的数据外,通常还会包含额外的元数据。

(5) 网络传输

基于成熟的网络库走TCP/UDP传输。

RPC的好处:

1、单一职责,有利于分工协作和运维开发,部署,运维独立,不同的服务采用不同的语言开发。

2、可扩展性更强,资源使用率更优,压力大时,可独立的扩充资源,针对性扩容,底层资源可以复用。

3、故障隔离,服务的整体可靠性更高

RPC的弊端(通过RPC框架来处理):

1、服务宕机,对方应如何处理?

2、在调用的过程中可能发生网络异常,如何保证消息的可达性?

3、请求量突增导致服务无法及时处理,有什么应对措施?

2、分层设计

编解码层、协议层、网络通信层

分层设计:

 编解码层 ---- 生成代码

数据格式:

(1)语言特定的格式,许多编程语言内建了将内存对象编码为字节序列的支持,与特定的编程语言绑定,其他语言无法读取数据,兼容性低。

(2)文本格式

具有人类可读性,JSON,XML,CSV等文本格式,描述可能不严谨,会存在缺陷,JSON可以区分字符串和数组,但无法区分整数和浮点数,也不能指定精度。JSON编解码的实现采用反射的机制,性能差。

(3)二进制编码

具有跨语言和高性能等特点,常见的右Thrift的BinaryProtocol,protobuf等,TLV编码 。

编解码层 - 选型

兼容性:支持增加新的字段,而不影响老的服务,提高系统的灵活性。

通用性:跨平台、跨语言

性能:从时间和空间两个维度来考虑,编码后数据的大小和编码耗费时长。

协议层

编解码层只是将数据转换成字节流,但并不是将字节流直接打包发送给对方,还需要特定的通信协议,添加一些元数据。

特殊结束符:需要有一个标志位,常见的是HTTP协议。

LENGTH:数据包大小,不包含自身。

HEADER MAGIC:解析协议的版本信息,知道这是什么类型的协议。

SEQUENCE NUMBER:数据包的seqID,在单连接内递增,适合于多路复用(在一个连接内可以有多个请求流,肯定要表示seqID)。

HEADER SIZE:从第十四个字节到payload前整个都是头部。

 对协议进行解析:

首先从内存中读取指定的部分,先读取magic number所在的位置,知道是什么类型的协议,再读取编解码的方式,再把解出来 。

网络通信层

网络之间的通信通过socket API,操作系统提供的sockets API位于应用层和传输层之间。首先在sockets编程的时候必须要知道两个信息,IP和端口,sockets创建一个套接字,首先会有一个bind操作,将套接字绑定到IP+端口上,再去监听进来的连接,放到一个队列里面,队列可能由于满了发生阻塞,需要等到队列清空再放进去,队列有一个长度规定backlog,linux默认的长度规定是128,之后是accept,在客户端发起connect请求的时候,接收连接的请求,没有请求的时候就会一直阻塞等待连接进来,调用read,write读写进行通信。

使用封装好的网络库作为RPC框架的网络通信层需要满足:

1、提供易用API,封装底层Sockets API,对连接进行管理,对可读,可写事件进行分发。

2、功能,协议支持UDP,TCP,UDS等,优雅退出,对底层的异常进行处理。

3、性能,通过应用层的buffer减少copy,高性能的定时器,对象池         

3、关键指标

稳定性、易用性、扩展性、观测性、高性能

稳定性 -- 保障策略

保障策略主要有三种:

熔断:服务A调用服务B,服务B调用服务C,服务C响应超时,导致B一直等待,返回给A就是超时的,A就会频繁的调用服务B,因为频繁堆积的请求导致服务B宕机,就会产生服务雪崩 。

保护调用方,防止被调用的服务出现问题影响到整个链路。

限流:保护被调用方,防止大流量把服务压垮。

超时控制:避免资源浪费在不可用的节点上。被调用端可能由于某种原因响应过慢,调用端会停止一些不必要的请求,快速的返回,及时释放资源,避免资源浪费在不可调用的服务上。

稳定性 -- 请求成功率

负载均衡(服务A均匀调用服务B的节点)、重试(多试几次可能就好了)

 稳定性 -- 长尾请求

明显高于平均响应时间的占比比较小的那一部分请求

 提高长尾请求的请求成功率,通过backup  request 

稳定性 -- 注册中间件

无论是client还是server,创建的时候都可以通过options的方式将这些可选的方式加上,灵活的注入稳定性策略,保证请求的稳定。

 易用性

开箱即用,提供合理的默认配置,提供丰富的文档(遇到问题解决)

周边工具:生成代码工具(辅助用户更好的使用框,IDL生成代码工具)、脚手架工具(生成一些重复的代码)

RPC框架会有一个suite提供熔断、限流、降级等基本的功能。 

扩展性

编解码层:支持不同的编解码

协议层:支持尽可能多的RPC通信协议

网络传输层:支持不同的网络库

中间件的执行流程:request会分别经过middleware1,2,n后才会真正的将请求发送到远端,负载均衡,超时控制都是通过中间件的方式加一些策略的。 

观测性

RPC在运行过程中相对于用于来说是一个空盒,不知道服务现在是什么状况

传统的三件套:Log(日志)、Mrtric(监控)、Tracing(跟踪,知道在那个阶段超时,往往会携带ID,通过ID将整个链路串起来。)

RPC框架有内置观测性服务,框架内部的配置是什么,运行过程中环境变量是什么,运行过程中的线程有多少,协程有多少,使用了哪些中间件,都需要框架主动的暴露出来。

高性能

目标:高吞吐(在单位时间内尽可能处理多的请求)、低延迟(发出请求返回时间尽可能的短)

场景:单机多机、单连接多连接、不同大小的请求包、不同请求类型(不是简单的发送一个请求返回一个响应,一个请求多个响应)、单/多 client ,单/多 server

手段:连接池、多路复用(提高连接的复用率,减少重复创建消费连接的开销)、高性能编解码协议、高性能网络库

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值