譯者 | 布加迪
審校 | 重樓
51CTO讀者成長計劃社群招募,咨詢小助手(微信號:TTalkxiaozhuli)
HTTP利用客戶端/服務器架構來傳輸信息和數據。Rust等服務器端編程語言的特性之一是,開發用于與基于HTTP的服務交互的服務器和客戶端應用程序。
Rust因其安全性、性能和可靠性等特性而適合構建HTTP服務器系統。Rust的第三方庫(比如Actix和Rocket)因構建能夠處理高流量的復雜Web服務器而大受歡迎。
一、為什么應該使用Rust進行HTTP Web服務器開發?
Rust在Web服務器開發方面大受歡迎,因為該語言的一些特性正是構建大多數Web服務器所需要的。
使用Rust可以確保應用程序有效擴展,使該語言成為構建高性能應用程序的理想語言。以下是考慮為Web服務器及其他服務器端應用程序使用Rust的幾個具體原因。
1.Rust的高性能
高性能是Rust成為構建HTTP Web服務器絕佳選擇的原因之一。Rust提供了對系統資源(包括內存和CPU)的低級訪問,使您能夠編寫比其他服務器端語言使用更少資源運行得更快的代碼。
此外,Rust的所有權機制不需要編譯時收集垃圾,這是一些服務器端語言速度較慢的原因之一。
2.安全和保障
Rust的內存管理所有權機制使得該語言對于Web服務器開發而言很安全。您不會遇到可能導致內存泄漏及其他安全漏洞的空指針或懸空指針引用。
Rust的所有權機制可以防止這些常見錯誤,為您的服務器和應用程序確保安全。Rust還專注于防止緩沖區溢出及其他與內存相關的錯誤。
3.并發性
并發性是指能夠以無序的方式運行程序的多個單元而不影響輸出。并發程序的輸出應該與異步程序的輸出相同。
并發性會顯著影響應用程序的性能,因為服務器需要同時處理多個請求。Rust支持與輕量級線程模型共存。
Rust中并發編程的優勢在于,所有權機制讓您可以編寫線程安全的代碼,不需要鎖及其他同步原語。
4.Rust提供現代工具
Rust標準庫和Rust生態系統中的第三方軟件包為有效的Web服務器開發提供了現代工具。
Rust的軟件包管理器Cargo簡化了依賴項管理和構建流程。此外,Rust還通過Rust Analyzer等工具提供了出色的IDE支持,這類工具提供了無縫代碼補全、錯誤高亮顯示及其他特性。
二、Actix庫和Rocket庫概述
Rust的標準庫擁有構建Web服務器所需的大部分實用程序。像Rocket和Actix這樣的第三方庫簡化了用Rust服務器端應用程序的工作。
Actix和Rocket是流行的Rust Web框架,但它們的庫在設計和特性上有所不同。
Rocket是一種高級Web框架,注重生產力和易用性。Rocket為使用Rust構建Web應用程序提供了大量的抽象和語法元素。Rocket也因其強大的類型和直觀的API設計而頗受歡迎。
您可以在Cargo.toml文件中添加Rocket作為項目依賴項,從而開始使用Rust構建Web應用程序:
[dependencies]
rocket = "0.4.11"
另一方面,Actix-web是一個注重性能和可擴展性的低級框架。Actix利用了基于actor的并發模型,提供了非阻塞I/O,這使得該軟件包成為構建高性能Web應用程序的理想選擇。
在Cargo.toml文件的依賴項部分中添加Actix作為項目依賴項:
[dependencies]
actix-web = "4.3.1"
為項目選擇一個庫將取決于您項目的規范、庫的特性以及您在使用Rust和HTTP方面的經驗。
三、使用Rust構建簡單的Web服務器
在創建Rust項目并將任何Rocket或Actix框架添加到Cargo.toml文件中的項目依賴項之后,您已準備好開始使用Rust構建Web服務器了。
使用Actix構建簡單的Web服務器
使用Rust構建Web服務時,您可以為請求使用序列化器。
Serde是一個流行的Rust庫,用于在Rust類型與JSON、YAML和TOML等數據格式之間序列化和反序列化數據。Serde提供了一個框架,用于定義Rust數據結構與其他數據格式的對應表示之間的數據轉換。
下面是為您的項目添加Serde作為第三方軟件包的指令。
[dependencies]
serde = { version = "1.0.159" , features = ["derive"] }
一旦您添加了Serde和Actix作為項目依賴項,就可以用Rust生成基本的Web服務器。下面介紹了如何創建一個簡單的Hello World! Web服務器,使用Actix將字符串寫入到客戶端:
首先,從actix_web庫和serde庫導入必要的模塊和類型:
use actix_web::{get, web, App, HttpResponse, HttpServer, Responder};
use serde::{Deserialize, Serialize};
您將使用serde用構件(struct)將消息序列化到客戶端。serde將為客戶端將構件轉換成JSON。下面是該消息的構件:
#[derive(Debug, Serialize, Deserialize)]
struct Message {
message: String,
}
現在您可以為端點定義處理程序(handler)函數。在處理程序函數的頂部,您可以為自定義行為添加裝飾符:
#[get("/")]
async fn hello() -> impl Responder {
HttpResponse::Ok().json(Message {
message: "Hello, World!".to_owned(),
})
}
hello處理程序函數處理GET請求。該函數返回實現來自Actix軟件包的Responder特征的類型。
HttpResponse::Ok()類型的JSON方法接受Serde在底層處理的構件實例,并將響應返回給客戶端。
定義端點后,您可以啟動服務器實例,并將端點掛載到路由上。
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| App::new().service(hello))
.bind("127.0.0.1:8080")?
.run()
.await
}
HttpServer::new函數是一個新的服務器實例。main函數啟動,服務器用新的應用程序實例掛載hello處理程序函數。bind方法將服務器綁定到指定的URL,run函數運行服務器。
四、使用Rocket構建簡單的Web服務器
Rocket很簡約,所以您可以構建簡單的Web服務器,無需任何依賴項(除了Rocket庫外)。
下面介紹如何使用Rocket創建帶有Hello World!端點的簡單服務器:
首先,為服務器導入必要的依賴項。
#![feature(proc_macro_hygiene, decl_macro)]
#[macro_use]
extern crate rocket;
// imports from the Rocket crate
use rocket::response::content;
use rocket::State;
#![feature(proc_macro_hygiene, decl_macro)]屬性為Rocket框架啟用了Rust實驗特性。#[macro_use]屬性從Rocket模塊導入宏。
下面是一個處理程序函數,接到請求時提供html:
#[get("/")]
fn hello_world() -> content::Html<&'static str> {
content::Html("<h1>Hello, world!</h1>")
}
hello_world函數返回一個HTML靜態字符串,含有content:: HTML函數。
下面是服務器的配置構件聲明(Rocket框架約定):
struct Config {
port: u16,
}
#[get("/port")]
fn port(config: State<Config>) -> String {
format!("Server running on port {}", config.port)
}
運行服務器時,可以向/port端點請求端口狀態。
最后,您將使用ignite函數創建一個服務器實例。添加配置、掛載路由,并啟動服務器:
fn main() {
let config = Config { port: 8000 };
rocket::ignite()
.manage(config)
.mount("/", routes![hello_world, port])
.launch();
}
config變量是config構件的一個實例。ignite函數啟動服務器實例,manage方法為服務器添加配置,mount方法在基本路由上掛載處理程序函數。最后,launch方法啟動服務器以偵聽指定的端口。
五、借助WASM使用Rust構建功能強大的Web應用程序
WebAssembly(WASM)是一種二進制指令格式,是為了在瀏覽器及其他設備上執行而設計的。WASM提供了一種低級字節碼格式,Rust等高級編程語言可以將其用作編譯目標。
借助WASM,您可以將Rust代碼編譯成大多數流行瀏覽器都可以執行的二進制格式。WASM為使用Rust構建健壯的Web應用程序(包括全棧Web應用程序)提供了無限的可能。
原文鏈接:https://www.makeuseof.com/build-http-web-server-in-rust/