这是我参与「第五届青训营 」伴学笔记创作活动的第16天。
RPC 框架分层设计
函数调用分类:本地函数调用、远程函数调用。
RPC调用:即远程函数调用,机器间存在距离,由网络连接。
RPC调用需要解决的问题:函数映射、数据转换成字节流(即需要客户端将数据流转换为字节流传递给服务端),网络传输(即通过网络高效稳定地传输数据)。
RPC过程的5个组成模型:User、User-Stub、RPC-Runtime、Server-Stub、Server。
IDL(Interface description language)文件:IDL通过一种中立的方式来描述接口,使得在不同平台上运行的对象和用不同语言编写的程序可以相互通信。进行网络传输的双方需要使用同一份IDL文件。
生成代码:通过编译器工具把IDL文件转换成对应的静态库。
编解码:从内存中表示到字节序列的转换称为编码,也称为序列化。将字节序列转换到内存中称为解码,也称为反序列化。编解码解决了跨编程语言的问题。
通信协议:规范了数据在网络中的传输内容和格式。除了必须的请求/响应数据外,通常还会包含额外的元数据。
网络传输:通常基于成熟的网络库走TCP/UDP传输。
TCP的优点: 可靠,稳定 TCP的可靠体现在TCP在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制,在数据传完后,还会断开连接用来节约系统资源。 TCP的缺点: 慢,效率低,占用系统资源高,易被攻击 TCP在传递数据之前,要先建连接,这会消耗时间,而且在数据传递时,确认机制、重传机制、拥塞控制机制等都会消耗大量的时间,而且要在每台设备上维护所有的传输连接,事实上,每个连接都会占用系统的CPU、内存等硬件资源。 而且,因为TCP有确认机制、三次握手机制,这些也导致TCP容易被人利用,实现DOS、DDOS、CC等攻击。有些应用场景对可靠性要求不高会用到UPD,只能使用TCP,比如长视频,要求速率。
UDP的优点: 快,比TCP稍安全 UDP没有TCP的握手、确认、窗口、重传、拥塞控制等机制,UDP是一个无状态的传输协议,所以它在传递数据时非常快。没有TCP的这些机制,UDP较TCP被攻击者利用的漏洞就要少一些。但UDP也是无法避免攻击的,比如:UDP Flood攻击…… UDP的缺点: 不可靠,不稳定 因为UDP没有TCP那些可靠的机制,在数据传递时,如果网络质量不好,就会很容易丢包。 基于上面的优缺点,那么: 什么时候应该使用TCP: 当对网络通讯质量有要求的时候,比如:整个数据要准确无误的传递给对方,这往往用于一些要求可靠的应用,比如HTTP、HTTPS、FTP等传输文件的协议,POP、SMTP等邮件传输的协议。 在日常生活中,常见使用TCP协议的应用如下: 浏览器,用的HTTP FlashFXP,用的FTP Outlook,用的POP、SMTP Putty,用的Telnet、SSH QQ文件传输 ………… 什么时候应该使用UDP: 当对网络通讯质量要求不高的时候,要求网络通讯速度能尽量的快,这时就可以使用UDP。 比如,日常生活中,常见使用UDP协议的应用如下: QQ语音 QQ视频 TFTP 等。
RPC完整过程
PRC的好处:单一职责,有利于分工协作和运维开发,可扩展性强,资源使用率更优,故障隔离,服务的整体可靠性更高。
分层设计
生成代码
数据格式:语言特定的格式(例如Java.io.Serializable),文本格式(例如JSON、XML、CSV),二进制编码(例如BinaryProtocol、Protobuf)。
二进制编码TLV编码
Tag:标签,可以理解为类型。
Length:长度。
Value:值,也可以是个TVL结构。
编解码层选型:兼容性、通用性、性能。
兼容性:支持自动增加新的字段,而不影响老的服务,者将提高系统的灵活度。
通用性:支持跨平台、跨语言。
性能:编码后数据大小和编码耗费时长。
特殊结束符:一个特殊的字符作为每个协议单元的结束标示。
变长协议:以定长加不定长的部分组成,定长部分需要描述不定长部分的内容长度。
LENGTH:数据包大小,不包含自身。
HEADER MAGIC:标识版本信息,协议解析时候快速校验。
SEQUENCE NUMBER:表示数据包的seqID,可用于多路复用,单连接内地增。
HEADER SIZE:头部长度,从第14个字节开始计算到PAYLOAD前的长度。
PROTOCOL ID:编解码方式,有Binary和Compact两种。
TRANSFORM ID:压缩方式,例如zlib和snappy。
INFO ID:传递一些定制的meta信息。
PAYLOAD:消息体。
协议解析
Sockets API
backload为阻塞长度,Linux默认为128。
RPC 关键指标分析与企业实践
RPC关键指标:稳定性、易用性、扩展性、观测性、高性能。
稳定性保障策略:熔断、限流、超时控制。
熔断:保护调用方,防止被调用的服务出现问题而影响到整个链路。
限流:保护被调用方,防止大流量把服务压垮。
超时控制:避免浪费资源在不可用节点上。
稳定性请求操作:负载均衡、重试。
重试第三次才算是真正的失败。
开箱即用:合理的默认参数选项、丰富的文档。
周边工具:生成代码工具、脚手架工具。
扩展性:Middleware、Option、编解码层、协议层、网络传输层、代码生成工具插件扩展。
高性能场景:单机多机、单连接多连接、单/多client、单/多server、不同大小的请求包、不同请求类型。
高性能目标:高吞吐、低延迟。
高性能手段:连接池、多路复用、高性能编解码协议、高性能网络库。
Kitex整体架构:Kitex Core(核心组件)、Kitex Byted(与公司内部基础设施集成)、Kitex Tool(代码生成工具)。
自研网络库背景:原生库无法感知连接状态,原生库存在goroutine暴涨的风险。
扩展性设计:支持多协议,支持灵活的自定义协议扩展。
网络库优化:调度优化、LinkBuffer、Pool。
编解码优化:Codegen、JIT。
微服务过微,传输和序列化开销越来越大。
合并部署:中心化的部署调度和流量控制,基于共享内存的通信协议,定制化的服务发现和连接池实现,定制化的服务启动和监听逻辑。