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上的文字,其实根本没有进入脑子,如此懒惰作风什么时候能改掉?但其实我也不想烂。只是真的没有时间。

与君共勉。

相关推荐
西岸行者5 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意5 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码5 天前
嵌入式学习路线
学习
毛小茛5 天前
计算机系统概论——校验码
学习
babe小鑫5 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms5 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下5 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。5 天前
2026.2.25监控学习
学习
im_AMBER5 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J5 天前
从“Hello World“ 开始 C++
c语言·c++·学习