摘要:反向代理反向代理反向代理負(fù)載均衡鑒權(quán)限流等邏輯架構(gòu)在邏輯上分為入口層,模塊化的功能處理層,系統(tǒng)調(diào)用層。多個(gè)共同監(jiān)聽(tīng)事件并處理,反向代理會(huì)把請(qǐng)求轉(zhuǎn)發(fā)給后端服務(wù)。
一.概述
本文將深入剖析nginx的架構(gòu)。
第一部分介紹nginx現(xiàn)有框架,用典型的4+1視圖闡述,包括邏輯架構(gòu),開(kāi)發(fā)架構(gòu),運(yùn)行架構(gòu),物理架構(gòu),功能用例,nginx為單機(jī)服務(wù),不考慮物理架構(gòu)。其中功能用例概述nginx功能;邏輯架構(gòu)主要介紹nginx高度模塊化中各個(gè)模塊的分層和依賴(lài)關(guān)系;開(kāi)發(fā)架構(gòu)主要描述nginx的代碼結(jié)構(gòu)和代碼內(nèi)容簡(jiǎn)介;重點(diǎn)是運(yùn)行架構(gòu),nginx一主多從的進(jìn)程模型架構(gòu)和通信,高并發(fā)進(jìn)程和IO并發(fā)的選型等。
第二部分對(duì)比nginx運(yùn)行架構(gòu)和其他開(kāi)源運(yùn)行架構(gòu),總結(jié)nginx為何要這樣選型;介紹nginx邏輯架構(gòu)中的優(yōu)點(diǎn)。
本文適合閱讀對(duì)象:1)已經(jīng)看過(guò)nginx代碼,本文幫你高度抽象總結(jié)了nginx的架構(gòu)和與我自己設(shè)計(jì)相比較,nginx哪里設(shè)計(jì)的優(yōu)點(diǎn),試著從架構(gòu)層來(lái)重新看下代碼;2)研究各種系統(tǒng)架構(gòu)的人,本文從統(tǒng)一的架構(gòu)視圖介紹,無(wú)需知道nginx的代碼細(xì)節(jié),列出了與其他架構(gòu)比,nginx架構(gòu)的亮點(diǎn)。3)還未看過(guò)nginx的代碼,關(guān)注第二章,可以看四個(gè)視圖忽略對(duì)特性的分析和架構(gòu)的思考,幫助了解nginx有什么功能、如何組織代碼、如何運(yùn)行。
關(guān)鍵詞:Nginx架構(gòu),nginx功能,nginx邏輯架構(gòu),nginx代碼結(jié)構(gòu),nginx運(yùn)行架構(gòu),nginx高性能實(shí)現(xiàn) 二.nginx現(xiàn)有架構(gòu)實(shí)現(xiàn) 功能介紹nginx最核心的功能是web服務(wù)器和反向代理服務(wù)器,web服務(wù)器完成對(duì) http請(qǐng)求協(xié)議的解析 和 以http協(xié)議格式響應(yīng)請(qǐng)求、緩存、日志處理這些 基本web服務(wù)器 功能,反向代理服務(wù)器完成對(duì)請(qǐng)求的轉(zhuǎn)發(fā)、負(fù)載均衡、鑒權(quán)、限流、緩存、日志處理等代理常用功能。nginx在這方面提供了豐富的功能,包括對(duì)http2,ssl等等的支持。除了http外,nginx還支持mail服務(wù)和普通的tcp,udp協(xié)議的反向代理功能。一下列出了常用功能,詳細(xì)所有功能見(jiàn)參考1
### http服務(wù)器/反向代理服務(wù)器
靜態(tài)文件,fastcgi,uwsgi,scgi,memcached 服務(wù)
緩存
負(fù)載均衡
SSL/TLS
HTTP2
鑒權(quán)/限流
虛擬servers
功能用例舉例:web服務(wù)器和反向代理服務(wù)器的功能(第一個(gè)locatiion為服務(wù)器,后面是反向代理)。在nginx中配置如圖配置,啟動(dòng)nginx加載配置后,發(fā)起http請(qǐng)求,獲取服務(wù)器響應(yīng)。
server{ listen 8091; root /home/xiaoju/yyl/; index index.php; location / { root html; index index.html index.htm; } location ~ .php$ { rewrite /(.*)$ /index.php/$1 break; fastcgi_index index.php; fastcgi_pass 127.0.0.1:9000; include fastcgi.conf; } }
curl localhost:8091 -v * About to connect() to localhost port 8091 (#0) * Trying 127.0.0.1... connected * Connected to localhost (127.0.0.1) port 8091 (#0) > GET / HTTP/1.1 > User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.27.1 zlib/1.2.3 libidn/1.18 libssh2/1.4.2 > Host: localhost:8091 > Accept: */* > < HTTP/1.1 200 OK < Server: nginx/1.13.11 < Date: Sun, 02 Dec 2018 06:29:01 GMT < Content-Type: text/html; charset=utf-8 < Content-Length: 612 < Last-Modified: Tue, 10 Apr 2018 15:32:02 GMT < Connection: keep-alive < ETag: "5accd8f2-264" < Accept-Ranges: bytes <mail反向代理Welcome to nginx! ... * Connection #0 to host localhost left intact * Closing connection #0
mail反向代理
SSL; STARTTLS/STLS
TCP/UDP反向代理 socket,websocketSSL/TLS, 負(fù)載均衡, 鑒權(quán)/限流等
2.邏輯架構(gòu)nginx在邏輯上分為入口層,模塊化的功能處理層,系統(tǒng)調(diào)用層。入口調(diào)用配置模塊和核心模塊,各核心模塊分別調(diào)用各自功能模塊,系統(tǒng)調(diào)用層封裝了各個(gè)操作系統(tǒng)的功能被功能處理層使用。邏輯架構(gòu)最明顯主要的特征就是高度模塊化,所有功能都是模塊,每個(gè)模塊都統(tǒng)一結(jié)構(gòu),下面先看下這個(gè)統(tǒng)一結(jié)構(gòu),然后分別介紹各個(gè)模塊。
nginx除了main等少量代碼,其他全都是模塊,所有模塊都是Ngx_module_t的抽象,只有初始化,退出,對(duì)配置項(xiàng)的處理;每個(gè)模塊內(nèi)部也都有自己模塊ngx_xx_module_t的抽象;配置也高度抽象統(tǒng)一的結(jié)構(gòu)ngx_command_t。如圖:
核心模塊/配置模塊核心流程會(huì)只會(huì)調(diào)用核心模塊和配置模塊。
核心模塊調(diào)用各個(gè)其他模塊的core_module完成各自模塊的加載工作。配置模塊為其他模塊的基礎(chǔ),負(fù)責(zé)解析配置文件。
負(fù)責(zé)請(qǐng)求連接的建立,分發(fā)等網(wǎng)絡(luò)事件及定時(shí)器事件,其中所有模塊封裝到ngx_events_module_t接口中供其他模塊直接調(diào)用。
http/stream/mail模塊對(duì)應(yīng)nginx用戶(hù)功能的三個(gè)主體。以Http模塊為例,初始化,退出,對(duì)配置項(xiàng)的處理等工作也統(tǒng)一封裝在ngx_http_module_t中。http請(qǐng)求的處理過(guò)程各模塊可插拔,為固定的11個(gè)階段,模塊想介入,只需在ngx_http_module_t中定義回調(diào)函數(shù),http協(xié)議內(nèi)容多,對(duì)結(jié)果的處理也高度模塊化,根據(jù)配置項(xiàng)將模塊選擇性插入到輸出過(guò)濾鏈中。
系統(tǒng)調(diào)用nginx對(duì)各種操作系統(tǒng)的調(diào)用做了一層封裝,使模塊代碼無(wú)需區(qū)分。
依賴(lài)關(guān)系http,stream,mail依賴(lài)事件模塊,事件模塊依賴(lài)核心模塊和配置模塊,上層模塊依賴(lài)底層的系統(tǒng)調(diào)用。
3. 開(kāi)發(fā)架構(gòu)開(kāi)發(fā)架構(gòu)主要關(guān)注現(xiàn)有的代碼結(jié)構(gòu)和開(kāi)發(fā)代碼時(shí)如何擴(kuò)展。先介紹代碼結(jié)構(gòu)然后列舉一下如何新增模塊
代碼結(jié)構(gòu)包含core,event,http,mail,misc,os,stream這幾個(gè)文件夾
core
為nginx的核心源代碼,包括main函數(shù)/整體控制,基本數(shù)據(jù)結(jié)構(gòu)封裝,配置管理,內(nèi)存管理,日志管理,文件讀寫(xiě)網(wǎng)絡(luò)套接字功能,系統(tǒng)參數(shù)資源通用管理等
event
module子目錄實(shí)現(xiàn)了Nginx支持的事件驅(qū)動(dòng)模型:AIOepollkqueueselectpoll等,其他提供了事件驅(qū)動(dòng)模型相關(guān)數(shù)據(jù)結(jié)構(gòu)的定義、初始化、事件接收傳遞管理功能以及時(shí)間驅(qū)動(dòng)模型調(diào)用功能
http
module文件實(shí)現(xiàn)了http模塊的功能,perl為對(duì)perl的支持,v2為對(duì)http2.0的支持,其他提供結(jié)構(gòu)定義、初始化、網(wǎng)絡(luò)連接建立、管理、關(guān)閉、數(shù)據(jù)報(bào)解析、upstream等通用功能
mail 郵件功能的實(shí)現(xiàn)
misc
os 根據(jù)操作系統(tǒng)對(duì)系統(tǒng)調(diào)用的封裝
stream 為對(duì)TCP/UDP反向代理的支持
開(kāi)發(fā)擴(kuò)展模塊編輯新的模塊步驟:
在自定義文件夾下,創(chuàng)建conf文件,說(shuō)明名字和目錄。
編寫(xiě)代碼。
編譯入nginx:
在configure腳本執(zhí)行時(shí)加入?yún)?shù)--add-module=PATH,執(zhí)行后會(huì)生成objs/Makefile,objs/ngx_modules.c(也可以直接修改)。會(huì)執(zhí)行conf文件,生成的ngx_modules.c包含nginx啟動(dòng)時(shí)加載的所有模塊,nginx核心代碼中全局modules從這里獲取。這個(gè)模塊就被編譯到nginx程序中了。
首先給出nginx的整體架構(gòu)圖,然后介紹運(yùn)行架構(gòu)中關(guān)注的運(yùn)行模式,通信方式,IO處理選型。再總結(jié)下nginx運(yùn)行架構(gòu)的特性:事件驅(qū)動(dòng)+碎片化+異步處理
架構(gòu)圖
說(shuō)明:因?yàn)榫τ邢?,只看了epoll的運(yùn)行時(shí)架構(gòu),以下所有分析均只考慮linux并使用epoll的情況。
啟動(dòng)后,有一個(gè)主進(jìn)程,多個(gè)worker進(jìn)行,兩個(gè)cache相關(guān)進(jìn)程。多個(gè)worker共同監(jiān)聽(tīng)事件并處理,反向代理會(huì)把請(qǐng)求轉(zhuǎn)發(fā)給后端服務(wù)。
master: 管理worker等子進(jìn)程實(shí)現(xiàn)重啟服務(wù),平滑升級(jí),更換日志文件,配置文件實(shí)時(shí)生效等
worker: 簡(jiǎn)單的負(fù)載均衡(高負(fù)載等待),搶鎖,監(jiān)聽(tīng)處理事件,接收master命令
cache: nginx開(kāi)啟緩存功能,會(huì)創(chuàng)建cache的兩個(gè)進(jìn)程,cache loader在nginx啟動(dòng)后將磁盤(pán)上次緩存的對(duì)象加載到內(nèi)存后自動(dòng)退出,cache管理進(jìn)程清理超時(shí)緩存文件,限制緩存文件總大小,這個(gè)過(guò)程反反復(fù)復(fù),直到Nginx整個(gè)進(jìn)程退出。
進(jìn)程間通信nginx的進(jìn)程間通信,在不同應(yīng)用場(chǎng)景下采取不同的形式:
linux與master/worker/cache進(jìn)程通信:信號(hào)
master啟動(dòng)時(shí)先把感興趣的信號(hào)注冊(cè);
在主進(jìn)程fork子進(jìn)程之前要把所有信號(hào)調(diào)用sigprocmask阻塞住,等待fork成功后再將阻塞信號(hào)清除;
主進(jìn)程之后就掛起在sigsuspend中,等待信號(hào);
主進(jìn)程與子進(jìn)程通信:socketpair
這里每個(gè)子進(jìn)程和父進(jìn)程之間使用的是socketpair系統(tǒng)調(diào)用建立起來(lái)的全雙工的socket channel[]在父子進(jìn)程中各有一套,channel[0]為寫(xiě)端,channel[1]為讀端
父進(jìn)程關(guān)閉socket[0], 子進(jìn)程關(guān)閉socket[1],父進(jìn)程從sockets[1]中讀寫(xiě),子進(jìn)程從sockets[0]中讀寫(xiě),還是全雙工形態(tài)
子進(jìn)程也會(huì)監(jiān)督部分信號(hào),是master通過(guò)socketpair發(fā)送過(guò)去的。linux關(guān)閉worker后,worker也會(huì)通過(guò)socketpair把信號(hào)發(fā)送給主進(jìn)程
其他進(jìn)程間共享數(shù)據(jù):共享內(nèi)存
nginx中所有共享內(nèi)存都是以list鏈表的形式組織在全局變量cf->cycle->shared_memory下,在創(chuàng)建新的共享內(nèi)存之前會(huì)先對(duì)該鏈表進(jìn)行遍歷查找以及沖突檢測(cè),對(duì)于已經(jīng)存在且不存在沖突的共享內(nèi)存可直接返回引用。
函數(shù)ngx_shm_alloc()時(shí)共享內(nèi)存的實(shí)際分配,針對(duì)當(dāng)前系統(tǒng)可提供的接口,可以是mmap,shmget等
應(yīng)用于進(jìn)程(如子進(jìn)程之間,在進(jìn)程重啟時(shí)新舊主進(jìn)程需要搶鎖等)間需要共享的數(shù)據(jù),比如連接數(shù)/互斥鎖等,另外提下鎖有多重互斥方式,在操作系統(tǒng)支持的情況下用優(yōu)先用原子操作。
這部分為了并發(fā)需要考慮多進(jìn)程,多線(xiàn)程,IO阻塞,IO非阻塞,每個(gè)進(jìn)程處理一個(gè)還是多個(gè)事件 等典型的IO網(wǎng)絡(luò)選型中的這幾個(gè)問(wèn)題。
nginx在操作系統(tǒng)支持的情況下(不支持根據(jù)不同操作系統(tǒng)和配置,事件模型中選擇不同IO處理方式)采取多進(jìn)程,每個(gè)進(jìn)程可以同時(shí)接收多個(gè)請(qǐng)求,IO多路復(fù)用非阻塞的方式。詳細(xì)的運(yùn)行架構(gòu)如圖。簡(jiǎn)單抽象過(guò)程:主進(jìn)程創(chuàng)建監(jiān)聽(tīng)socket后所有worker子進(jìn)程繼承共同監(jiān)聽(tīng),通過(guò)搶鎖的方式?jīng)Q定同一時(shí)刻哪個(gè)worker是請(qǐng)求的acceptor方,accept請(qǐng)求后在本子進(jìn)程中處理。
多進(jìn)程
為了并發(fā)和利用多核處理,首先啟用多進(jìn)程的模式,在主進(jìn)程創(chuàng)建所有監(jiān)聽(tīng)的socket,為了所有worker都可以繼承并監(jiān)聽(tīng)該socket的fd。
多acceptor,多handler 采取多acceptor,多handler的模式,每個(gè)進(jìn)程在自己內(nèi)部acceptor后分配給自己內(nèi)部的handler處理。為了防止多acceptor同時(shí)accept的驚群現(xiàn)象,只有搶到鎖的才把事件加入到監(jiān)聽(tīng),喚醒只會(huì)喚醒當(dāng)前進(jìn)程accept事件(新版的nginx采取reuseport可以一個(gè)端口被多個(gè)進(jìn)程監(jiān)聽(tīng),支持的4.3的accept相關(guān)特征也不需要搶鎖)
進(jìn)程accept多個(gè) 每個(gè)進(jìn)程可以accept多個(gè)連接的模式,每次只處理accept,為三次握手完成的請(qǐng)求建立連接后就將其他事件放入延遲隊(duì)列,釋放鎖后才處理這部分隊(duì)列,以便其他進(jìn)程可以繼續(xù)搶鎖
worker監(jiān)聽(tīng)處理的過(guò)程如圖所示,在master啟動(dòng)的時(shí)候,為每個(gè)端口創(chuàng)建監(jiān)聽(tīng)套接字listen socked(以下簡(jiǎn)稱(chēng)lss),然后fork出worker進(jìn)程,所有worker進(jìn)程繼承同一份lss,為每個(gè)ls創(chuàng)建連接和事件結(jié)構(gòu),每個(gè)空閑worker搶鎖獲取這些lss的處理權(quán)。持有鎖就將ls的讀事件加入到epoll中等待,把接收事件分為兩類(lèi):優(yōu)先處理accept,延時(shí)處理非建立連接事件。accept后就釋放鎖。
worker會(huì)有三種情況,一種是空閑但沒(méi)有搶到鎖,就等待事件后繼續(xù)搶鎖。另一種是在處理隊(duì)列中請(qǐng)求,空閑后去搶鎖。第三種是空閑并且搶到鎖,則持有鎖并監(jiān)聽(tīng)和分配給hander后釋放鎖,處理隊(duì)列請(qǐng)求
事件驅(qū)動(dòng)+碎片化+異步處理
nginx所有需要等待的全都盡可能的碎片化,并加入到事件中,當(dāng)事件ready后根據(jù)回調(diào)調(diào)用消費(fèi)者處理,在Nginx里,Listen后是不需要循環(huán)等待accept,把他加入到epoll中,統(tǒng)一在epoll_wait中處理,當(dāng)有返回直接調(diào)用accept。包括后續(xù)與客戶(hù)端建立的主動(dòng)連接(非Listen的)的所有事件也都統(tǒng)一在epoll_wait中等待,有事件直接調(diào)用事件的消費(fèi)回調(diào)函數(shù)。在調(diào)用epoll_wait時(shí)也是一直循環(huán)等待事件沒(méi)有退出,所以就要把事件拆分成特別細(xì)小的單元,這些單元都是可以異步執(zhí)行的,有了epoll這個(gè)模型可以把任何涉及到磁盤(pán)讀寫(xiě)的小粒度事件加入到監(jiān)控中,比如讀過(guò)了頭第一行就去處理headline把其他的再加入到epoll中。
考慮如果沒(méi)有nginx,自己實(shí)現(xiàn),是如何實(shí)現(xiàn)。
先聊運(yùn)行架構(gòu)
要實(shí)現(xiàn)的簡(jiǎn)化功能概述:服務(wù)器要持續(xù)啟動(dòng),監(jiān)聽(tīng)8000端口,收到請(qǐng)求后解析http協(xié)議,若是靜態(tài)請(qǐng)求,獲取文件內(nèi)容,封裝為Http的響應(yīng)協(xié)議格式,發(fā)送;若為動(dòng)態(tài)請(qǐng)求,轉(zhuǎn)化為fastcgi協(xié)議,轉(zhuǎn)發(fā)給fastcgi程序,發(fā)送到響應(yīng)的端口,獲取數(shù)據(jù)后再轉(zhuǎn)化為Http響應(yīng)協(xié)議格式發(fā)送。
為了實(shí)現(xiàn)高并發(fā),當(dāng)然要開(kāi)啟多個(gè)處理進(jìn)程,因?yàn)橐O(jiān)聽(tīng)同一個(gè)端口,需要一個(gè)監(jiān)聽(tīng)進(jìn)程負(fù)責(zé)監(jiān)聽(tīng)端口(在不考慮新的技術(shù)支持多個(gè)進(jìn)程同時(shí)監(jiān)聽(tīng)一個(gè)端口的情況),accept后分配給處理進(jìn)程。對(duì)于單個(gè)監(jiān)聽(tīng)端口最好設(shè)計(jì)是單acceptor多進(jìn)程的形式,然而,這基本上是不可能實(shí)現(xiàn)的,因?yàn)槎鄠€(gè)進(jìn)程處理完的數(shù)據(jù)如何返回給監(jiān)聽(tīng)進(jìn)程,大量的數(shù)據(jù)再進(jìn)程間通信是不現(xiàn)實(shí)的。因此對(duì)于單個(gè)監(jiān)聽(tīng)端口只能是單進(jìn)程。或者改用線(xiàn)程,然而多線(xiàn)程不穩(wěn)定。
我可以對(duì)多個(gè)監(jiān)聽(tīng)端口開(kāi)啟多個(gè)進(jìn)程,每個(gè)監(jiān)聽(tīng)不同的端口,但端口間流量分配不均勻時(shí),進(jìn)程負(fù)載不均衡。
=》從監(jiān)聽(tīng)處理進(jìn)程個(gè)數(shù)上,nginx比我自己設(shè)計(jì)聰明的地方體現(xiàn)出來(lái)了,特殊的多reactor多進(jìn)程結(jié)構(gòu)。
再說(shuō)說(shuō)每個(gè)進(jìn)程里的高并發(fā),網(wǎng)絡(luò)連接肯定會(huì)有IO等待,此時(shí)若可以繼續(xù)做其他的,會(huì)更快。每次接收一個(gè)請(qǐng)求的情況下,可以讀完請(qǐng)求后,一邊請(qǐng)求異步磁盤(pán)一邊寫(xiě)返回頭等;在有子請(qǐng)求和接受多個(gè)請(qǐng)求的情況下,可以一邊為其他請(qǐng)求建立連接,一邊處理本請(qǐng)求的事件,多個(gè)請(qǐng)求同時(shí)處理。因此設(shè)計(jì)為單進(jìn)程可以同時(shí)accept多個(gè),每個(gè)可以并行的操作都拆為多帶帶事件異步處理。思想和nginx一樣。
再聊聊開(kāi)發(fā)架構(gòu),代碼架構(gòu)可以依照開(kāi)發(fā)架構(gòu)
nginx因?yàn)橹С址聪虼恚С侄嗥脚_(tái),支持自定義配置,所以有配置模塊,統(tǒng)一的事件模塊,有抽象的配置結(jié)構(gòu)。自己開(kāi)發(fā)web服務(wù)器,可能不會(huì)考慮這么多,主要考慮http的處理過(guò)程,http固定的讀取頭,解析頭,真實(shí)ip,權(quán)限,處理,輸出協(xié)議的轉(zhuǎn)換,寫(xiě)日志做成固定的順序,直接調(diào)用固定函數(shù)。nginx再此之上,每個(gè)過(guò)程有自己的回調(diào),整體階段清晰,每個(gè)模塊可以在把回調(diào)加入到各個(gè)子階段,更靈活。協(xié)議按順序也先固定輸出鏈,若沒(méi)有該協(xié)議直接跳過(guò),對(duì)于這種運(yùn)行前不知道會(huì)有哪些輸出過(guò)濾的情況,自己寫(xiě)可能就在運(yùn)行中判斷有就調(diào)用了,nginx是固定走,沒(méi)有直接跳過(guò),這兩種根據(jù)不同應(yīng)用各有應(yīng)用吧。
高可擴(kuò)展性模塊化
無(wú)論配置,初始化,代碼結(jié)構(gòu)都是模塊化的,各個(gè)模塊要介入到主流程,根本不需要修改主流程代碼,通過(guò)在hook位置增加回調(diào)。
高度抽象
正常很難想到所有的模塊和配置全部都一個(gè)抽象結(jié)構(gòu),各個(gè)子模塊也都統(tǒng)一抽象結(jié)構(gòu),新增加功能簡(jiǎn)單,可讀性高
輸出統(tǒng)一過(guò)濾鏈,功能可插拔
擴(kuò)展容易,代碼簡(jiǎn)潔,可讀性高
高性能多reactor多進(jìn)程結(jié)構(gòu)
經(jīng)過(guò)上述分析,Nginx在并發(fā)選型上要么是單reactor單進(jìn)程結(jié)構(gòu),要么是單reactor多線(xiàn)程結(jié)構(gòu),但多線(xiàn)程只要一個(gè)操作共享區(qū)域,會(huì)影響其他線(xiàn)程,所以在不需要共享數(shù)據(jù)的情況下,最好用多進(jìn)程。nginx巧妙的雖然同一時(shí)刻只能單reactor,但在accept后立刻釋放鎖,也達(dá)到多reactor的性能,此架構(gòu)不常見(jiàn),可以參考。memcache,mysql等因?yàn)橐蚕頂?shù)據(jù)都是多reactor多線(xiàn)程;apache舊版是一個(gè)進(jìn)程處理一個(gè)請(qǐng)求,類(lèi)似phpfpm,本質(zhì)上是單reactor單進(jìn)程,后來(lái)一個(gè)進(jìn)程中有多個(gè)線(xiàn)程,單reactor多線(xiàn)程,但每個(gè)線(xiàn)程處理一個(gè)請(qǐng)求;后面也加入了IO多路復(fù)用,每個(gè)線(xiàn)程中處理多個(gè)請(qǐng)求。
后續(xù)preactor+線(xiàn)程
本質(zhì)上epoll還是等待的,還是需要進(jìn)程去詢(xún)問(wèn),利用內(nèi)核異步IO,可以做到事件自動(dòng)處理,處理后通知,不需要詢(xún)問(wèn),其架構(gòu)如下:
單linux的AIO還不完善,到目前為止,nginx實(shí)現(xiàn)了AIO+線(xiàn)程的模型,但還未應(yīng)用。
內(nèi)存池,連接池
為了省去每次申請(qǐng),減少內(nèi)存碎片,統(tǒng)一釋放等,提前準(zhǔn)備好內(nèi)存池和連接池 。
四.總結(jié)nginx作為一個(gè)高性能高可用高可擴(kuò)展的 http服務(wù)器和多協(xié)議反向代理服務(wù)器,其運(yùn)行架構(gòu)采用特殊的監(jiān)聽(tīng)同一端口卻多reactor多進(jìn)程的模型,值得借鑒;高度抽象和模塊化的邏輯架構(gòu)使得功能龐大代碼卻清晰易懂,開(kāi)發(fā)和擴(kuò)展代價(jià)低。
參考
nginx功能 http://nginx.org/en/
nginx代碼結(jié)構(gòu) https://www.kancloud.cn/diges...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/40247.html
摘要:反向代理反向代理反向代理負(fù)載均衡鑒權(quán)限流等邏輯架構(gòu)在邏輯上分為入口層,模塊化的功能處理層,系統(tǒng)調(diào)用層。多個(gè)共同監(jiān)聽(tīng)事件并處理,反向代理會(huì)把請(qǐng)求轉(zhuǎn)發(fā)給后端服務(wù)。 一.概述 本文將深入剖析nginx的架構(gòu)。 第一部分介紹nginx現(xiàn)有框架,用典型的4+1視圖闡述,包括邏輯架構(gòu),開(kāi)發(fā)架構(gòu),運(yùn)行架構(gòu),物理架構(gòu),功能用例,nginx為單機(jī)服務(wù),不考慮物理架構(gòu)。其中功能用例概述nginx功能;邏輯...
摘要:而且在負(fù)載上面遠(yuǎn)超,為什么目前大多數(shù)的互聯(lián)網(wǎng)公司都是使用這種架構(gòu)模式,而不是直接,這樣不是架構(gòu)更加方便,而且性能更佳優(yōu)異嘛。其特點(diǎn)是占有內(nèi)存少,并發(fā)能力強(qiáng)。 最近有人問(wèn)我,Nginx有動(dòng)態(tài)分離機(jī)制,靜態(tài)請(qǐng)求直接就可以通過(guò)Nginx處理,動(dòng)態(tài)請(qǐng)求才轉(zhuǎn)發(fā)請(qǐng)求到后臺(tái)交由Tomcat進(jìn)行處理。而且Nginx在負(fù)載上面遠(yuǎn)超Apache,為什么目前大多數(shù)的互聯(lián)網(wǎng)公司都是使用Nginx+Apache...
摘要:而且在負(fù)載上面遠(yuǎn)超,為什么目前大多數(shù)的互聯(lián)網(wǎng)公司都是使用這種架構(gòu)模式,而不是直接,這樣不是架構(gòu)更加方便,而且性能更佳優(yōu)異嘛。其特點(diǎn)是占有內(nèi)存少,并發(fā)能力強(qiáng)。 最近有人問(wèn)我,Nginx有動(dòng)態(tài)分離機(jī)制,靜態(tài)請(qǐng)求直接就可以通過(guò)Nginx處理,動(dòng)態(tài)請(qǐng)求才轉(zhuǎn)發(fā)請(qǐng)求到后臺(tái)交由Tomcat進(jìn)行處理。而且Nginx在負(fù)載上面遠(yuǎn)超Apache,為什么目前大多數(shù)的互聯(lián)網(wǎng)公司都是使用Nginx+Apache...
摘要:請(qǐng)求的多階段異步處理多階段異步處理請(qǐng)求與事件驅(qū)動(dòng)架構(gòu)是密切相關(guān)的,也就是說(shuō),請(qǐng)求的多階段異步處理只能基于事件驅(qū)動(dòng)架構(gòu)實(shí)現(xiàn)。 前言 最近在讀 Nginx 相關(guān)的書(shū)籍,做一下讀書(shū)筆記。 Nginx 作為業(yè)界知名的高性能服務(wù)器,被廣泛的應(yīng)用。它的高性能正是由于其優(yōu)秀的架構(gòu)設(shè)計(jì),其架構(gòu)主要包括這幾點(diǎn):模塊化設(shè)計(jì)、事件驅(qū)動(dòng)架構(gòu)、請(qǐng)求的多階段異步處理、管理進(jìn)程與多工作進(jìn)程設(shè)計(jì)、內(nèi)存池的設(shè)計(jì),以下內(nèi)...
閱讀 2416·2021-11-11 16:54
閱讀 1219·2021-09-22 15:23
閱讀 3660·2021-09-07 09:59
閱讀 2009·2021-09-02 15:41
閱讀 3294·2021-08-17 10:13
閱讀 3061·2019-08-30 15:53
閱讀 1244·2019-08-30 13:57
閱讀 1216·2019-08-29 15:16