首頁 後端開發 Python教學 使用 Zig 和 Python 的高效能且可擴展的 Web 伺服器

使用 Zig 和 Python 的高效能且可擴展的 Web 伺服器

Oct 07, 2024 am 06:12 AM

前言

我對軟體開發充滿熱情,特別是按照人體工學創建軟體系統的難題,該系統可以解決最廣泛的問題,同時盡可能減少妥協。我還喜歡將自己視為系統開發人員,根據 Andrew Kelley 的定義,這意味著有興趣完全理解他們正在使用的系統的開發人員。在這篇部落格中,我與您分享我解決以下問題的想法:建立可靠且高效能的全端企業應用程式。這是一個很大的挑戰,不是嗎?在部落格中,我專注於「高效能網頁伺服器」部分 - 我覺得我可以在這方面提供一個新鮮的視角,因為其餘部分要么是眾所周知的,要么我沒有什麼可補充的。

一個重要的警告 - 將會有沒有程式碼範例,我還沒有實際測試過這一點。是的,這是一個重大缺陷,但實際上實現這一點需要花費很多時間,而我沒有時間,在發布有缺陷的部落格和根本不發布它之間,我堅持前者。我們已警告您。

A performant and extensible Web Server with Zig and Python

我們將用哪些部分來組裝我們的應用程式?

  • 一個您熟悉的前端,但如果您想要最小的依賴性 - WASM 形式的 HTMX 中有 Zig。
  • Zig Web 伺服器,與 Linux 核心緊密整合。這是性能部分,我將在本部落格中重點介紹。
  • Python 後端,與 Zig 整合。這是複雜的部分。
  • 與 Temporal 和 Flowable 等持久執行系統整合。這有助於提高可靠性,並且不會在部落格中討論。

確定了我們的工具,讓我們開始吧!

協程是否被高估了?

