随着微服务架构的广泛应用,高性能、易用性的微服务框架成为开发者的核心需求。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 快速接入:配置驱动的低门槛使用
用户只需通过简单的配置即可开启该功能:
-
使用
volo-cli的init命令创建项目。 -
在项目中的
volo.yml配置文件中添加unknown_fields相关配置(默认关闭)。该配置支持按 IDL 级别进行精细化控制。
配置完成后,生成代码会自动集成 unknown fields 的能力,无需手动修改业务代码。
2.1.2 设计实现:零拷贝的高性能透传方案
开启该功能后,生成的结构体末尾会新增一个 _unknown_fields 字段,专门用于透传所有未识别的字段。该字段的类型为 Pilota 中定义的 BytesVec,由一个 bytes 队列和记录全长的 size 组成。选择该数据结构的核心目标是降低编解码开销。 在解码(decode)过程中,核心逻辑如下:
-
将二进制数据读入缓冲区。
-
解析 Protobuf 协议的 tag,判断字段是否为已知字段。
-
若为未知字段,则按 Protobuf 二进制协议完整跳过该字段,计算跳过的长度,并将对应的数据切片存入 unknown fields 列表。
此过程的核心开销在于数据写入。因此,Volo 采用了零拷贝结构 Bytes ,通过复用缓冲区中的原有数据,大幅降低了性能损耗。 后续优化方向 :引入短路优化。如果判断所有已知字段都已解析完成,可将剩余的字节一次性载入 unknown fields 列表。但该优化受 Protobuf 官方定义的限制------repeated 字段的元素无需强制连续出现,这导致难以精准判断解析的终点。目前该优化仍在改进中。当前建议将新增的透传字段置于结构体的末尾,以提升解析效率。
2.2 Protobuf Options:注解驱动的编解码控制与业务配置
Volo 基于 Google Protobuf 官方的注解语法,扩展实现了 pb options 能力,以支持两类核心场景:
-
通过 Pilota 注解控制编解码行为。
-
通过用户自定义注解配置业务相关数据。
该功能同样通过 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 协议的业务场景中,存在三类核心需求:
-
在统一 IDL 的场景下,减少传输带宽和编解码开销。
-
Gateway/Proxy 服务的接口复用与分发。
-
字段权限控制。
这些需求的本质是"运行时动态裁剪编码字段"。为此,Volo 引入了 thrift field mask 能力,即通过一个掩码列表来指定需要保留的字段,从而实现数据的精准裁剪。该能力已在 Kitex 框架中得到验证和落地,目前已适配 Volo 框架。 以 Client 端裁剪 request 为例,使用 thrift field mask 需要两步操作:
-
指定
thrift path作为掩码列表(支持黑白名单配置,默认为白名单,即指定需要保留的字段)。 -
传入
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_keys、utf8-lossy等特性,提升了 object 类型的查询性能,并为faststr实现了 GDB/LLDB 调试插件,以降低调试成本。 -
linkedbytes 升级 :支持
io slice,并提供了concat接口用于获取完整的 bytes,提升了数据操作的灵活性与效率。
作为 CloudWeGo 生态中 Rust 方向的核心维护者,团队将持续聚焦于性能与易用性,致力于输出更多高质量的 Rust 微服务组件。
四、未来规划:持续完善 Rust 微服务生态

后续,Volo 将围绕 RPC 框架升级 和 Rust 生态完善两大方向来推进迭代。
-
RPC 框架层面
-
协议扩展 :实现
thriftMultiService与Thrift Streaming。 -
性能优化 :接入
shmipc并完成 Volo 适配,以解决用户进程与 Sidecar 之间的 RPC 通信开销。 -
易用性提升:重构生成代码的错误处理逻辑,完善服务发现与服务治理组件,并强化生态的可观测性。
-
-
Rust 生态层面
-
优化
faststr的内存占用。 -
持续完善
sonic-rs、linkedbytes等组件的性能与功能覆盖,构建更完整的 Rust 微服务工具链。
-
五、总结
Volo 框架的迭代始终围绕"易用性"与"性能"两大核心目标。通过 pb unknown fields、pb options、thrift field mask 三大核心功能的落地,精准解决了微服务业务中字段透传、编解码控制、数据裁剪等痛点。所有迭代都基于现有的生态架构,通过 Pilota 工具和 volo.yml 配置实现了低侵入式的接入,保障了开发体验的一致性。
未来,随着 RPC 协议不断扩展、性能持续优化以及生态组件逐步完善,Volo 会进一步降低使用 Rust 开发微服务的难度,发挥 Rust 语言高性能的优势,为微服务架构的发展提供更高效的技术支持。