Volo 新能力:面向易用性与性能的 HTTP & RPC 框架迭代

随着微服务架构的广泛应用,高性能、易用性的微服务框架成为开发者的核心需求。Volo 作为专注于 Rust 微服务生态的高性能框架,在追求极致性能的同时,持续优化工程化易用性与可扩展性。

本文基于字节跳动服务框架团队研发工程师、Volo/Pilota 项目 Maintainer 王杰在 CloudWeGo 四周年技术沙龙上的演讲内容整理,聚焦 Volo 框架的重要迭代,深入解读其在 RPC 生成代码能力及 HTTP 新能力上的优化升级。

点击链接可查看本次分享回放👉🏻b23.tv/pB7YAKl

一、Volo框架概述

Volo 的核心定位是构建专注于 Rust 微服务生态的高性能框架,设计上兼顾极致性能与工程化易用性、可扩展性,通过统一抽象架构实现"协议、治理、传输"的分层解耦,衍生出三大协议框架------volo-thrift、volo-grpc、volo-http,三者共享同一套核心抽象,确保开发体验一致,同时支持中间件能力的复用。

Volo 生态围绕核心框架构建了完善的辅助工具与模块,降低开发门槛:

  • 中间件系统 :实现了服务治理链,提供可观测性三件套、超时重试等核心能力,并以 service/layer 的形式支持用户自由组合。

  • 传输层与运行时:提供了 TCP/TLS 实现,并基于 Tokio Runtime 构建了异步生态。同时,封装了统一的 Client/Server 接口,便于用户快速上手。

  • Pilota:作为核心代码生成工具,支持 Thrift 与 Protobuf 的编解码,是本次迭代的核心载体。

  • Metainfo:负责调用元信息的透传,保障了微服务链路的可追踪性。

  • volo-cli :命令行工具,支持一键创建项目、拉取远端 IDL,并配合 volo.yml 配置文件实现 IDL 管理与功能开关控制。

目前,Volo 已在字节跳动内部多个业务线的大量服务中落地应用,并根据业务发展需求持续进行迭代优化。

二、RPC生成代码能力的易用性与性能优化

Volo 的迭代重点聚焦于 RPC 框架的生态完善,针对微服务业务中的常见需求,如为字段透传、编解码控制、数据裁剪等提供了解决方案。 核心迭代集中在代码生成工具 Pilota 中,通过 volo.yml 配置文件实现了 IDL 级别的功能开关控制。这种方式为用户提供了低侵入式的功能接入体验------所有新增能力都集成于生成代码中,并提供了标准化的结构与方法。

2.1 Protobuf Unknown Fields:未定义字段的可靠保留与透传

根据 Protobuf 的官方定义,unknown fields 能力的核心是保留并传输 proto 文件中未定义的字段,以解决跨版本、跨服务交互中因字段未定义而导致数据丢失的问题。

2.1.1 快速接入:配置驱动的低门槛使用

用户只需通过简单的配置即可开启该功能:

  1. 使用 volo-cliinit 命令创建项目。

  2. 在项目中的 volo.yml 配置文件中添加 unknown_fields 相关配置(默认关闭)。该配置支持按 IDL 级别进行精细化控制。

配置完成后,生成代码会自动集成 unknown fields 的能力,无需手动修改业务代码。

2.1.2 设计实现:零拷贝的高性能透传方案

开启该功能后,生成的结构体末尾会新增一个 _unknown_fields 字段,专门用于透传所有未识别的字段。该字段的类型为 Pilota 中定义的 BytesVec,由一个 bytes 队列和记录全长的 size 组成。选择该数据结构的核心目标是降低编解码开销。 在解码(decode)过程中,核心逻辑如下:

  1. 将二进制数据读入缓冲区。

  2. 解析 Protobuf 协议的 tag,判断字段是否为已知字段。

  3. 若为未知字段,则按 Protobuf 二进制协议完整跳过该字段,计算跳过的长度,并将对应的数据切片存入 unknown fields 列表。

此过程的核心开销在于数据写入。因此,Volo 采用了零拷贝结构 Bytes ,通过复用缓冲区中的原有数据,大幅降低了性能损耗。 后续优化方向 :引入短路优化。如果判断所有已知字段都已解析完成,可将剩余的字节一次性载入 unknown fields 列表。但该优化受 Protobuf 官方定义的限制------repeated 字段的元素无需强制连续出现,这导致难以精准判断解析的终点。目前该优化仍在改进中。当前建议将新增的透传字段置于结构体的末尾,以提升解析效率。

2.2 Protobuf Options:注解驱动的编解码控制与业务配置

Volo 基于 Google Protobuf 官方的注解语法,扩展实现了 pb options 能力,以支持两类核心场景:

  1. 通过 Pilota 注解控制编解码行为。

  2. 通过用户自定义注解配置业务相关数据。

该功能同样通过 volo.yml 的开关开启,接入成本低。

2.2.1 Pilota 注解:解决性能与工程化痛点

使用 Pilota 注解需要先引入 pilota.proto 文件。Volo 采用 well-known types 的方式来简化接入,降低了维护成本。 典型应用: rust_wrapper_arc_all 注解。针对大量栈拷贝导致的内存带宽过高问题,该注解可以使生成的 Server lib 模板代码中,request 和 response 结构体自动添加 Arc wrapper,从而减少拷贝开销。此外,Volo 还提供了多种其他 Pilota 注解,以覆盖编解码流程的精细化控制需求。

2.2.2 自定义注解:灵活适配业务配置需求

