摘要:請求的多階段異步處理多階段異步處理請求與事件驅動架構是密切相關的,也就是說,請求的多階段異步處理只能基于事件驅動架構實現。
前言
最近在讀 Nginx 相關的書籍,做一下讀書筆記。
Nginx 作為業界知名的高性能服務器,被廣泛的應用。它的高性能正是由于其優秀的架構設計,其架構主要包括這幾點:模塊化設計、事件驅動架構、請求的多階段異步處理、管理進程與多工作進程設計、內存池的設計,以下內容依次進行說明。
模塊化設計高度模塊化的設計是 Nginx 的架構基礎。在 Nginx 中,除了少量的核心代碼,其他一切皆為模塊。
所有模塊間是分層次、分類別的,Nginx 官方共有五大類型的模塊:核心模塊、配置模塊、事件模塊、HTTP 模塊、mail 模塊。它們之間的關系如下:
在這 5 種模塊中,配置模塊和核心模塊是與 Nginx 框架密切相關的。而事件模塊則是 HTTP 模塊和 mail 模塊的基礎。HTTP 模塊和 mail 模塊的“地位”類似,它們都是更關注于應用層面。
事件驅動架構事件驅動架構,簡單的說就是由一些事件發生源來產生事件,由事件收集器來收集、分發事件,然后由事件處理器來處理這些事件(事件處理器需要先在事件收集器里注冊自己想處理的事件)。
對于 Nginx 服務器而言,一般由網卡、磁盤產生事件,Nginx 中的事件模塊將負責事件的收集、分發操作;而所有的模塊都可能是事件消費者,它們首先需要向事件模塊注冊感興趣的事件類型,這樣,在有事件產生時,事件模塊會把事件分發到相應的模塊中進行處理。
對于傳統 web 服務器(如 Apache)而言,采用的所謂事件驅動往往局限在 TCP 連接建立、關閉事件上,一個連接建立以后,在其關閉之前的所有操作都不再是事件驅動,這時會退化成按順序執行每個操作的批處理模式,這樣每個請求在連接建立后都將始終占用著系統資源,直到關閉才會釋放資源。這種請求占用著服務器資源等待處理的模式會造成服務器資源極大的浪費。如下圖所示,傳統 web 服務器往往把一個進程或線程作為時間消費者,當一個請求產生的事件被該進程處理時,直到這個請求處理結束時,進程資源都將被這一請求所占用。比較典型的例子如 Apache 同步阻塞的多進程模式就是這樣的。
傳統 web 服務器處理事件的簡單模型(矩形代表進程):
Nginx 采用事件驅動架構處理業務的方式與傳統的 web 服務器是不同的。它不使用進程或者線程來作為事件消費者,所謂的事件消費者只能是某個模塊。只有事件收集、分發器才有資格占用進程資源,它們會在分發某個事件時調用事件消費模塊使用當前占用的進程資源,如下圖所示,該圖中列出了 5 個不同的事件,在事件收集、分發者進程的一次處理過程中,這 5 個事件按照順序被收集后,將開始使用當前進程分發事件,從而調用相應的事件消費者來處理事件。當然,這種分發、調用也是有序的。
Nginx 處理事件的簡單模型:
由上圖可以看出,處理請求事件時,Nginx 的事件消費者只是被事件分發者進程短期調用而已,這種設計使得網絡性能、用戶感知的請求時延都得到了提升,每個用戶的請求所產生的事件會及時響應,整個服務器的網絡吞吐量都會由于事件的及時響應而增大。當然,這也帶來一定的要求,即每個事件消費者都不能有阻塞行為,否則將會由于長時間占用事件分發者進程而導致其他事件得不到及時響應,Nginx 的非阻塞特性就是由于它的模塊都是滿足這個要求的。
請求的多階段異步處理多階段異步處理請求與事件驅動架構是密切相關的,也就是說,請求的多階段異步處理只能基于事件驅動架構實現。多階段異步處理就是把一個請求的處理過程按照事件的觸發方式劃分為多個階段,每個階段都可以由事件收集、分發器來觸發。
處理獲取靜態文件的 HTTP 請求時切分的階段及各階段的觸發事件如下所示:
這個例子中,該請求大致分為 7 個階段,這些階段是可以重復發生的,因此,一個下載靜態資源請求可能會由于請求數據過大,網速不穩定等因素而被分解為成百上千個上圖所列出的階段。
異步處理和多階段是相輔相成的,只有把請求分為多個階段,才有所謂的異步處理。當一個時間被分發到事件消費者中進行處理時,事件消費者處理完這個事件只相當于處理完 1 個請求的階段。什么時候可以處理下一個階段呢?這只能等待內核的通知,即當下一次事件出現時,epoll 等事件分發器將會獲取到通知,然后去調用事件消費者進行處理。
管理進程、多工作進程設計Nginx 在啟動后,會有一個 master 進程和多個 worker 進程。master 進程主要用來管理worker 進程,包括接收來自外界的信號,向各 worker 進程發送信號,監控 worker 進程的運行狀態以及啟動 worker 進程。 worker 進程是用來處理來自客戶端的請求事件。多個 worker 進程之間是對等的,它們同等競爭來自客戶端的請求,各進程互相獨立,一個請求只能在一個 worker 進程中處理。worker 進程的個數是可以設置的,一般會設置與機器 CPU 核數一致,這里面的原因與事件處理模型有關。Nginx 的進程模型,可由下圖來表示:
在服務器上查看 Nginx 進程:
這種設計帶來以下優點:
1) 利用多核系統的并發處理能力
現代操作系統已經支持多核 CPU 架構,這使得多個進程可以分別占用不同的 CPU 核心來工作。Nginx 中所有的 worker 工作進程都是完全平等的。這提高了網絡性能、降低了請求的時延。
2) 負載均衡
多個 worker 工作進程通過進程間通信來實現負載均衡,即一個請求到來時更容易被分配到負載較輕的 worker 工作進程中處理。這也在一定程度上提高了網絡性能、降低了請求的時延。
3) 管理進程會負責監控工作進程的狀態,并負責管理其行為
管理進程不會占用多少系統資源,它只是用來啟動、停止、監控或使用其他行為來控制工作進程。首先,這提高了系統的可靠性,當 worker 進程出現問題時,管理進程可以啟動新的工作進程來避免系統性能的下降。其次,管理進程支持 Nginx 服務運行中的程序升級、配置項修改等操作,這種設計使得動態可擴展性、動態定制性較容易實現。
內存池的設計為了避免出現內存碎片,減少向操作系統申請內存的次數、降低各個模塊的開發復雜度,Nginx 設計了簡單的內存池,它的作用主要是把多次向系統申請內存的操作整合成一次,這大大減少了 CPU 資源的消耗,同時減少了內存碎片。
因此,通常每一個請求都有一個簡易的獨立內存池(如每個 TCP 連接都分配了一個內存池),而在請求結束時則會銷毀整個內存池,把曾經分配的內存一次性歸還給操作系統。這種設計大大提高了模塊開發的簡單些,因為在模塊申請內存后不用關心它的釋放問題;而且因為分配內存次數的減少使得請求執行的時延得到了降低。同時,通過減少內存碎片,提高了內存的有效利用率和系統可處理的并發連接數,從而增強了網絡性能。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/11970.html
摘要:請求的多階段異步處理多階段異步處理請求與事件驅動架構是密切相關的,也就是說,請求的多階段異步處理只能基于事件驅動架構實現。 前言 最近在讀 Nginx 相關的書籍,做一下讀書筆記。 Nginx 作為業界知名的高性能服務器,被廣泛的應用。它的高性能正是由于其優秀的架構設計,其架構主要包括這幾點:模塊化設計、事件驅動架構、請求的多階段異步處理、管理進程與多工作進程設計、內存池的設計,以下內...
摘要:常規的網絡應用設計都是為每個連接分配一個線程或進程。深入理解進程每個進程都是用配置進行初始化的,并且由主進程提供了一組監聽套接字。套接字上發生事件后,進程開始進行處理監聽套接字上的事件意味著有個客戶端發起了一盤新的象棋游戲。 NGINX在web性能上的表現尤為出眾,這完全得益于其設計方式,許多web和應用服務器都是基于線程或進程這種簡單的架構,NGINX用了一種精妙的事件驅動架構,在現...
摘要:阻塞,非阻塞首先,阻塞這個詞來自操作系統的線程進程的狀態模型網絡爬蟲基本原理一后端掘金網絡爬蟲是捜索引擎抓取系統的重要組成部分。每門主要編程語言現未來已到后端掘金使用和在相同環境各加載多張小圖片,性能相差一倍。 2016 年度小結(服務器端方向)| 掘金技術征文 - 后端 - 掘金今年年初我花了三個月的業余時間用 Laravel 開發了一個項目,在此之前,除了去年換工作準備面試時,我并...
摘要:阻塞,非阻塞首先,阻塞這個詞來自操作系統的線程進程的狀態模型網絡爬蟲基本原理一后端掘金網絡爬蟲是捜索引擎抓取系統的重要組成部分。每門主要編程語言現未來已到后端掘金使用和在相同環境各加載多張小圖片,性能相差一倍。 2016 年度小結(服務器端方向)| 掘金技術征文 - 后端 - 掘金今年年初我花了三個月的業余時間用 Laravel 開發了一個項目,在此之前,除了去年換工作準備面試時,我并...
摘要:作為面試官,我是如何甄別應聘者的包裝程度語言和等其他語言的對比分析和主從復制的原理詳解和持久化的原理是什么面試中經常被問到的持久化與恢復實現故障恢復自動化詳解哨兵技術查漏補缺最易錯過的技術要點大掃盲意外宕機不難解決,但你真的懂數據恢復嗎每秒 作為面試官,我是如何甄別應聘者的包裝程度Go語言和Java、python等其他語言的對比分析 Redis和MySQL Redis:主從復制的原理詳...
閱讀 2845·2021-10-21 09:38
閱讀 2751·2021-10-11 10:59
閱讀 3022·2021-09-27 13:36
閱讀 1649·2021-08-23 09:43
閱讀 790·2019-08-29 14:14
閱讀 3034·2019-08-29 12:13
閱讀 3203·2019-08-29 12:13
閱讀 310·2019-08-26 12:24