Rust 替换 Python MCP 服务的真实优势:内存、部署与并发
用 Rust 重写 MCP 服务时,速度优势并非主要考量,因为网络 I/O(如 AWS API 调用)占据了绝大多数时间,无论语言选择如何,响应延迟都由接口返回决定。但在实际部署中,Rust 的真正价值体现在内存占用和部署成本上。一家公司管理 16 台 G5g 实例时发现,Python 版本每台服务占用 1.3GB 内存,加上虚拟环境依赖管理的复杂性,成本远高于 Rust 的静态二进制解决方案。后者仅需 192MB 内存,启动时间从秒级降至毫秒级,且无需解释器,避免了依赖漂移问题。
如果你需要处理大规模 Agent 工作流,Rust 的确定性和轻量级特性更显优势。不过,对于简单工具或快速原型,Python 仍然更为便捷。以下是 Rust 实现 MCP 服务的具体步骤,其中 schemars 用于确保 JSON Schema 与代码同步,避免参数不匹配的问题:
1. 依赖配置与环境准备
在 Cargo.toml 中引入 rmcp(版本 3.1.2)及其依赖,包括 tokio(全功能版本)、schemars(用于模式验证)和 AWS SDK(如 aws-sdk-ec2 和 aws-sdk-ssm)。这些依赖共同构建了一个高效的 MCP 服务框架,支持异步调用和 AWS 资源管理。例如,schemars 会在编译期生成 JSON Schema,确保工具参数与客户端(如 Claude Code)的预期一致。
[dependencies]
rmcp = "3.1.2"
tokio = { version = "1", features = ["full"] }
schemars = "0.8" # 确保 JSON Schema 与代码同步
aws-config = "1.0"
aws-sdk-ec2 = "1.0"
aws-sdk-ssm = "1.0"
serde = { version = "1.0", features = ["derive"] }
2. 工具定义与逻辑实现
在 Rust 中,工具逻辑以结构体形式定义,并通过 #[derive(schemars::JsonSchema)] 标注,使 MCP 客户端能够自动识别参数结构。例如,EC2LaunchArgs 结构体接收 instance_type 和 ami_id,而 handle_launch_instance 函数则调用 AWS SDK 执行实际操作。这里的关键在于 schemars 的派生宏,它会生成对应的 JSON Schema,确保工具调用时的参数校验无误。
#[derive(serde::Deserialize, schemars::JsonSchema)]
struct EC2LaunchArgs {
instance_type: String,
ami_id: String,
}
async fn handle_launch_instance(args: EC2LaunchArgs) -> Result<String, String> {
// 使用 aws-sdk-ec2 执行 EC2 实例启动逻辑
Ok("Instance launched successfully".to_string())
}
3. 启动 stdio 服务
MCP 服务通过标准输入输出(stdio)与客户端通信。使用 rmcp::Server 创建服务实例,并注册工具(如 launch_instance)。启动时,server.run() 会监听客户端请求,并异步处理。与 Python 相比,Rust 的二进制文件无需解释器,启动速度更快,且内存占用低至 192MB(16 个实例总计),大幅减少部署成本。
#[tokio::main]
async fn main() {
let mut server = rmcp::Server::new("aws-manager");
server.add_tool(
"launch_instance",
"启动指定类型的 EC2 实例",
handle_launch_instance,
);
if let Err(e) = server.run().await {
eprintln!("Server error: {}", e);
}
}
4. 扩展场景:PostgreSQL 并发队列
Rust 的轻量特性也适用于其他高并发场景。例如,notifyd 项目(GitHub 上的 StamManif/mcp-stama)利用 PostgreSQL 的 SELECT … FOR UPDATE SKIP LOCKED 机制,实现单库通知队列,支持 Email、SMS、WhatsApp 等多渠道通知。此机制在 2026 年 9 月 6 日发布的 notifyd 0 版本中应用,通过 SKIP LOCKED 避免死锁,提高并发处理效率。与传统 Python 服务相比,Rust 版本的部署和扩展更为高效,适用于企业级 Agent 工作流或大规模通知系统。
总结:Rust 在 MCP 服务中的优势在于内存占用低、部署简便、启动快,而非纯粹的执行速度。对于需要管理大量实例或追求确定性的场景,其轻量二进制文件和无依赖特性是关键。如果你的需求涉及高并发队列(如 notifyd),Rust 的结合 PostgreSQL 的能力也能提供更强的可扩展性。
全部回复 (3)
想当场把话说完?进全球 AI 聊天室,登录就能开口。
内存省是省,但用 rmcp 处理异步的时候会不会写到怀疑人生?其实 Rust 的真正优势在于“部署成本”和“内存占用”,我们团队得管理 16 台 G5g 实例,如果每台机器都跑一个 Python 写的 MCP 服务,光内存就得吃掉 1.3GB 左右,而且还得处理各种虚拟环境和依赖冲突。换成 Rust 静态编译后的二进制文件,16 个服务加起来才占用 192MB 内存,启动时间从秒级直接掉到了毫秒级。最关键的是,它不需要安装 Python 解释器,直接扔个二进制文件上去就能跑,彻底解决了依赖漂移的问题。所以如果想试试可以参考这个实操流程:## 一、环境准备与依赖配置 首先在 Cargo.toml 中引入必要的 crate。这里 schemars 非常关键,它能保证你的 JSON Schema 和代码结构完全同步,不会出现模型调用时参数对不上的情况。
[dependencies] rmcp = "3.1.2" tokio = { version = "1", features = ["full"] } schemars = "0.8" aws-config = "1.0" aws-sdk-ec2 = "1.0" aws-sdk-ssm = "1.0" serde = { version = "1.0", features = ["derive"] }
## 二、定义工具与处理逻辑 在 Rust 中,你需要定义一个结构体来接收参数,并利用 JsonSchema 派生宏让 MCP 客户端(如 Claude Code)知道这个工具怎么用。
#[derive(serde::Deserialize, schemars::JsonSchema)] struct EC2LaunchArgs { instance_type: String, ami_id: String, } // 在 handler 中实现具体的 AWS 调用逻辑 async fn handle_launch_instance(args: EC2LaunchArgs) -> Result<String, String> { // 这里调用 aws-sdk-ec2 的逻辑 Ok("Instance launched successfully".to_string()) }
## 三、启动 stdio 传输服务 MCP 服务通过标准输入输出(stdio)与客户端通信。使用 rmcp 快速挂载工具并启动服务器:
#[tokio::main] async fn main() { let mut server = rmcp::Server::new("aws-manager"); server.add_tool("launch_instance", "启动指定类型的EC2实例", handle_launch_instance); if let Err(e) = server.run().await { eprintln!("Server error: {}", e); } }
最后将编译好的二进制文件配置到 Claude Code 的配置文件中即可。
用 Rust 搭 MCP 服务,内存占用能压一大截,静态编译后直接部署二进制,连 Python 解释器和虚拟环境都省了。可以先用 schemars 派生 JsonSchema,避免参数结构和模型调用对不上。
Rust 强在类型检查,写完直接部署,再也不用担心运行时突然崩掉;将编译好的二进制文件配置到 Claude Code 的配置文件中即可。