用户可以按照 Google 的官方语法定义自定义注解。通过生成代码提供的 file_descriptor 方法,可以获取其抽象语法树,然后遍历找到目标结构体(匹配时需使用 IDL 中定义的名称),再通过 get 方法直接获取注解的值。 实践中发现,用户在使用 struct 描述时需要遍历整个 file descriptor,操作较为繁琐。因此,Volo 在后续的迭代中计划增加易用性方法,这一优化已在 thrift field mask 功能中得到了落地验证。

后续发展方向

  • 提升自定义注解的性能与可扩展性,并完善易用性方法。

  • 优化构建性能,解决 pb custom options 开启 touch_all 时导致的 build 变慢、代码体积增大的问题。计划通过"按需生成注解"的机制进行优化,并在 Pilota 中提供更多的 hook 点。

2.3 Thrift Field Mask:运行时动态裁剪的高效解决方案

在字节内部大量使用 Thrift 协议的业务场景中,存在三类核心需求:

  1. 在统一 IDL 的场景下,减少传输带宽和编解码开销。

  2. Gateway/Proxy 服务的接口复用与分发。

  3. 字段权限控制。

这些需求的本质是"运行时动态裁剪编码字段"。为此,Volo 引入了 thrift field mask 能力,即通过一个掩码列表来指定需要保留的字段,从而实现数据的精准裁剪。该能力已在 Kitex 框架中得到验证和落地,目前已适配 Volo 框架。 以 Client 端裁剪 request 为例,使用 thrift field mask 需要两步操作:

  1. 指定 thrift path 作为掩码列表(支持黑白名单配置,默认为白名单,即指定需要保留的字段)。

  2. 传入 struct descriptor

为降低性能损耗,建议使用全局缓存来减少 field mask 构建开销对主链路的影响。

为保障生态的兼容性,Volo 采用了与 Kitex 一致的 thrift path 定义,Kitex 用户可以无缝复用其路径定义,无需额外适配。struct descriptor 可以通过生成代码中结构体的内置方法获取,这一设计也为 pb descriptor 的后续迭代指明了方向。

在用户层面,只需为 request 设置 fieldmask,生成代码便会自动完成动态裁剪的逻辑。此外,Volo 还提供了多个 API 接口来简化 fieldmask 的操作。 后续规划 :支持 fieldmask 自身的序列化与传递,以满足"通知对端服务屏蔽特定字段"的场景需求。

三、volo-http 0.4 及 Rust 生态组件更新

除 RPC 框架迭代外,Volo 还推进了 HTTP 能力升级与 Rust 生态组件优化:

  • volo-http 0.4 升级 :新增了对 HTTP/2 的支持和连接池优化,同时改进了 trace 能力,提升了 HTTP 服务的性能与可观测性。

  • sonic-rs 0.5 升级 :完善了多架构支持,为 ARM 架构新增了 sort_keysutf8-lossy 等特性,提升了 object 类型的查询性能,并为 faststr 实现了 GDB/LLDB 调试插件,以降低调试成本。

  • linkedbytes 升级 :支持 io slice,并提供了 concat 接口用于获取完整的 bytes,提升了数据操作的灵活性与效率。

作为 CloudWeGo 生态中 Rust 方向的核心维护者,团队将持续聚焦于性能与易用性,致力于输出更多高质量的 Rust 微服务组件。

四、未来规划:持续完善 Rust 微服务生态

后续,Volo 将围绕 RPC 框架升级Rust 生态完善两大方向来推进迭代。

  • RPC 框架层面

    • 协议扩展 :实现 thriftMultiServiceThrift Streaming

    • 性能优化 :接入 shmipc 并完成 Volo 适配,以解决用户进程与 Sidecar 之间的 RPC 通信开销。

    • 易用性提升:重构生成代码的错误处理逻辑,完善服务发现与服务治理组件,并强化生态的可观测性。

  • Rust 生态层面

    • 优化 faststr 的内存占用。

    • 持续完善 sonic-rslinkedbytes 等组件的性能与功能覆盖,构建更完整的 Rust 微服务工具链。

五、总结

Volo 框架的迭代始终围绕"易用性"与"性能"两大核心目标。通过 pb unknown fieldspb optionsthrift field mask 三大核心功能的落地,精准解决了微服务业务中字段透传、编解码控制、数据裁剪等痛点。所有迭代都基于现有的生态架构,通过 Pilota 工具和 volo.yml 配置实现了低侵入式的接入,保障了开发体验的一致性。

未来,随着 RPC 协议不断扩展、性能持续优化以及生态组件逐步完善,Volo 会进一步降低使用 Rust 开发微服务的难度,发挥 Rust 语言高性能的优势,为微服务架构的发展提供更高效的技术支持。

相关推荐
^_scv_^2 小时前
QEMU-RISCV平台opensbi代码分析(2)
linux·架构·risc-v
狗哥哥2 小时前
企业级 HTTP 客户端架构演进与设计
前端·架构
前端阿森纳4 小时前
公司是否因为AI正在从“以人为本”走向“以核心数据集为本”?
架构·aigc
小宝哥Code4 小时前
区块链(Blockchain)—— 概念、架构与应用
架构·区块链
0x派大星4 小时前
深入解析 Uniswap:自动做市商模型的数学推导与智能合约架构
架构·区块链·智能合约·uniswap
a努力。4 小时前
网易Java面试被问:偏向锁在什么场景下反而降低性能?如何关闭?
java·开发语言·后端·面试·架构·c#
敲敲敲敲暴你脑袋5 小时前
晋江文学城账号安全简直就是笑话
安全·架构·产品
一水鉴天5 小时前
整体设计 定稿 之6 完整设计文档讨论及定稿 之4 整体设计数据库设计规范(含两个版本)
开发语言·人工智能·架构
Tezign_space5 小时前
SEO优化与AI内容运营的技术融合:架构、算法与实施路径
人工智能·架构·内容运营·私域运营·ai内容生成·seo流量增长·内容运营效率