Zig 沒有對協程的語言等級支援:( 而協程是建構每個高效能 Web 伺服器的基礎。那麼,嘗試沒有意義嗎?

等一下,讓我們先戴上系統程式設計師的帽子。協程不是靈丹妙藥,沒有什麼是靈丹妙藥。涉及的實際好處和缺點是什麼?

眾所周知,協程(使用者空間執行緒)更加輕量級且速度更快。但具體是透過什麼方式呢? (這裡的答案大部分都是猜測,請持保留態度並親自測試一下)

  • 預設情況下,它們一開始的堆疊空間較小(2KB 而不是 4MB)。但這可以手動調整。
  • 它們更好地與用戶空間調度程序配合。由於核心調度程序是搶佔式的,因此執行緒執行的任務會被分配時間片。如果實際任務不適合切片 - 一些 CPU 時間就會被浪費。與 Goroutines 不同,Goroutines 將不同 Goroutines 執行的盡可能多的微任務放入操作系統線程的同一時間片中。

A performant and extensible Web Server with Zig and Python

例如,Go 運行時將 goroutine 重複使用到作業系統執行緒上。執行緒共享頁表以及其他行程擁有的資源。如果我們在混合中引入CPU 隔離和親和性- 線程將在各自的CPU 核心上持續運行,所有作業系統資料結構將保留在記憶體中,無需換出,用戶空間調度程序將CPU 時間分配給goroutine精度,因為它使用協作多任務模型。競爭還可能嗎?

效能的提升是透過將執行緒的作業系統級抽象放在一邊並用 goroutine 的抽象來代替來實現的。但翻譯中沒有遺失任何內容嗎?

我們可以和核心合作嗎?

我認為獨立執行單元的「真正」作業系統級抽象甚至不是線程 - 它實際上是作業系統進程。實際上,這裡的差異並不那麼明顯——區分執行緒和進程的只是不同的 PID 和 TID 值。至於檔案描述子、虛擬記憶體、訊號處理程序、追蹤資源 - 這些是否對於子進程是獨立的,在「複製」系統呼叫的參數中指定。因此,我將使用術語「進程」來表示擁有自己的系統資源的執行線程 - 主要是 CPU 時間、記憶體、開啟的檔案描述符。

A performant and extensible Web Server with Zig and Python

為什麼這很重要?每個執行單元對系統資源都有自己的需求。每個複雜的任務都可以分解為多個單元,每個單元都可以提出自己的、可預測的資源請求 - 記憶體和 CPU 時間。沿著子任務樹越往上走,您就會看到更一般的任務 - 系統資源圖形成一條帶有長尾的鐘形曲線。您有責任確保尾部不會超出系統資源限制。但這是如何做到的呢?如果實際上超出了該限制會發生什麼?

如果我們使用單一進程和多個協程的模型來執行獨立任務,當一個協程超出記憶體限制時 - 因為記憶體使用情況是在進程層級追蹤的,整個進程將被終止。這是最好的情況 - 如果您使用 cgroup(Kubernetes 中的 pod 會自動出現這種情況,每個 pod 都有一個 cgroup) - 整個 cgroup 都會被殺死。建立一個可靠的系統需要考慮到這一點。那麼CPU時間呢?如果我們的服務同時受到許多運算密集型請求的影響,它將變得無回應。然後是截止日期、取消、重試、重新開始。

對於大多數主流軟體堆疊來說,處理這些場景的唯一現實方法是在系統中保留「脂肪」 - 一些未使用的資源用於鐘形曲線的尾部- 並限制並發請求的數量- 這再次導致未使用的資源。即使如此,我們偶爾也會被 OOM 殺死或變得無響應 - 包括恰好與異常值處於同一進程中的「無辜」請求。這種妥協對許多人來說是可以接受的,並且在實踐中足以很好地服務於軟體系統。但我們能做得更好嗎?

並發模型

由於每個進程都會追蹤資源使用情況,因此理想情況下我們會為每個小的、可預測的執行單元產生一個新進程。然後我們設定 CPU 時間和記憶體的 ulimit - 我們就可以開始了! ulimit 具有軟限制和硬限制,這將允許進程在達到軟限制時優雅終止,如果沒有發生,可能是由於錯誤 - 在達到硬限制時強制終止。不幸的是,在 Linux 上產生新進程的速度很慢,許多 Web 框架以及其他系統(例如 Temporal)不支援每個請求產生新進程。此外,進程切換的成本更高——這可以透過 CoW 和 CPU 固定來緩解,但仍然不理想。不幸的是,長時間運行的進程是不可避免的現實。

A performant and extensible Web Server with Zig and Python

我們離短期行程的乾淨抽象越遠,我們需要處理的作業系統層級工作就越多。但也有一些好處 - 例如利用 io_uring 在許多執行緒之間進行批次 IO。事實上,如果一個大任務是由子任務組成的——我們真的關心它們各自的資源利用率嗎?僅用於分析。但如果對於大型任務,我們可以管理(切斷)資源鐘形曲線的尾部,那就足夠了。因此,我們可以產生與我們希望同時處理的請求一樣多的進程,讓它們長期存在,並且只需為每個新請求重新調整 ulimit 即可。因此,當請求超出其資源限制時,它會收到作業系統訊號並能夠正常終止,而不影響其他請求。或者,如果高資源使用率是故意的,我們可以告訴客戶端支付更高的資源配額。我覺得聽起來不錯。

但是與每個請求的協程方法相比,效能仍然會受到影響。首先,複製進程記憶體表的成本很高。由於該表包含對記憶體頁的引用,因此我們可以使用大頁,從而限制要複製的資料的大小。這只能透過低階語言直接實現,例如 Zig。此外,作業系統層級多工處理是搶佔式的而不是協作式的,這總是效率較低的。或者是嗎?

與 Linux 的協作多工處理

系統呼叫 sched_yield,它允許執行緒在完成其部分工作後放棄 CPU。看來還蠻合作的。有沒有辦法也要求給定大小的時間片?實際上,調度策略 SCHED_DEADLINE 是有的。這是一個即時策略,這意味著對於請求的CPU時間片,執行緒不間斷地運行。但是,如果切片溢位 - 搶佔就會啟動,並且您的執行緒將被換出並取消優先權。如果切片運作不足 - 執行緒可以呼叫 sched_yield 來發出提前完成的訊號,從而允許其他執行緒運行。這看起來是兩全其美——合作和先發制人的模式。

A performant and extensible Web Server with Zig and Python

一個限制是 SCHED_DEADLINE 執行緒無法分叉。這給我們留下了兩種並發模型- 要么每個請求一個進程,它為自己設置最後期限,並運行一個事件循環以實現高效的IO,要么一個從一開始就為每個微任務生成一個線程的進程,每個微任務設定自己的截止日期,並利用佇列相互通訊。前者較直接,但需要使用者空間中的事件循環,後者則較多利用核心。

兩種策略都達到了與協程模型相同的目的 - 透過與核心合作,可以讓應用程式任務以最小的中斷運行

Python 作為嵌入式腳本語言

這一切都是為了高效能、低延遲、低階的方面,而這正是 Zig 的閃光點。但當涉及到應用程式的實際業務時,靈活性比延遲更有價值。如果一個流程涉及真人簽署文檔,則電腦的延遲可以忽略不計。此外,儘管效能受到影響,物件導向語言為開發人員提供了更好的原語來對業務領域進行建模。在最遠的一端,像 Flowable 和 Camunda 這樣的系統允許管理和營運人員以更大的靈活性和更低的進入門檻對業務邏輯進行程式設計。像 Zig 這樣的語言對此沒有幫助,只會阻礙你。

A performant and extensible Web Server with Zig and Python

另一方面,Python 是最具活力的語言之一。類別、物件——它們都是底層的字典,可以在運行時按照你喜歡的方式進行操作。這會降低效能,但使得使用類別和物件以及許多巧妙的技巧對業務進行建模變得實用。 Zig 則相反 - Zig 中故意添加了一些巧妙的技巧,為您提供最大程度的控制。我們可以透過讓它們互通來結合它們的力量嗎?

確實可以,因為兩者都支援 C ABI。我們可以讓 Python 解釋器在 Zig 進程內運行,而不是作為單獨的進程運行,從而減少運行時成本和黏合程式碼的開銷。這進一步允許我們在 Python 中使用 Zig 的自訂分配器 - 設定一個區域來處理單一請求,從而減少(如果沒有消除)垃圾收集器的開銷,並設定記憶體上限。一個主要限制是 CPython 運行時產生用於垃圾收集和 IO 的線程,但我沒有發現任何證據表明它確實如此。透過使用 AbstractMemoryLoop 中的「context」字段,我們可以將 Python 連接到 Zig 中的自訂事件循環中,並進行每個協程記憶體追蹤。可能性是無限的。

結論

我們討論了並行性、並行性以及與作業系統核心的各種形式整合的優點。這項探索缺乏基準和程式碼,我希望它能透過提供的想法的品質來彌補。你嘗試過類似的事情嗎?你有什麼想法?歡迎回饋:)

