iT邦幫忙

2025 iThome 鐵人賽

DAY 14
0
Rust

30天解鎖 Rust 開發者工具箱系列 第 14

「Day 14」Tokio 架構與生態

  • 分享至 

  • xImage
  •  

前言

昨天介紹了前端工程,yew,以 Rust 的方式進行前端工作的開發,後編譯成 wasm 的二進制檔案才丟到客戶端由遊覽器直接執行,跳過了JS的動態編譯與執行的過程,提供了近乎原生的網頁邏輯效能,是未來效能需求不斷成長下的值得考量的解決方案。

在介紹 Rust 的後端生態之前,tokio 架構與其生態系是一定要理解的。

Tokio 簡介

Tokio 是一個為 Rust 語言設計的事件驅動、非阻塞 I/O 平台,專為編寫網路應用程式而生 。它提供了一個多執行緒、工作竊取(work-stealing)的排程器,讓應用程式能以極低的開銷處理大量併發請求 。Tokio 的核心價值在於其快速、可靠與易用的特性,它利用 Rust 的記憶體安全模型來避免常見的程式錯誤,並透過 async/await 語法簡化了異步程式的開發複雜度 。  

Rust 的異步模型:Future, async/await 與 poll 狀態機

Rust 的異步模型由幾個核心概念組成,而 Tokio 則是驅動這個模型的執行引擎 。  

Future Trait:Future 是一個 trait,代表一個最終會產生值的異步計算。它本質上是一個狀態機,當執行器(Executor)對其進行輪詢(poll)時,它會回傳兩種狀態之一:Poll::Ready(value) 表示計算完成,或 Poll::Pending 表示尚未完成,需要稍後再次輪詢 。  

async fn.await:async fn 是一種語法糖,它會將一個函數轉換為實作 Future 的狀態機。呼叫 async fn 並不會立即執行,而是返回一個 Future 物件。.await 運算子則用於暫停當前 async 函數的執行,直到被等待的 Future 完成為止。在暫停期間,執行緒的控制權會交還給執行時(如 Tokio),使其能夠去執行其他已就緒的任務,從而避免了執行緒阻塞 。  

poll 狀態機:執行器會反覆呼叫 Future 的 poll 方法來推進其狀態。如果 poll 回傳 Pending,Future 會負責在未來準備就緒時通知執行器(透過一個名為 Waker 的機制),以便執行器可以再次排程並輪詢它 。這個「輪詢-等待通知-再次輪詢」的循環是整個異步模型的運作核心。  

Tokio 任務的生命週期

一個典型的 Tokio 任務經歷以下生命週期:

  • 派生 (Spawning):一個 Future 被傳遞給 tokio::spawn,Tokio 將其包裝成一個可排程的任務單元。
  • 執行與輪詢 (Execution & Polling):排程器將任務交給一個工作執行緒,該執行緒開始對 Future 進行 poll。
  • 暫停 (Suspension):當任務遇到一個無法立即完成的操作(例如等待網路數據)並 .await 時,poll 方法會回傳 Poll::Pending。任務的執行被暫停,並讓出執行緒的控制權 。  
  • 喚醒 (Waking):當等待的 I/O 資源準備就緒時,作業系統會通知 Tokio 的反應器(Reactor),反應器隨後會喚醒對應的任務 。  
  • 恢復 (Resumption):被喚醒的任務會被重新放入排程器的佇列中,等待下一次被工作執行緒輪詢並從上次暫停的地方繼續執行 。  
  • 完成 (Completion):這個「執行-暫停-喚醒-恢復」的循環會不斷重複,直到最外層的 Future 回傳 Poll::Ready,代表任務完成。

Tokio 生態系 (The Tokio Stack)

Tokio 不僅僅是一個執行時,它還包含了一整套用於建構生產級應用程式的函式庫,通常被稱為「Tokio 技術堆疊」 。  

  • Runtime:Tokio 的核心,提供了執行異步程式碼所需的一切,包括 I/O、計時器、檔案系統、同步原語和任務排程器 。  
  • Hyper:一個高效能的 HTTP/1 和 HTTP/2 客戶端與伺服器函式庫,是許多 Rust Web 框架的基礎 。  
  • Tonic:一個原生、樣板程式碼極少的 gRPC 客戶端與伺服器函式庫,建構於 Hyper 之上 。  
  • Tower:一個用於建構可靠客戶端和伺服器的模組化元件庫。它提供了重試、負載平衡、過濾和請求限制等中介軟體(middleware)功能 。  
  • Mio:一個在作業系統事件 I/O API(如 epoll, kqueue)之上的輕量級、可移植的抽象層,是 Tokio 反應器的底層基礎 。  
  • Tracing:一個用於應用程式和函式庫的結構化、事件驅動的日誌記錄與診斷框架 。  
  • Bytes:提供了一套豐富的工具,用於高效地操作位元組陣列,這在網路程式設計中至關重要 。  

上一篇
「Day 13」寫 Rust 寫到前端去~
系列文
30天解鎖 Rust 開發者工具箱14
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言