RPC框架 | 青训营
深入浅出RPC框架
基本概念
本地函数调用
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.计算x*y,并将结果存在z
4.将z的值压栈,然后从calculate返回
5.从栈中取出z返回值,并赋值给result
远程函数调用(RPC)
RPC - Remote Procedure Calls
RPC需要解决的问题
1.函数映射
2.数据转换成字节流
3.网络传输
RPC概念模型
RPC的过程由5个模型组成:User、User-Stub、RPC-Runtime、Server-Stub、Server
一次RPC的完整过程
IDL(Interface description language)文件
IDL通过一种中立的方式来描述接口,使得在不同平台上运行的对象和用不同语言编写的程序可以相互通信
生成代码
通过编译器工具把IDL文件转换成语言对应的静态库
编解码
从内存中表示到字节序列的转换称为编码,反之为解码,也常叫做序列化和反序列化
通信协议
规范了数据在网络中的传输内容和格式。除必须的请求/响应数据外,通常还会包含额外的元数据
网络传输
通常基于成熟的网络库走TCP/UDP传输
RPC的好处
1.单一职责,有利于分工协作和运维开发
2.可扩展性强,资源使用率更优
3.故障隔离,服务的整体可靠性更高
RPC带来的问题
分层设计
分层设计-以Apache Thrift为例
编解码层
生成代码
数据格式
语言特定的格式
许多编程语言都内建了将内存对象编码为字节序列的支持,例如Java有java.io.Serializable
文本格式
JSON、XML、CSV等文本格式,具有人类可读性
二进制编码
具备跨语言和高性能等优点,常见有Thrift的BinaryProtocol,Protobuf等
二进制编码
TLV编码
Tag:标签,可以理解为类型
Lenght:长度
Value:值,Value也可以是个TLV结构
struct Person {
1: required string userName,
2: optional i64 favoriteNumber,
3: optional list<string> interests
}
选型
兼容性
支持自动增加新的字段,而不影响老的服务,这将提高系统的灵活度
通用性
支持跨平台、跨语言
性能
从空间和时间两个维度来考虑,也就是编码和数据大小和编码耗费时长
协议层
概念
特殊结束符
一个特殊字符作为每个协议单元结束的标示
变长协议
以定长加不定长的部分组成,其中定长的部分需要描述不定长的内容长度
协议构造
LENGTH:数据包大小,不包含自身
HEADER MAGIC:标识版本信息,协议解析时候快速校验
SEQUENCE NUMBER:表示数据包的seqID,可用于多路复用,单连接内递增
HEADER SIZE:头部长度,从第14个字节开始计算一直到PAYLOAD前
PROTOCOL ID:编解码方式,有Binary和Compact两种
TRANSFORM ID:压缩方式,如zlib和snappy
INFO ID:传递一些定制的meta信息
PAYLOAD:消息体
协议解析
网络通信层
Sockets API
网络库
提供易用API
封装底层Socket API
连接管理和事件分发
功能
协议支持:TCP、UDP和uds等
优雅退出、异常处理等
性能
应用层buffer减少copy
高性能定时器、对象池等
关键指标
稳定性
保障策略
熔断:保护调用方,防止被调用的服务出现问题而影响到整个链路
限流:保护被调用方,防止大流量把服务压垮
超时控制:避免浪费资源在不可用节点上
请求成功率
负载均衡
重试
长尾请求
Backup Request
注册中间件
易用性
开箱即用
合理的默认参数选项、丰富的文档
周边工具
生成代码工具、脚手架工具
简单易用的命令行工具
生成服务代码脚手架
支持protobuf和thrift
内置功能丰富的选项
支持自定义的生成代码插件
扩展性
Middleware
Option
编解码层
协议层
网络传输层
代码生成工具插件扩展
观测性
Log、Metric、Tracing
内置观测性服务
高性能
场景
单机多机
单连接多连接
单/多client 单/多server
不同大小的请求包
不同请求类型:例如pingpong、streaming等
目标
高吞吐
低延迟
手段
连接池
多路复用
高性能编解码协议
高性能网络库
企业实践
整体结构-Kitex
Kitex Core
核心组件
Kitex Byted
与公司内部基础设施集成
Kitex Tool
代码生成工具
自研网络库
背景
原生库无法感知连接状态
在使用连接池时,池中存在失效连接,影响连接池的复用
原生库存在goroutine暴涨的风险
一个连接一个goroutine的模式,由于连接利用率低下,存在大量goroutine占用调度开销,影响性能
Netpoll
解决无法感知连接状态问题
引入epoll主动监听机制,感知连接状态
解决goroutine暴涨的风险
建立goroutine池,复用goroutine
提升性能
引入Nocopy Buffer,向上层提供NoCopy的调用接口,编解码层面零拷贝
扩展性设计
支持多协议,也支持灵活的自定义协议扩展
性能优化
网络库优化
调度优化
epoll_wait在调度上的控制
gopool重用goroutine降低同时运行协程数
LinkBuffer
读写并行无锁,支持nocopy地流式读写
高效扩缩容
Nocopy Buffer池化,减少GC
Pool
引入内存池和对象池,减少GC开销
编解码优化
Codegen
预计算并预分配内存,减少内存操作次数,包括内存分配和拷贝
Inline减少函数调用次数和避免不必要的反射操作等
自研了Go语言实现的Thrift IDL解析和代码生成器,支持完善的Thrift IDL语法和语义检查,并支持了插件机制-Thriftgo
JIT
使用JIT编译技术改善用户体验的同时带来更强的编解码性能,减轻用户维护生成代码的负担
基于JIT编译技术的高性能动态Thrift编解码器-Frugal
合并部署
合并部署要解决的问题
微服务过微,传输和序列化开销越来越大
将亲和性强的服务实例尽可能调度到同一个物理机,远程RPC调用优化为本地IPC调用
解决方案
中心化的部署调度和流量控制
基于共享内存的通信协议
定制化的服务发现和连接池实现
定制化的服务启动和监听逻辑
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgbaief
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13