在互聯網的快速發展中,高性能、高效率和高安全性的網絡服務成為了各大互聯網基礎設施提供商的核心追求。Cloudflare 作為全球領先的互聯網安全和基礎設施公司,近期做出了一個重大技術決策:棄用長期使用的 Nginx,轉而采用其內部開發的基于 Rust 的新一代代理服務——Pingora。
一、棄用 Nginx 的原因
(一)架構限制影響性能
Nginx 作為一款高性能的 HTTP 和反向代理服務器,多年來一直是 Cloudflare 的核心組件之一。然而,隨著 Cloudflare 業務規模的迅速擴張,Nginx 的架構局限性逐漸顯現。Nginx 的 worker(進程)架構導致每個請求只能由單個 worker 處理,這不僅造成了 CPU 內核之間的負載不平衡,還使得執行 CPU 密集型或阻塞 I/O 任務的請求會減緩其他請求的速度。此外,Nginx 的連接池與單個 worker 相對應,限制了連接的重用率。當增加更多的 worker 進行擴展時,連接會分散在更多的孤立池中,導致連接重用率下降,增加了資源消耗。
(二)功能擴展困難
Nginx 雖然在 Web 服務器、負載均衡器或簡單的網關方面表現出色,但對于更高級、定制化的功能需求,其擴展性存在明顯不足。Cloudflare 在嘗試圍繞 Nginx 構建所需功能時,面臨著與上游代碼庫保持一致的挑戰,這并不容易實現。此外,Nginx 社區的活躍度有限,開發工作往往缺乏開源社區的支持和協作。
二、Pingora 的優勢
(一)性能提升
Pingora 采用 Rust 編程語言開發,Rust 的內存安全和高性能特性使其在處理高并發請求時表現優異。Pingora 的多線程架構允許跨所有線程共享連接,從而實現更好的連接重用率,減少了 TCP 和 TLS 握手的時間。實際數據顯示,Pingora 的 TTFB(第一個字節時間)中位數減少了 5 毫秒,第 95 百分位數減少了 80 毫秒。對于一個主要客戶,Pingora 將連接重用率從 87.1% 提高到 99.92%,減少了 160 倍的新連接。
(二)效率優化
在生產環境中,Pingora 在相同流量負載的情況下,消耗的 CPU 和內存資源分別減少了約 70% 和 67%。Rust 代碼的運行效率高于舊的 Lua 代碼,多線程模型也使得跨請求共享數據更加高效。
(三)安全性增強
Rust 的內存安全語義保護 Cloudflare 免受未定義行為的影響,使其相信服務將正確運行。這使得 Cloudflare 能夠更多地關注服務更改將如何與其他服務或客戶來源進行交互,以更高的節奏開發功能,而不用背負內存安全和難以診斷崩潰的問題。
三、Pingora 的使用示例
Cloudflare 官方提供了一個簡單的 Pingora 使用示例,展示了如何快速構建一個負載均衡器:
use pingora_core::services::background::background_service;
use pingora_core::server::configuration::Opt;
use pingora_core::server::Server;
use pingora_core::upstreams::peer::HttpPeer;
use pingora_core::Result;
use pingora_load_balancing::{health_check, selection::RoundRobin, LoadBalancer};
use pingora_proxy::{ProxyHttp, Session};
use std::sync::Arc;pub struct LB(Arc<LoadBalancer<RoundRobin>>);#[async_trait::async_trait]
impl ProxyHttp for LB {type CTX = ();fn new_ctx(&self) -> Self::CTX {}async fn upstream_peer(&self, _session: &mut Session, _ctx: &mut ()) -> Result<Box<HttpPeer>> {let upstream = self.0.select(b"", 256).unwrap();let peer = Box::new(HttpPeer::new(upstream, true, "one.one.one.one".to_string()));Ok(peer)}
}fn main() {let opt = Opt::from_args();let mut my_server = Server::new(Some(opt)).unwrap();my_server.bootstrap();let mut upstreams = LoadBalancer::try_from_iter(["1.1.1.1:443", "1.0.0.1:443"]).unwrap();let hc = health_check::TcpHealthCheck::new();upstreams.set_health_check(hc);upstreams.health_check_frequency = Some(std::time::Duration::from_secs(1));let background = background_service("health check", upstreams);let upstreams = background.task();let mut lb = pingora_proxy::http_proxy_service(&my_server.configuration, LB(upstreams));lb.add_tcp("0.0.0.0:6188");my_server.add_service(lb);my_server.add_service(background);my_server.run_forever();
}
在這個示例中,Pingora 使用 Rust 的異步編程特性,通過簡單的代碼實現了負載均衡器的基本功能。它展示了 Pingora 的靈活性和開發效率,同時也體現了 Rust 在處理高并發網絡服務時的優勢。
四、Pingora 的 GitHub 鏈接
Cloudflare 已經正式開源了 Pingora 框架,源代碼采用 Apache License,托管在 GitHub。以下是 Pingora 的 GitHub 倉庫鏈接,你可以在這里查看代碼、提交問題或參與貢獻:
- Pingora GitHub 倉庫地址:https://github.com/cloudflare/pingora
五、總結
Cloudflare 從 Nginx 轉向 Pingora 是一個具有里程碑意義的決策。Pingora 不僅在性能、效率和安全性方面顯著優于 Nginx,還為 Cloudflare 提供了更強大的功能擴展能力。隨著 Cloudflare 將 Pingora 開源,這一技術變革有望為整個互聯網行業帶來新的啟示和機遇,推動更多企業探索更高效、更安全的網絡服務解決方案。