進一步閱讀

  • https://linux.die.net/man/2/clone
  • https://man7.org/linux/man-pages/man7/sched.7.html
  • https://man7.org/linux/man-pages/man2/sched_yield.2.html
  • https://rigtorp.se/low-latency-guide/
  • https://eli.thegreenplace.net/2018/measuring-context-switching-and-memory-overheads-for-linux-threads/
  • https://hadar.gr/2017/lightweight-goroutines

以上是使用 Zig 和 Python 的高效能且可擴展的 Web 伺服器的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
<🎜>掩蓋:探險33-如何獲得完美的色度催化劑
2 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1677
14
CakePHP 教程
1430
52
Laravel 教程
1333
25
PHP教程
1278
29
C# 教程
1257
24
Python與C:學習曲線和易用性 Python與C:學習曲線和易用性 Apr 19, 2025 am 12:20 AM

Python更易學且易用,C 則更強大但複雜。 1.Python語法簡潔,適合初學者,動態類型和自動內存管理使其易用,但可能導致運行時錯誤。 2.C 提供低級控制和高級特性,適合高性能應用,但學習門檻高,需手動管理內存和類型安全。

學習Python:2小時的每日學習是否足夠? 學習Python:2小時的每日學習是否足夠? Apr 18, 2025 am 12:22 AM

每天學習Python兩個小時是否足夠?這取決於你的目標和學習方法。 1)制定清晰的學習計劃,2)選擇合適的學習資源和方法,3)動手實踐和復習鞏固,可以在這段時間內逐步掌握Python的基本知識和高級功能。

Python vs.C:探索性能和效率 Python vs.C:探索性能和效率 Apr 18, 2025 am 12:20 AM

Python在開發效率上優於C ,但C 在執行性能上更高。 1.Python的簡潔語法和豐富庫提高開發效率。 2.C 的編譯型特性和硬件控制提升執行性能。選擇時需根據項目需求權衡開發速度與執行效率。

Python vs. C:了解關鍵差異 Python vs. C:了解關鍵差異 Apr 21, 2025 am 12:18 AM

Python和C 各有優勢,選擇應基於項目需求。 1)Python適合快速開發和數據處理,因其簡潔語法和動態類型。 2)C 適用於高性能和系統編程,因其靜態類型和手動內存管理。

Python標準庫的哪一部分是:列表或數組? Python標準庫的哪一部分是:列表或數組? Apr 27, 2025 am 12:03 AM

pythonlistsarepartofthestAndArdLibrary,herilearRaysarenot.listsarebuilt-In,多功能,和Rused ForStoringCollections,而EasaraySaraySaraySaraysaraySaraySaraysaraySaraysarrayModuleandleandleandlesscommonlyusedDduetolimitedFunctionalityFunctionalityFunctionality。

Python:自動化,腳本和任務管理 Python:自動化,腳本和任務管理 Apr 16, 2025 am 12:14 AM

Python在自動化、腳本編寫和任務管理中表現出色。 1)自動化:通過標準庫如os、shutil實現文件備份。 2)腳本編寫:使用psutil庫監控系統資源。 3)任務管理:利用schedule庫調度任務。 Python的易用性和豐富庫支持使其在這些領域中成為首選工具。

科學計算的Python:詳細的外觀 科學計算的Python:詳細的外觀 Apr 19, 2025 am 12:15 AM

Python在科學計算中的應用包括數據分析、機器學習、數值模擬和可視化。 1.Numpy提供高效的多維數組和數學函數。 2.SciPy擴展Numpy功能,提供優化和線性代數工具。 3.Pandas用於數據處理和分析。 4.Matplotlib用於生成各種圖表和可視化結果。

Web開發的Python:關鍵應用程序 Web開發的Python:關鍵應用程序 Apr 18, 2025 am 12:20 AM

Python在Web開發中的關鍵應用包括使用Django和Flask框架、API開發、數據分析與可視化、機器學習與AI、以及性能優化。 1.Django和Flask框架:Django適合快速開發複雜應用,Flask適用於小型或高度自定義項目。 2.API開發:使用Flask或DjangoRESTFramework構建RESTfulAPI。 3.數據分析與可視化:利用Python處理數據並通過Web界面展示。 4.機器學習與AI:Python用於構建智能Web應用。 5.性能優化:通過異步編程、緩存和代碼優

See all articles