Rust:從基礎到高級
第 6 部分:測試、CI/CD 和生產
亞洲開發網
1. 發布設定檔優化
# Cargo.toml
[profile.release]
opt-level = 3 # Maximum optimization
lto = "fat" # Link-Time Optimization — binary nhỏ hơn, nhanh hơn
codegen-units = 1 # Single codegen unit — tối ưu tốt hơn
strip = true # Strip debug symbols
panic = "abort" # Không unwind — binary nhỏ hơn
[profile.dev]
opt-level = 0
debug = true
# Custom profile
[profile.profiling]
inherits = "release"
debug = true # Debug symbols nhưng optimized
strip = false
# Build size comparison
cargo build --release
ls -la target/release/my-app # ~5MB (stripped, LTO)
# Analyze binary size
cargo install cargo-bloat
cargo bloat --release --crates
2. 記憶體分配器
// jemalloc — tốt cho multi-threaded workloads
#[global_allocator]
static GLOBAL: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;
// mimalloc — tốt cho general purpose
// [dependencies]
// mimalloc = { version = "0.1", default-features = false }
#[global_allocator]
static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
| 分配器 | 使用案例 | 優點 |
| 系統(預設) | 一般 | 沒有額外的依賴 |
| 傑馬洛克 | 高並發伺服器 | 減少碎片和多線程 |
| 米馬洛克 | 一般,延遲敏感 | 快速、緊湊、跨平台 |
// Connection pooling
let pool = PgPoolOptions::new()
.max_connections(20)
.min_connections(5)
.max_lifetime(Duration::from_secs(1800))
.idle_timeout(Duration::from_secs(600))
.acquire_timeout(Duration::from_secs(5))
.connect(&database_url)
.await?;
// Request batching
use tokio::sync::mpsc;
use tokio::time::interval;
struct Batcher {
tx: mpsc::Sender<BatchItem>,
}
impl Batcher {
fn new(pool: PgPool) -> Self {
let (tx, mut rx) = mpsc::channel(1000);
tokio::spawn(async move {
let mut buffer = Vec::new();
let mut tick = interval(Duration::from_millis(100));
loop {
tokio::select! {
Some(item) = rx.recv() => {
buffer.push(item);
if buffer.len() >= 100 {
flush_batch(&pool, &mut buffer).await;
}
}
_ = tick.tick() => {
if !buffer.is_empty() {
flush_batch(&pool, &mut buffer).await;
}
}
}
}
});
Self { tx }
}
}
// String optimization — avoid allocation
fn process(input: &str) -> &str {
// Trả reference thay vì clone
input.trim()
}
// Cow — clone on write
use std::borrow::Cow;
fn normalize(input: &str) -> Cow<'_, str> {
if input.contains(' ') {
Cow::Owned(input.replace(' ', "_"))
} else {
Cow::Borrowed(input)
}
}
4. 生產檢查表
| 類別 | 專案 |
| 建構 | 啟用 LTO,單一代碼生成單元,剝離 |
| 分配器 | jemalloc 或 mimalloc |
| 記錄 | 追蹤 + JSON 格式 + RUST_LOG |
| 指標 | 普羅米修斯+格拉法納 |
| 健康 | /健康終點,準備度/活躍度 |
| 關閉 | 正常關閉 (SIGTERM) |
| 安全性 | 貨物審核、貨物拒絕 |
| 碼頭工人 | 多階段+distroless/scratch |
| 資料庫 | 連接池、遷移 |
| 持續整合/持續交付 | fmt、clippy、測試、審核、構建 |
恭喜您完成系列 Rust:從基礎到高級! 🎉