# 后端基础| 青训营笔记

41 阅读5分钟

这是我参与「第五届青训营」伴学笔记创作活动的第 12 天

RPC框架 本地函数调用

image.png

远程函数调用(RPC—Remote Rrocedure Calls)
网络商城然后进行支付,由支付服务进行余额的减少然后返回扣款成功。
RPC需要解决的问题 1.函数映射 2.数据转换成字节流 3.网络传输

image.png

IDL(Interface description language)文件:IDL通过一种中立的方式来描述接口,使得在不同平台上运行的对象和用不同语言编写的程序可以相互通信
生成代码:通过编译器工具把IDL文件转换成语言对应的静态库
编解码:从内存中表示到字节序列的转换称为编码,反之为解码,也常叫做序列化和反序列化
通信协议:规范了数据在网络中的传输内容和格式。除必须的请求/响应数据外,通常还会包含额外的元数据
网络传输:通常基于成熟的网络库走TCP/UDP传输

image.png

RPC的好处:
1.单一职责,有利于分工协作和运维开发
2.可扩展性强,资源使用率更优
3.故障隔离,服务的整体可靠性更高

image.png

问题:
1.服务宕机,对方应该如何处理?
2.在调用过程中发生网络异常,如何保证消息的可达性?
3.请求量突增导致服务无法及时处理,有哪些应对措施?

image.png

分层设计:编解码层,协议层,网络通信层

image.png

服务端和客户端要依赖同一份IDL文件来生成不同语言的CodeGen(Golang c++ Java)
数据格式:
语言特定的格式: 许多编程语言都内建了将内存对象编码为字节序列的支持,例如 Java 有 java.io.Serializable
文本格式: JSON、XML、CSV 等文本格式,具有人类可读性
二进制编码: 具备跨语言和高性能等优点,常见有 Thrift 的 BinaryProtocol,Protobuf 等

二进制编码

image.png

选型需要考虑的方面:
兼容性:支持自动增加新的字段,而不影响老的服务,这将提高系统的灵活度
通用性:支持跨平台、跨语言,也要考虑他的流行性
性能:从空间和时间两个维度来考虑,也就是编码后数据大小和编码耗费时长

协议层—概念
特殊结束符:一个特殊字符作为每个协议单元结束的表示
message \r\n
变长协议:以定长加不定长的部分组成,其中定长的部分需要描述不定长的内容长度
length message

协议构造: image.png

协议解析:
—Peek—MagicNumeber(知道什么类型的协议)—Peek—PayloadCodec(编解码方式)—Decode—Payload

image.png

网络通信层 - 网络库
提供易用 API: 封装底层 Socket API连接管理和事件分发
功能: 协议支持: tcp、udp 和 uds 等优雅退出、异常处理等
性能: 应用层 buffer 减少 copy、 高性能定时器、对象池等

image.png

关键指标:
稳定性
熔断:保护调用方,防止被调用的服务出现问题而影响到整个链路
限流:保护被调用方,防止大流量把服务压垮
超时控制:避免浪费资源在不可用节点上
请求成功率

image.png


长尾请求,明显高于平均响应时间的低占比请求 (单个请求的耗时处于99%的请求为pc99,然后高于的可以叫做长尾请求)

image.png
左边是普通的重试,右边Backup Request(被动请求)
稳定性—注册中间件

image.png


易用性
开箱即用:合理的默认参数选项、丰富的文档
周边工具:生成代码工具、脚手架工具(生成比较重复的代码)
比如说:
Suite包括了熔断、限流、降级
简单易用的命令行工具
①生成服务代码脚手架
②支持protobuf和thrift
③内置功能丰富的选项
④支持自定义的生成代码插件

扩展性

image.png

观测性
三件套:Log、Metric(监控面板QBS)、Tracing(链路跟踪)
内置观测服务

image.png

高性能
场景:
①单机多机 ②单连接多连接 ③单/多client 单/多server ④不同大小的请求包 ⑤不同请求类型: 例如 pingpong、streaming 等
目标: 高吞吐、低延迟
手段: ①连接池 ②多路复用 ③高性能编解码协议 ④高性能网络库

image.png

企业实践(字节)
整体框架

image.png

自研网络库
背景:
①原生库无法感知连接状态(在使用连接池时,池中存在失效连接,影响连接池的复用)原生库存在goroutine暴涨的风险
②一个连接一个goroutine的模式,由于连接利用率低下,存在大量goroutine占用调度开销,影响性能。
解决方案:Netpoll
解决无法感知连接状态问题(引入epoll主动监听机制,感知连接状态)
解决goroutine保障的风险(建立goroutine池,复用goroutine)
提升性能(引入Nocopy Buffer,向上层提供Nocopy的调用接口,编解码层面零拷贝)

扩展性设计

image.png

性能优化
网络库优化

image.png

编解码优化

image.png

合并部署
问题:微服务过微,传输和序列化开销越来越大
解决方案:将亲和性强的服务实例尽可能调度到同一个物理机,远程RPC调用优化为本地IPC调用

image.png

image.png

小结 image.png

课程总结 image.png