Tonic Rust 完整指南:gRPC 框架安装、方法与实战示例

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

什么是 Tonic?为什么需要它?

Tonic 是一个现代化、高性能的 Rust 语言 gRPC 服务器与客户端实现库。它基于 Tokio 异步运行时和 Hyper HTTP/2 框架构建,提供极致性能并完全兼容 gRPC 标准。

Tonic 的核心优势:

  • 原生异步支持 — 完全基于 async/await,无阻塞操作
  • 类型安全 — 编译时从 proto 文件自动生成代码
  • 支持所有 gRPC 模式 — unary、服务端流式、客户端流式、双向流式
  • 无缝集成 Rust 生态 — 与 Tokio、Tower、Hyper 等流行 crate 完美协作
  • 卓越性能 — 业界最快的 gRPC 框架之一

该库已被 Discord、Microsoft、Amazon 等公司用于生产环境。Tonic 是构建微服务、API 网关以及任何需要高效服务间通信的分布式系统的理想选择。

安装 Tonic

使用 Tonic 需要安装几个依赖项。将它们添加到您的 Cargo.toml 中:

[dependencies]
tonic = "0.12"
prost = "0.13"
tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] }

[build-dependencies]
tonic-build = "0.12"

依赖说明:

  • tonic — gRPC 核心库
  • prost — Rust 的 Protocol Buffers 代码生成器
  • tokio — 异步运行时
  • tonic-build — 构建时用于编译 .proto 文件

此外,您还需要安装 Protocol Buffers 编译器 protoc。在 Ubuntu/Debian 上:

sudo apt install protobuf-compiler

在 macOS 上:

brew install protobuf

在 Windows 上,请从官方仓库下载二进制文件并将其添加到 PATH 环境变量中。

快速入门:gRPC Hello World

让我们创建一个简单的服务,接收名字并返回问候语。

步骤 1. 创建 proto/helloworld.proto 文件:

syntax = "proto3";

package helloworld;

service Greeter {
    rpc SayHello (HelloRequest) returns (HelloReply);
}

message HelloRequest {
    string name = 1;
}

message HelloReply {
    string message = 1;
}

步骤 2. 在项目根目录创建 build.rs:

fn main() -> Result<(), Box> {
    tonic_build::compile_protos("proto/helloworld.proto")?;
    Ok(())
}

步骤 3. 实现服务器端(src/server.rs):

use tonic::{transport::Server, Request, Response, Status};
use hello_world::greeter_server::{Greeter, GreeterServer};
use hello_world::{HelloRequest, HelloReply};

pub mod hello_world {
    tonic::include_proto!("helloworld");
}

#[derive(Default)]
pub struct MyGreeter;

#[tonic::async_trait]
impl Greeter for MyGreeter {
    async fn say_hello(
        &self,
        request: Request,
    ) -> Result, Status> {
        let name = request.into_inner().name;
        let reply = HelloReply {
            message: format!("你好,{}!", name),
        };
        Ok(Response::new(reply))
    }
}

#[tokio::main]
async fn main() -> Result<(), Box> {
    let addr = "[::1]:50051".parse()?;
    let greeter = MyGreeter::default();

    Server::builder()
        .add_service(GreeterServer::new(greeter))
        .serve(addr)
        .await?;

    Ok(())
}

步骤 4. 创建客户端

推荐