博客 / 詳情

返回

Rust 與 Go,後端開發的下一個五年,誰是更穩的選擇?

開發沒有那麼容易,每個後端有它的脾氣,它不關心業務的快速變化,只關心自身的穩定和高效。

那麼在未來幾年,在高併發、低延遲的新興後端領域,Rust 和 Go,誰會成為更主流的選擇?我個人認為,這不在於哪個語言更時髦,而在於誰的架構性成本更低。

image.png

核心差異:編譯時的嚴謹 vs. 運行時的靈活性

Rust 和 Go 的設計哲學,從一開始就走向了兩個不同的方向。

  • Rust 選擇的是一條“先難後易”的路。它的編譯器非常嚴格,尤其是所有權和借用檢查機制,會在編譯階段就把潛在的內存安全問題全部暴露出來。這個過程對新手來説確實有不小的學習曲線,但一旦編譯通過,程序在運行時的穩定性和性能表現會非常可靠。它沒有垃圾回收(GC),這意味着不會有因GC掃描而導致的不可預測的延遲暫停。
  • Go 則走了另一條路:“快速上手,快速產出”。它的語法簡潔,工具鏈完善,特別是goroutine讓併發編程變得前所未有的簡單。開發者可以很快地將業務邏輯轉化為可運行的服務。這種高效率的背後,是Go語言運行時自帶的垃圾回收機制。在大多數情況下,Go的GC表現得相當不錯,但在面對流量洪峯或大量瞬時內存分配的場景時,GC的“Stop-the-world”暫停仍然可能引發P99延遲的抖動。

這本質上是兩種不同權衡:一種是用前期的開發投入換取運行時的極致性能和可預測性;另一種是用運行時的些許不確定性,換取極高的開發效率和更低的入門門檻。

性能場景對比

比如一個很常見的後端任務:接收一個JSON格式的POST請求,進行一些數據處理,然後返回一個新的JSON響應。

在這個場景下,兩種語言的表現通常會呈現一種規律:

  • Go (1.22) :我用Go寫這個功能可能只需要很短的時間。服務在常規負載下運行良好,響應迅速。但當併發請求量急劇上升時,通過監控工具,就會觀察到延遲曲線出現一些細小的毛刺,內存佔用也會隨請求量線性增長。
  • Rust (基於tokio) :用Rust實現同樣的功能,可能需要花更多時間去處理數據的生命週期和所有權問題,確保代碼能通過編譯器的檢查。但服務部署後,它的延遲曲線會很平滑,即使在高壓下,性能表現也始終如一,內存佔用非常穩定。

Rust 是把優化工作前置到了編碼和編譯階段,而Go則讓開發者先快速實現功能,再根據運行時的性能表現進行針對性優化。

從代碼的細節來看

我們來看一下實現相同功能的兩段代碼。

Go:清晰直觀,關注業務

package main

import (
        "encoding/json"
        "fmt"
        "log"
        "net/http"
        "time"
)

type RequestPayload struct {
        Name  string `json:"name"`
        Value int    `json:"value"`
}

type ResponsePayload struct {
        ID      int64  `json:"id"`
        Message string `json:"message"`
}

func handleRequest(w http.ResponseWriter, r *http.Request) {
        if r.Method != http.MethodPost {
                http.Error(w, "Only POST method is allowed", http.StatusMethodNotAllowed)
                return
        }

        var reqPayload RequestPayload
        if err := json.NewDecoder(r.Body).Decode(&reqPayload); err != nil {
                http.Error(w, "Bad JSON format", http.StatusBadRequest)
                return
        }

        respPayload := ResponsePayload{
                ID:      time.Now().UnixNano(),
                Message: fmt.Sprintf("hello %s", reqPayload.Name),
        }

        w.Header().Set("Content-Type", "application/json")
        if err := json.NewEncoder(w).Encode(respPayload); err != nil {
                log.Printf("Failed to encode response: %v", err)
        }
}

func main() {
        http.HandleFunc("/api/process", handleRequest)
        fmt.Println("Go server listening on :8080")
        if err := http.ListenAndServe(":8080", nil); err != nil {
                log.Fatalf("Server failed to start: %v", err)
        }
}

