自学内容网 自学内容网

241125学习日志——[CSDIY] [ByteDance] 后端训练营 [18]

CSDIY:这是一个非科班学生的努力之路,从今天开始这个系列会长期更新,(最好做到日更),我会慢慢把自己目前对CS的努力逐一上传,帮助那些和我一样有着梦想的玩家取得胜利!!!
第一弹:Cpp零基础学习【30 DAYS 从0到1】
第二弹:Cpp刷题文档【LeetCode】
第三弹:Go开发入门【字节后端青训营】
第四弹:Cpp简单项目开发【黑马Rookie】
第五弹:数据结构绪论【数据结构与算法】
第六弹:Go工程实践【字节后端青训营】
第七弹:高质量编程和性能调优【字节后端青训营】
第八弹:Linux 基础知识【书生大模型训练营】
第九弹:Python 基础知识【书生大模型训练营】
第十弹:Git 基础知识【书生大模型训练营】
第十一弹:玩转HF/魔搭/魔乐社区【书生大模型训练营】
第十二弹:书生大模型全链路开源体系【书生大模型训练营】
第十三弹:玩转书生「多模态对话」与「AI搜索」产品【书生大模型训练营】
第十四弹:浦语提示词工程实践【书生大模型训练营】
第十五弹:HTTP 框架修炼之道【字节后端青训营】
第十六弹:打开抖音会发生什么【字节后端青训营】
第十七弹:将我的服务开放给用户【字节后端青训营】
第十八弹:InternLM + LlamaIndex RAG 实践【书生大模型训练营】
第十九弹:深入浅出 RPC 框架【字节后端青训营】

241125——[ByteDance] [06] 深入浅出 RPC 框架

01. 基础概念

1.1 本地函数调用

压栈…弹栈…等等操作

基于 Go 语言的实现。

1.2 远程函数调用(RPC - Remote Procedure Calls)

RPC 需要解决的问题

  1. 函数映射
  2. 数据转换成字节流
  3. 网络传输

1.3 RPC 概念模型

1.4 一次 RPC 的完整过程

IDL 文件:Interface description language

生成文件

编解码

通信协议

网络传输

1.5 RPC 的好处

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

1.6 RPC 带来的问题

  1. 服务宕机,对方如何处理?
  2. 在调用过程中发生网络异常
  3. 请求量徒增导致服务无法及时处理

👇

RPC 框架应运而生

02. 分层设计

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

2.1 分层设计 - 以 Apache Thrift 为例

用户编写的业务逻辑代码

👇

通过代码生成工具转化为 lib 代码

👇

框架的编解码层

👇

框架的协议层

👇

框架的网络通信层

2.3 编解码层 - 生成代码

IDL 生成不同语言的 CodeGen

2.4 编解码层 - 数据格式

  • 语言特定格式
    • 许多编程语言都内建了将内存对象编码为字节序列的支持
  • 文本格式
    • JSON、XML、CSV 等文本格式,具有人类可读性
  • 二进制编码
    • 具备跨语言和高性能等优点,常见有 Thrift 的 BinaryProtocol,Protobuf 等

2.5 编解码层 - 二进制编码

  • TLV编码

    • Tag:标签(类型)
    • Length:长度
    • Value:值

2.6 编解码层 - 选型

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

2.7 协议层

约定的通信协议

2.8 协议层 - 概念

  • 特殊结束符
    • 一个特殊字符作为每个协议单元结束的表示
  • 变长协议
    • 以定长加不定长的部分组成,其中定长的部分需要描述不定长的内容长度

2.9 协议层 - 协议构造

LENGTH:数据包大小

HEADER MAGIC:标识版本信息

SEQUENCE NUMBER:表示数据包的 seqID

HEADER SIZE:头部长度

PROTOCOL ID:…

TRANSFORM ID:…

INFO ID:…

PAYLOAD:…

2.10 协议层 - 协议解析

2.11 网络通信层

2.12 网络通信层 - Sockets API

2.13 网络通信层 - 网络库

  • 提供易用 API
    • 封装底层 Scoket API
    • 连接管理和事件分发
  • 功能
    • 协议支持:tcp、udp 和 uds 等
    • 优雅退出(高级功能…)、异常处理等
  • 性能
    • 应用层 buffer 减少 copy
    • 高性能定时器、对象池等

03. 关键指标

3.1 稳定性 - 保障策略

  • 熔断:保护调用方,防止被调用的服务出现问题而影响到整个链路
  • 限流:保护被调用方,防止大流量把服务压垮
  • 超时控制:避免浪费资源在不可用节点上

均会导致 👉 降级

3.2 稳定性 - 请求成功率

负载均衡、重试

3.3 稳定性 - 长尾请求

Backup Request

设计Backup request的关键是要防止服务器繁忙时期的请求风暴。在服务器繁忙时期client容易发生等待超时,倾向于发送backup request。大量的backup request会进一步让服务器更繁忙,于是请求风暴诞生了。防止请求风暴的要点是区分普通超时和风暴期超时。

3.4 稳定性 - 注册中间件

3.5 易用性

  • 开箱即用

    • 合理的默认参数选项、丰富的文档
  • 周边工具

    • 生成代码工具、脚手架工具

简单易用的命令行工具…

3.6 扩展性

  • Middleware
  • Option
  • 编解码层
  • 协议层
  • 网络传输层
  • 代码生成工具插件扩展

3.7 观测性

  • Log、Metric、Tracing
  • 内置观测性服务

3.8 高性能

场景

  • 单机多机
  • 单连接多连接
  • 单/多 client 单/多 server
  • 不同大小的请求包
  • 不同请求类型:pingpong streaming

目标

  • 高吞吐
  • 低延迟

手段

  • 连接池
  • 多路复用
  • 高性能编解码协议
  • 高性能网络库

04. 企业实践

4.1 整体架构 - Kitex

Kitex Core 核心组件

Kitex Byted 与公司内部基础设施集成

Kitex Tool 代码生成工具

4.2 自研网络库 - 背景

  • 原生库无法感知连接状态
    • 在使用连接库时,池中存在失效连接
  • 原生库存在 goroutine 暴涨的风险
    • 一个连接 一个 goroutine 的模式,由于连接利用率低下,存在大量 goroutine 占用调度开销,影响性能

4.3 自研网络库 - Netpoll

  • 解决无法感知连接状态问题
    • 引入 epoll 主动监听机制
  • 解决 goroutine 暴涨风险

4.4 扩展性设计

支持多协议,也支持灵活的自定义协议扩展

4.5 性能优化 - 网络库优化

  • 调度优化
  • LinkBuffer
  • Pool
    • 引入内存池和对象池,减少 GC 开销

4.6 性能优化 - 编解码优化

  • Codegen
    • 预计算并预分配内存,减少内存操作次数,包括内存分配和拷贝
    • Inline 减少函数调用次数和不必要的反射操作
    • 自研 Go 语言实现的 Thrift IDL 解析和代码生成器
  • JIT
    • Frugal

4.7 合并部署

微服务过微,传输和序列化开销越来越大

  • 中心化的部署调度和流量控制
  • 基于共享内存的通信协议
  • 定制化的服务发现和连接池实现

碎碎念:八股文选手养成日记,只是一位复制PPT上的文字,其实根本没有进入脑子,如此懒惰作风什么时候能改掉?但其实我也不想烂。只是真的没有时间。

与君共勉。


原文地址:https://blog.csdn.net/Rain050415/article/details/144043795

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!