这是我参与「第五届青训营」伴学笔记创作活动的第 8 天
本节课主要介绍:
一、基本概念
1.1本地函数调用
func main(){
var a 2
var b =3
result calculate(a,b)
fmt.Println(result)
return
}
func calculate(x,y int){
Z :x*y
return Z
}
1.将a和b的值压栈
2.通过函数指针找到calculate函数,进入函数 取出栈中的值2和3,将其赋予x和y
3.计算×*y,并将结果存在Z
4.将Z的值压栈,然后从calculate返回
5.从栈中取出z返回值,并赋值给result
1.2远程函数调用(RPC-Remote Procedure Calls)
RPC需要解决的问题
1.函数映射
2.数据转换成字节流
3.网络传输
函数映射:
在本地调用中,函数体是直接通过函数指针来指定的,我们调用哪个方法,编译器就自动帮我们调用它相应的函数指针。但是在远程调用中,函数指针是不行的,因为两个进程的地址空间是完全不一样的。所以函数都有自己的一个D,在做RPC的时候要附上这个ID,还得有个ID和函数的对照关系表,通过ID找到对应的函数并执行。
客户瑞把参数值传给远程的函数:
在本地调用中,我们只需要把参数压到栈里,然后让函数自己去栈里读就行。但是在远程过程调用时,客户端跟服务端是不同的进程,不能通过内存来传递参数。这时候就需要客户端把参数先转成一个字节流,传给服务端后,再把字节流转成自己能读取的格式。
1.3RPC概念模型
论文提出RPC的过程由5个模型组成:User、User-Stub、RPC-Runtime、Server-Stub、Server
二、分层设计
2.1分层设计-以Apache Thrift为例
2.2编解码层
2.7协议层
2.11网络通信层
2.3编解码层-生成代码
2.4编解码层-数据格式
1.语言特定的格式
许多编程语言都内建了将内存对象编码为字节序列的支持,例如Java有java.io.Serializable
2.文本格式
JSON、XML、CSV等文本格式,具有人类可读性
3.二进制编码
具备跨语言和高性能等优点,常见有Thrift的BinaryProtocol,Protobuf等
2.5编解码层-二进制编码
TLV编码 -Tag:标签,可以理解为类型 -Lenght:长度 -Value:值,Value也可以是个TLV结构
2.6编解码层-选型
1.兼容性
移动互联时代,业务系统需求的更新周期变得更快,新的需求不断涌现,而老的系统还是需要继续维护。如果序列化协议具有良好的可扩展性,支持自动增加新的业务字段,而不影响老的服务,这将大大提供系统的灵活度。
2.通用性
通用性有两个层面的意义: 第一、技术层面,序列化协议是否支持跨平台、跨语言。如果不支持,在技术层面上的通用性就大大降低了。 第二、流行程度,序列化和反序列化需要多方参与,很少人使用的协议往往意味着昂贵的学习成本;另一方面,流行度低的协议,往往缺乏稳定而成熟的跨语言、跨平台的公共包。
3.性能
第一、空间开销,序列化需要在原有的数据上加上描述字段,以为反序列化解析之用。如果序列化过程引入的额外开销过高,可能会导致过大的网络,磁盘等各方面的压力。对于海量分布式存储系统,数据量往往以TB为单位,巨大的的额外空间开销意味着高昂的成本. 第二、时间开销,复杂的序列化协议会导致较长的解析时间,这可能会使得序列化和反序列化阶段成为整个系统的瓶颈。
2.8协议层-概念
1.特殊结束符 一个特殊字符作为每个协议单元结束的标示 2.变长协议 以定长加不定长的部分组成,其中定长的部分需要描述不定长的内容长度
2.9协议层-协议构造
LENGTH:数据包大小,不包含自身 HEADER MAGIC:标识版本信息,协议解析时 候快速校验 SEQUENCE NUMBER:表示数据包的seqID 可用于多路复用,单连接内递增 HEADER SIZE:头部长度,从第14个字节开始 计算一直到PAYLOAD前 PROTOCOL ID:编解码方式,有Binary和 Compact两种 TRANSFORM ID:压缩方式,如zIib和 snappy INFO ID:传递一些定制的meta信息 PAYLOAD:消息体
2.10协议层-协议解析
2.12网络通信层-Sockets APl
2.13网络通信层-网络库
1.提供易用API
封装底层Socket API 连接管理和事件分发
2.功能
协议支持:tcp、udp和uds等 优雅退出、异常处理等
3.性能
应用层buffer减少copy 高性能定时器、对象池等
三、关键指标
3.1稳定性-保障策略
1.熔断:保护调用方,防止被调用的服务出现问题而影响到整个链路
2.限流:保护被调用方,防止大流量把服务压垮
3.超时控制:避免浪费资源在不可用节点上
3.2稳定性-请求成功率
负载均衡、重试
3.3稳定性-长尾请求
3.4稳定性-注册中间件
3.5易用性
1.开箱即用
合理的默认参数选项、丰富的文档
2.周边工具
生成代码工具、脚手架工具
3.6扩展性
1.Middleware 2.Option 3.编解码层 4.协议层 5.网络传输层 6.代码生成工具插件扩展
3.7观测性
1.Log、Metric、Tracing 2.内置观测性服务
3.8高性能
1.场景
√单机多机
√单连接多连接
√单/多client 单/多server
√不同大小的请求包
√不同请求类型:例如pingpong、streaming等
2.目标
√高吞吐
√低延迟
3.手段
√连接池
√多路复用
√高性能编解码协议
√高性能网络库