Nitrogen 是为云原生与低延迟分布式系统设计的现代 Rust RPC 框架。底层基于 AWS s2n-quic 实现高性能、抗丢包与多路复用的 QUIC 传输通道,上层结合 Rust 过程宏与 MessagePack 紧凑序列化,让开发者以接近原生 Rust 异步 Trait 的方式编写强类型、低开销的分布式微服务。
- ⚡ QUIC 原生传输:基于 UDP 与 TLS 1.3,无队头阻塞(Head-of-Line Blocking),支持单连接内多双向流(Bistream)并发与链路迁移。
- 🪄 零样板代码过程宏:只需声明
#[nitrogen::rpc_service]Trait,自动生成请求/应答枚举、服务端路由分发器及全异步强类型客户端。 - 📦 高性能紧凑编码:集成
MessagePack二进制序列化与流式分帧解码(LengthDelimitedCodec),带宽与 CPU 开销极低。 - 🔄 流水线多路复用:单个底层 Stream 内置请求 ID 关联与异步回调路由,支持高并发无序应答与超时控制。
- 🧩 模块化解耦架构:核心抽象、过程宏、QUIC 驱动、编解码工具与扩展路由层层解耦,按需引用。
flowchart TD
subgraph Client["Nitrogen 客户端"]
UserCode["用户业务调用 (client.method)"]
RpcClient["RpcServiceClient 生成客户端"]
FramedSink["MessagePack 帧编码器"]
end
subgraph Transport["QUIC 多路复用传输通道"]
BiStream["QUIC Bidirectional Stream (s2n-quic)"]
end
subgraph Server["Nitrogen 服务端"]
FramedStream["MessagePack 帧解码器"]
ServiceExt["ServiceExt::serve / route 分发"]
ServiceImpl["用户 Trait 业务实现"]
end
UserCode -->|"异步请求"| RpcClient
RpcClient -->|"Message[Req] (携带 ReqId)"| FramedSink
FramedSink -->|"二进制分帧"| BiStream
BiStream -->|"分发双向流"| FramedStream
FramedStream -->|"反序列化消息"| ServiceExt
ServiceExt -->|"派发执行"| ServiceImpl
ServiceImpl -->|"计算结果"| ServiceExt
ServiceExt -->|"Message[Resp]"| FramedStream
FramedStream -->|"回写流"| BiStream
BiStream -->|"应答通知"| FramedSink
FramedSink -->|"匹配 ReqId"| RpcClient
RpcClient -->|"返回 Future 结果"| UserCode
| Crate | 描述 |
|---|---|
nitrogen |
框架核心门面包,提供 RpcServiceClient、Negotiator、Message<T> 协议定义与统一导出 |
nitrogen-macro |
核心过程宏 #[rpc_service],自动生成客户端桩代码、服务路由与请求/应答枚举 |
nitrogen-quic |
基于 AWS s2n-quic 封装的 QUIC 监听器(QuicListener)与连接抽象 |
nitrogen-utils |
异步帧流适配(FramedTokioIO)、MessagePack 编解码器与 Stream/Sink Channel 桥接工具 |
nitrogen-extra |
高级扩展组件,包含多服务组合路由与网络中继占位 |
使用 #[nitrogen::rpc_service] 声明服务接口:
use nitrogen::rpc_service;
#[rpc_service]
pub trait CalculatorService {
async fn add(&self, a: i64, b: i64) -> i64;
async fn ping(&self) -> String;
}宏将自动为你生成:
CalculatorServiceRequest与CalculatorServiceResponse枚举CalculatorServiceExt服务端扩展(提供.route()与.serve(stream))CalculatorServiceClient强类型客户端(提供.add(a, b)与.ping())
use nitrogen::CalculatorServiceExt;
use nitrogen_quic::QuicListener;
#[derive(Clone)]
struct CalculatorServiceImpl;
#[async_trait::async_trait]
impl CalculatorService for CalculatorServiceImpl {
async fn add(&self, a: i64, b: i64) -> i64 {
a + b
}
async fn ping(&self) -> String {
"pong".to_string()
}
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let mut listener = QuicListener::bind("127.0.0.1:4433".parse()?).await?;
let service = CalculatorServiceImpl;
while let Ok(mut connection) = listener.accept().await {
let service = service.clone();
tokio::spawn(async move {
while let Ok(bi_stream) = connection.accept().await {
let service = service.clone();
tokio::spawn(async move {
// 自动分发该 Stream 上的所有 RPC 请求
service.serve(bi_stream).await;
});
}
});
}
Ok(())
}use nitrogen_quic::QuicConnection;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let connection = QuicConnection::connect("127.0.0.1:4433".parse()?).await?;
let bi_stream = connection.open_bidirectional_stream().await?;
// 初始化自动生成的强类型 Client
let client = CalculatorServiceClient::new(bi_stream);
// 发起异步 RPC 调用
let sum = client.add(100, 200).await?;
println!("100 + 200 = {}", sum);
let status = client.ping().await?;
println!("Server status: {}", status);
Ok(())
}确保本地已安装 Rust 1.75+ 工具链:
# 检查全部成员包编译状态
cargo check --workspace
# 运行代码测试
cargo test --workspace
# 格式化代码
cargo fmt --all本项目采用 MIT 许可证 开源。