這段Go代碼的邏輯非常直接,核心就是解碼、處理、編碼。開發者可以把注意力完全放在業務流程上。但在這個過程中,json.Decodejson.Encode等操作會隱式地進行內存分配,這些都是未來GC需要處理的對象。

Rust:嚴謹精密,掌控資源

首先,Cargo.toml 依賴配置:

[dependencies]
axum = "0.7"
tokio = { version = "1", features = ["full"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
chrono = { version = "0.4", features = ["serde"] }

然後是實現代碼:

use axum::{routing::post, Json, Router};
use serde::{Deserialize, Serialize};
use std::net::SocketAddr;
use tokio;

#[derive(Deserialize)]
struct RequestPayload {
    name: String,
    value: i32,
}

#[derive(Serialize)]
struct ResponsePayload {
    id: i64,
    message: String,
}

async fn handle_request(Json(payload): Json<RequestPayload>) -> Json<ResponsePayload> {
    let message = format!("hello {}", payload.name);

    let response = ResponsePayload {
        id: chrono::Utc::now().timestamp_nanos_opt().unwrap_or(0),
        message,
    };
    
    Json(response)
}

#[tokio::main]
async fn main() {
    let app = Router::new().route("/api/process", post(handle_request));

    let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
    println!("Rust server listening on {}", addr);
    
    let listener = tokio::net::TcpListener::bind(addr).await.unwrap();
    axum::serve(listener, app).await.unwrap();
}

Rust的代碼在結構上需要更多的思考,比如異步運行時和框架的選擇。但它帶來的好處是,所有的數據傳遞和內存使用都在編譯器的嚴格監督之下,開發者對資源的掌控力更強,從而避免了運行時的意外。

Go VS Rust,Pick 誰?

什麼時候會更傾向於Go?

  • 在構建內部系統、運維工具、以及大部分業務邏輯複雜的CRUD應用時,Go的開發效率是巨大的優勢。它的生態成熟,招聘相對容易,能讓團隊快速響應業務需求。

什麼時候會選擇Rust?

  • 對於那些直接面向用户、對性能和資源消耗有嚴苛要求的核心服務,我會選擇Rust。例如,API網關、底層中間件、實時計算引擎等。在這些領域,可預測的低延遲和內存效率至關重要。

對未來五年的看法

我認為,Go和Rust並不會是誰取代誰的關係,而是會在各自擅長的領域裏變得更加重要。

  • Go 將繼續作為雲原生時代的核心語言之一,在微服務和業務後端領域保持其強大影響力。
  • Rust 則會在高性能計算、系統編程和基礎設施領域佔據越來越重要的位置,成為追求極致性能和安全性的團隊的首選。

動手實踐是最好的檢驗方式

偉人曾經説過,實驗是檢驗真理的唯一標準,所以最好的方式還是親手實踐一下,感受兩種語言在開發體驗和運行表現上的真實差異。

但環境配置往往讓人抓耳撓腮。安裝Go,再安裝Rust,管理不同版本和依賴,尤其是在一個團隊裏,有的人用macOS,有的人用Windows,環境不統一很容易在協作中產生不必要的問題。

ServBay 這樣的工具就非常有用了。

ServBay 是一個集成的本地開發環境工具,支持macOS和Windows。它能一鍵安裝和管理Go、Rust以及Python、PHP、Node.js等多種開發環境,並且各個環境之間是隔離的,不會互相干擾。

image.png

這樣一來,無論是想快速驗證一個Go的Web服務想法,還是想深入學習Rust的所有權模型,都不再被繁瑣的環境配置所困擾。它提供了一個統一、乾淨的實驗平台,讓我們可以把精力真正集中在代碼和架構的探索上。

image.png

最終選擇哪門語言,其實是選擇在項目的哪個階段投入更多精力:是前期的嚴謹設計與實現,還是後期的性能調優與維護。通過ServBay這樣的工具親手嘗試,或許能幫我們更快地找到適合自己項目和團隊的答案。

user avatar u_16213658 頭像 u_2874575 頭像 zhujiu 頭像 onlythinking 頭像
4 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.