一、請(qǐng)求nginx默認(rèn)頁(yè)面
1整吆、流程
二拱撵、nginx.conf配置
listen 監(jiān)聽(tīng)端口。server_name 代表ip地址表蝙。location 映射地址
二拴测、nginx的進(jìn)程模型
Nginx的初始化過(guò)程:
解析配置文件,這是Nginx初始化最重要的一個(gè)環(huán)節(jié)
調(diào)用各個(gè)配置指令回調(diào)函數(shù)府蛇,完成各個(gè)模塊的配置集索、相互關(guān)聯(lián)等
建立listen 的 socket(listenfd)
準(zhǔn)備工作都完成后,fork worker子進(jìn)程和cache子進(jìn)程
nginx默認(rèn)有兩個(gè)工作模型,父進(jìn)程和子進(jìn)程抄谐。
master進(jìn)程:也是父進(jìn)程,負(fù)責(zé)worker進(jìn)程的管理和發(fā)送信號(hào)扰法。
信號(hào)分類
TERM/INT蛹含,立刻停止進(jìn)程;
QUIT塞颁,優(yōu)雅的退出浦箱,等請(qǐng)求處理完才退出;
HUP祠锣,重載配置文件酷窥;
USR1,重新打開(kāi)日志文件伴网,做日志文件的切割蓬推;
USR2,熱升級(jí)第一階段澡腾,啟動(dòng)新進(jìn)程沸伏。舊的 Nginx 主進(jìn)程 Master 將會(huì)把自己的進(jìn)程文件改名為 .oldbin,然后執(zhí)行新版 Nginx动分。此時(shí)新舊 Nginx 進(jìn)程會(huì)同時(shí)運(yùn)行毅糟,共同處理請(qǐng)求姆另;
WINCH,熱升級(jí)第二階段,停止老進(jìn)程殷绍。逐步停止舊版 Nginx 的 Worker 進(jìn)程就都會(huì)隨著任務(wù)執(zhí)行完畢而退出,新版的 Nginx 的 Worker 進(jìn)程會(huì)逐漸取代舊版 Worker 進(jìn)程。
子進(jìn)程分兩類:一種是 Worker 進(jìn)程伯铣,另一種是 Cache 相關(guān)的進(jìn)程恃泪。
worker進(jìn)程:也是子進(jìn)程览效,worker進(jìn)程一般配置成與服務(wù)器的CPU核數(shù)相同,worker進(jìn)程用來(lái)處理具體的請(qǐng)求的倘是。和接收信號(hào):TERM/INT升敲、QUIT锦茁、USR1笨篷、WINCH燕锥。
cache進(jìn)程:也是子進(jìn)程厚棵,包括cache manager(緩存管理)和cache loader(緩存加載),主要是反向代理時(shí)做緩存使用蔼紧。
nginx命令對(duì)應(yīng)信號(hào):
reload: HUP窟感;
reopen: USR1;
stop: TERM歉井;
quit: QUIT柿祈。
worker進(jìn)程數(shù)量修改
/sbin/nginx -t 可以查看參看配置有沒(méi)有問(wèn)題
進(jìn)程之間相互不影響,不公用內(nèi)存,受到攻擊容易處理
worker搶占機(jī)制
驚群現(xiàn)象
主進(jìn)程(master 進(jìn)程)首先通過(guò) socket() 來(lái)創(chuàng)建一個(gè) sock 文件描述符用來(lái)監(jiān)聽(tīng)躏嚎,然后fork生成子進(jìn)程(workers 進(jìn)程)蜜自,子進(jìn)程將繼承父進(jìn)程的 sockfd(socket 文件描述符),之后子進(jìn)程 accept() 后將創(chuàng)建已連接描述符(connected descriptor))卢佣,然后通過(guò)已連接描述符來(lái)與客戶端通信重荠。
由于所有子進(jìn)程都繼承了父進(jìn)程的 sockfd,那么當(dāng)連接進(jìn)來(lái)時(shí)虚茶,所有子進(jìn)程都將收到通知并“爭(zhēng)著”與它建立連接戈鲁,這就叫“驚群現(xiàn)象”。大量的進(jìn)程被激活又掛起嘹叫,只有一個(gè)進(jìn)程可以accept() 到這個(gè)連接婆殿,這當(dāng)然會(huì)消耗系統(tǒng)資源。
Nginx 提供了一個(gè) accept_mutex 這個(gè)東西罩扇,這是一個(gè)加在accept上的一把共享鎖婆芦。即每個(gè) worker 進(jìn)程在執(zhí)行 accept 之前都需要先獲取鎖,獲取不到就放棄執(zhí)行 accept()喂饥。有了這把鎖之后消约,同一時(shí)刻,就只會(huì)有一個(gè)進(jìn)程去 accpet()员帮,這樣就不會(huì)有驚群?jiǎn)栴}了或粮。accept_mutex 是一個(gè)可控選項(xiàng),我們可以顯示地關(guān)掉捞高,默認(rèn)是打開(kāi)的氯材。
nginx事件處理機(jī)制
傳統(tǒng)服務(wù)器事件處理
傳統(tǒng)服務(wù)器事件處理采用同步阻塞AIO機(jī)制(例如Apache),當(dāng)客戶端請(qǐng)求進(jìn)來(lái)后棠枉,worker1處理請(qǐng)求浓体,此時(shí)worker1會(huì)阻塞,無(wú)法處理其他請(qǐng)求辈讶。針對(duì)于高并發(fā)的場(chǎng)景命浴,則需要生產(chǎn)大量的worker。
Nginx事件處理機(jī)制
Nginx采用了Linux的epoll模型贱除,異步非阻塞生闲。單個(gè)worker可以同時(shí)處理幾萬(wàn)個(gè)請(qǐng)求的,具體取決于CPU和內(nèi)存月幌。當(dāng)多個(gè)client請(qǐng)求worker1碍讯,假設(shè)client1的請(qǐng)求阻塞,由于異步非阻塞機(jī)制扯躺,worker1仍可以去處理其他客戶端請(qǐng)求捉兴。epoll 工作模型 1個(gè)worker可以處理6-8萬(wàn)個(gè)請(qǐng)求
nginx.conf文件結(jié)構(gòu)
'##代碼塊中的events蝎困、http、server倍啥、location禾乘、upstream等都是塊配置項(xiàng)##
##塊配置項(xiàng)可以嵌套。內(nèi)層塊直接繼承外層快虽缕,例如:server塊里的任意配置都是基于http塊里的已有配置的##
##Nginx worker進(jìn)程運(yùn)行的用戶及用戶組
#語(yǔ)法:user username[groupname] 默認(rèn):user nobody
#user用于設(shè)置master進(jìn)程啟動(dòng)后始藕,fork出的worker進(jìn)程運(yùn)行在那個(gè)用戶和用戶組下。當(dāng)按照"user username;"設(shè)置時(shí)氮趋,用戶組名與用戶名相同伍派。
#若用戶在configure命令執(zhí)行時(shí),使用了參數(shù)--user=usergroup 和 --group=groupname,此時(shí)nginx.conf將使用參數(shù)中指定的用戶和用戶組剩胁。
#user nobody;
user root;
##Nginx worker進(jìn)程個(gè)數(shù):其數(shù)量直接影響性能诉植。
#每個(gè)worker進(jìn)程都是單線程的進(jìn)程,他們會(huì)調(diào)用各個(gè)模塊以實(shí)現(xiàn)多種多樣的功能摧冀。如果這些模塊不會(huì)出現(xiàn)阻塞式的調(diào)用倍踪,那么索昂,有多少CPU內(nèi)核就應(yīng)該配置多少個(gè)進(jìn)程,反之扩借,有可能出現(xiàn)阻塞式調(diào)用,那么,需要配置稍多一些的worker進(jìn)程何恶。
worker_processes 1;
##ssl硬件加速孽锥。
#用戶可以用OpneSSL提供的命令來(lái)查看是否有ssl硬件加速設(shè)備:openssl engine -t
#ssl_engine device;
##守護(hù)進(jìn)程(daemon)。是脫離終端在后臺(tái)允許的進(jìn)程细层。它脫離終端是為了避免進(jìn)程執(zhí)行過(guò)程中的信息在任何終端上顯示惜辑。這樣一來(lái),進(jìn)程也不會(huì)被任何終端所產(chǎn)生的信息所打斷疫赎。##
##關(guān)閉守護(hù)進(jìn)程的模式盛撑,之所以提供這種模式,是為了放便跟蹤調(diào)試nginx捧搞,畢竟用gdb調(diào)試進(jìn)程時(shí)最繁瑣的就是如何繼續(xù)跟進(jìn)fork出的子進(jìn)程了抵卫。##
##如果用off關(guān)閉了master_proccess方式狮荔,就不會(huì)fork出worker子進(jìn)程來(lái)處理請(qǐng)求,而是用master進(jìn)程自身來(lái)處理請(qǐng)求
#daemon off; #查看是否以守護(hù)進(jìn)程的方式運(yùn)行Nginx 默認(rèn)是on
#master_process off; #是否以master/worker方式工作 默認(rèn)是on
##error日志的設(shè)置#
#語(yǔ)法: error_log /path/file level;
#默認(rèn): error_log / log/error.log error;
#當(dāng)path/file 的值為 /dev/null時(shí)介粘,這樣就不會(huì)輸出任何日志了轴合,這也是關(guān)閉error日志的唯一手段;
#leve的取值范圍是debug碗短、info受葛、notice、warn偎谁、error总滩、crit、alert巡雨、emerg從左至右級(jí)別依次增大闰渔。
#當(dāng)level的級(jí)別為error時(shí),error铐望、crit冈涧、alert、emerg級(jí)別的日志就都會(huì)輸出正蛙。大于等于該級(jí)別會(huì)輸出督弓,小于該級(jí)別的不會(huì)輸出。
#如果設(shè)定的日志級(jí)別是debug乒验,則會(huì)輸出所有的日志愚隧,這一數(shù)據(jù)量會(huì)很大,需要預(yù)先確保/path/file所在的磁盤有足夠的磁盤空間锻全。級(jí)別設(shè)定到debug狂塘,必須在configure時(shí)加入 --with-debug配置項(xiàng)。
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
##pid文件(master進(jìn)程ID的pid文件存放路徑)的路徑
#pid logs/nginx.pid;
events {
#僅對(duì)指定的客戶端輸出debug級(jí)別的日志: 語(yǔ)法:debug_connection[IP|CIDR]
#這個(gè)設(shè)置項(xiàng)實(shí)際上屬于事件類配置鳄厌,因此必須放在events{……}中才會(huì)生效荞胡。它的值可以是IP地址或者是CIRD地址。
#debug_connection 10.224.66.14; #或是debug_connection 10.224.57.0/24
#這樣了嚎,僅僅以上IP地址的請(qǐng)求才會(huì)輸出debug級(jí)別的日志泪漂,其他請(qǐng)求仍然沿用error_log中配置的日志級(jí)別。
#注意:在使用debug_connection前新思,需確保在執(zhí)行configure時(shí)已經(jīng)加入了--with-debug參數(shù)窖梁,否則不會(huì)生效。
worker_connections 1024;
}
##核心轉(zhuǎn)儲(chǔ)(coredump):在Linux系統(tǒng)中夹囚,當(dāng)進(jìn)程發(fā)生錯(cuò)誤或收到信號(hào)而終止時(shí)纵刘,系統(tǒng)會(huì)將進(jìn)程執(zhí)行時(shí)的內(nèi)存內(nèi)容(核心映像)寫入一個(gè)文件(core文件),以作為調(diào)試只用荸哟,這就是所謂的核心轉(zhuǎn)儲(chǔ)(coredump).
http {
##嵌入其他配置文件 語(yǔ)法:include /path/file
#參數(shù)既可以是絕對(duì)路徑也可以是相對(duì)路徑(相對(duì)于Nginx的配置目錄假哎,即nginx.conf所在的目錄)
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr -(客戶端IP地址) $remote_user(用戶端名稱)
[$time_local] (時(shí)間)
"$request" (請(qǐng)求內(nèi)容 )
'$status請(qǐng)求狀態(tài)
$body_bytes_sent "
$http_referer"(用于記錄用戶在哪個(gè)鏈接跳轉(zhuǎn)過(guò)來(lái)的)
'"$http_user_agent"用戶代理
"$http_x_forwarded_for"客戶端ip';
#access_log logs/access.log main; 用戶請(qǐng)求記錄
sendfile on; 用于進(jìn)行文件高效傳輸
#tcp_nopush on;和sendfile配合使用瞬捕,數(shù)據(jù)包累計(jì)一定大小一起處理
#keepalive_timeout 0;客戶端鏈接超時(shí)時(shí)間
keepalive_timeout 65;tcp使用完不會(huì)立即消除,會(huì)保存一段時(shí)間舵抹,提高效率
#gzip on;壓縮
server {
##listen監(jiān)聽(tīng)的端口
#語(yǔ)法:listen address:port [ default(deprecated in 0.8.21) | default_server | [ backlog=num | rcvbuf=size | sndbuf=size | accept_filter=filter | deferred | bind | ssl ] ]
#default_server: 如果沒(méi)有設(shè)置這個(gè)參數(shù)肪虎,那么將會(huì)以在nginx.conf中找到的第一個(gè)server塊作為默認(rèn)server塊
listen 8080;
#主機(jī)名稱:其后可以跟多個(gè)主機(jī)名稱,開(kāi)始處理一個(gè)HTTP請(qǐng)求時(shí)惧蛹,nginx會(huì)取出header頭中的Host扇救,與每個(gè)server中的server_name進(jìn)行匹配,以此決定到底由那一個(gè)server來(lái)處理這個(gè)請(qǐng)求香嗓。有可能一個(gè)Host與多個(gè)server塊中的server_name都匹配迅腔,這時(shí)會(huì)根據(jù)匹配優(yōu)先級(jí)來(lái)選擇實(shí)際處理的server塊。server_name與Host的匹配優(yōu)先級(jí)見(jiàn)文末靠娱。
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
#location / {
# root html;
# index index.html index.htm;
#}
##location 語(yǔ)法: location [=|~|~*|^~] /uri/ { ... }
# location的使用實(shí)例見(jiàn)文末沧烈。
#注意:location時(shí)有順序的,當(dāng)一個(gè)請(qǐng)求有可能匹配多個(gè)location時(shí)像云,實(shí)際上這個(gè)請(qǐng)求會(huì)被第一個(gè)location處理锌雀。
location / {
proxy_pass http://192.168.1.60;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apaches document root
# concurs with nginxs one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
如果出現(xiàn)pid 找不到問(wèn)題,就重新創(chuàng)建目錄 pid無(wú)效從新指定pid 示例如下
nginx 常用指令
start nginx:打開(kāi) nginx
nginx -t :測(cè)試配置文件是否有語(yǔ)法錯(cuò)誤
nginx -s reopen:重啟Nginx
nginx -s reload:重新加載Nginx配置文件迅诬,然后以優(yōu)雅的方式重啟Nginx
nginx -s stop:強(qiáng)制停止Nginx服務(wù)
nginx -s quit:優(yōu)雅地停止Nginx服務(wù)(即處理完所有請(qǐng)求后再停止服務(wù))
nginx -v 版本號(hào)
nginx -V具體信息
nginx -腋逆?幫助文檔
nginx -c 指定特定的配置文件
nginx 日志分割
Nginx 日志切割-手動(dòng)
現(xiàn)有的日志都會(huì)存在 access.log 文件中,但是隨著時(shí)間的推移百框,這個(gè)文件的內(nèi)容會(huì)越來(lái)越多闲礼,體積會(huì)越來(lái)越大牍汹,不便于運(yùn)維人員查看铐维,所以我們可以通過(guò)把
文件切割為多份不同的小文件作為日志,切割規(guī)則可以以天為單位慎菲,如果每天有幾百G或者幾個(gè)T的日志的話嫁蛇,則可以按需以每半天或者每小時(shí)對(duì)日志切割一
具體步驟如下:
1. 創(chuàng)建一個(gè)shell可執(zhí)行文件: cut_my_log.sh ,內(nèi)容為:
#!/bin/bash
LOG_PATH="/var/log/nginx/"
RECORD_TIME=$(date -d "yesterday" +%Y-%m-%d+%H:%M)
PID=/var/run/nginx/nginx.pid
mv ${LOG_PATH}/access.log ${LOG_PATH}/access.${RECORD_TIME}.log
mv ${LOG_PATH}/error.log ${LOG_PATH}/error.${RECORD_TIME}.log
#向Nginx主進(jìn)程發(fā)送信號(hào)露该,用于重新打開(kāi)日志文件
kill -USR1 `cat $PID`
2. 為cut_my_log.sh 添加可執(zhí)行的權(quán)限:
chmod +x cut_my_log.sh
3. 測(cè)試日志切割后的結(jié)果:
./cut_my_log.sh
自動(dòng)切割
Nginx 日志切割-定時(shí)
使用定時(shí)任務(wù)
1. 安裝定時(shí)任務(wù):
yum install crontabs
2. crontab -e 編輯并且添加一行新的任務(wù):
*/1 * * * * /usr/local/nginx/sbin/cut_my_log.sh
3. 重啟定時(shí)任務(wù):
service crond restart
附:常用定時(shí)任務(wù)命令:
service crond start //啟動(dòng)服務(wù)
service crond stop //關(guān)閉服務(wù)
service crond restart //重啟服務(wù)
service crond reload //重新載入配置
crontab -e // 編輯任務(wù)
crontab -l // 查看任務(wù)列表
定時(shí)任務(wù)表達(dá)式:
Cron表達(dá)式是睬棚,分為5或6個(gè)域,每個(gè)域代表一個(gè)含義解幼,如下所示:
分時(shí)日月星期幾年(可選)
取值范圍0-59 0-23 1-31 1-12 1-7 2019/2020/2021/…
常用表達(dá)式:
每分鐘執(zhí)行:
*/1 * * * *
每日凌晨(每天晚上23:59)執(zhí)行:
59 23 * * *
每日凌晨1點(diǎn)執(zhí)行:
0 1 * * *
參考文獻(xiàn):
每天定時(shí)為數(shù)據(jù)庫(kù)備份:https://www.cnblogs.com/leechenxiang/p/7110382.html
例子:使用nginx提供靜態(tài)資源服務(wù)器
配置conf文件修改server
設(shè)置別名
文件壓縮
目的提高傳輸效率抑党,節(jié)約帶寬
刷新:command+shfit+r 不會(huì)出現(xiàn)緩存
location匹配規(guī)則
location匹配命令
~ #波浪線表示執(zhí)行一個(gè)正則匹配,區(qū)分大小寫
*代表不區(qū)分大小寫
~* #表示執(zhí)行一個(gè)正則匹配撵摆,不區(qū)分大小寫
^~ #^~表示普通字符匹配底靠,如果該選項(xiàng)匹配,只匹配該選項(xiàng)特铝,不匹配別的選項(xiàng)暑中,一般用來(lái)匹配目錄
= #進(jìn)行普通字符精確匹配
@ #"@" 定義一個(gè)命名的 location壹瘟,使用在內(nèi)部定向時(shí),例如 error_page, try_files
location 匹配的優(yōu)先級(jí)(與location在配置文件中的順序無(wú)關(guān))
= 精確匹配會(huì)第一個(gè)被處理鳄逾。如果發(fā)現(xiàn)精確匹配稻轨,nginx停止搜索其他匹配。
普通字符匹配雕凹,正則表達(dá)式規(guī)則和長(zhǎng)的塊規(guī)則將被優(yōu)先和查詢匹配殴俱,也就是說(shuō)如果該項(xiàng)匹配還需去看有沒(méi)有正則表達(dá)式匹配和更長(zhǎng)的匹配。
^~ 則只匹配該規(guī)則枚抵,nginx停止搜索其他匹配粱挡,否則nginx會(huì)繼續(xù)處理其他location指令。
最后匹配理帶有"~"和"~*"的指令俄精,如果找到相應(yīng)的匹配询筏,則nginx停止搜索其他匹配;當(dāng)沒(méi)有正則表達(dá)式或者沒(méi)有正則表達(dá)式被匹配的情況下竖慧,那么匹配程度最高的逐字匹配指令會(huì)被使用嫌套。
location 優(yōu)先級(jí)官方文檔
Directives with the = prefix that match the query exactly. If found, searching stops.
All remaining directives with conventional strings, longest match first. If this match used the ^~ prefix, searching stops.
Regular expressions, in order of definition in the configuration file.
If #3 yielded a match, that result is used. Else the match from #2 is used.
=前綴的指令嚴(yán)格匹配這個(gè)查詢。如果找到圾旨,停止搜索踱讨。
所有剩下的常規(guī)字符串,最長(zhǎng)的匹配砍的。如果這個(gè)匹配使用^?前綴痹筛,搜索停止。
正則表達(dá)式廓鞠,在配置文件中定義的順序帚稠。
如果第3條規(guī)則產(chǎn)生匹配的話,結(jié)果被使用床佳。否則滋早,使用第2條規(guī)則的結(jié)果。
location = / {
# 只匹配"/".
[ configuration A ]
}
location / {
# 匹配任何請(qǐng)求砌们,因?yàn)樗姓?qǐng)求都是以"/"開(kāi)始
# 但是更長(zhǎng)字符匹配或者正則表達(dá)式匹配會(huì)優(yōu)先匹配
[ configuration B ]
}
location ^~ /images/ {
# 匹配任何以 /images/ 開(kāi)始的請(qǐng)求杆麸,并停止匹配 其它location
[ configuration C ]
}
location ~* .(gif|jpg|jpeg)$ {
# 匹配以 gif, jpg, or jpeg結(jié)尾的請(qǐng)求.
# 但是所有 /images/ 目錄的請(qǐng)求將由 [Configuration C]處理.
[ configuration D ]
}
例:精準(zhǔn)匹配、只匹配這個(gè)
DNS域名解析
nginx跨域問(wèn)題
解決方式
nginx配置靜態(tài)資源防盜鏈
nginx模塊化體系
nginx core實(shí)現(xiàn)了底層的通訊協(xié)議浪感,為其他模塊和Nginx進(jìn)程構(gòu)建了基本的運(yùn)行時(shí)環(huán)境昔头,并且構(gòu)建了其他各模塊的協(xié)作基礎(chǔ)。
http模塊和mail模塊位于nginx core和各功能模塊的中間層影兽,這2個(gè)模塊在nginx core之上實(shí)現(xiàn)了另外一層抽象揭斧,分別處理與http協(xié)議和email相關(guān)協(xié)議(SMTP/IMAP/POP3)有關(guān)的事件,并且確保這些事件能被以正確的順序調(diào)用其它的一些功能模塊赢笨。
nginx功能模塊基本上分為如下幾種類型:
(1) event module:搭建了獨(dú)立于操作系統(tǒng)的事件處理機(jī)制的框架未蝌,以及提供了各具體事件的處理驮吱,包括ngx_event_module、ngx_event_core_module和ngx_epoll_module等萧吠,Nginx具體使用何種事件處理模塊左冬,這依賴于具體的操作系統(tǒng)和編譯選項(xiàng)。
(2) phase handler:此類型的模塊也被直接稱為handler模塊纸型,主要負(fù)責(zé)處理客戶端請(qǐng)求并產(chǎn)生待響應(yīng)內(nèi)容拇砰,比如ngx_http_module模塊,負(fù)責(zé)客戶端的靜態(tài)頁(yè)面請(qǐng)求處理并將對(duì)應(yīng)的磁盤文件準(zhǔn)備為響應(yīng)內(nèi)容輸出狰腌。
(3) output filter:也稱為filter模塊除破,主要是負(fù)責(zé)對(duì)輸出的內(nèi)容進(jìn)行處理,可以對(duì)輸出進(jìn)行修改琼腔,比如可以實(shí)現(xiàn)對(duì)輸出的所有html頁(yè)面增加預(yù)定義的footbar一類的工作瑰枫,或者對(duì)輸出的圖片的URL進(jìn)行替換之類的工作。
(4) upstream:實(shí)現(xiàn)反向代理功能丹莲,將真正的請(qǐng)求轉(zhuǎn)發(fā)到后端服務(wù)器上光坝,并從后端服務(wù)器上讀取響應(yīng),發(fā)回客戶端甥材,upstream模塊是一種特殊的handler盯另,只不過(guò)響應(yīng)內(nèi)容不是真正由自己產(chǎn)生的,而是從后端服務(wù)器上讀取的洲赵。
(5) load-balancer:負(fù)載均衡模塊鸳惯,實(shí)現(xiàn)特定的算法,在眾多的后端服務(wù)器中叠萍,選擇一個(gè)服務(wù)器出來(lái)作為某個(gè)請(qǐng)求的轉(zhuǎn)發(fā)服務(wù)器芝发。
(6) extend module:根據(jù)特定業(yè)務(wù)需要編寫的第三方模塊较沪。
三、請(qǐng)求處理
下面將會(huì)以http請(qǐng)求處理為例來(lái)說(shuō)明請(qǐng)求凤跑、配置和模塊是如何串起來(lái)的嗓奢。
當(dāng)Nginx讀取到一個(gè)HTTP Request的header時(shí),首先查找與這個(gè)請(qǐng)求關(guān)聯(lián)的虛擬主機(jī)的配置蜀撑,如果找到了則這個(gè)請(qǐng)求會(huì)經(jīng)歷以下幾個(gè)階段的處理(phase handlers):
NGX_HTTP_POST_READ_PHASE: 讀取請(qǐng)求內(nèi)容階段
NGX_HTTP_SERVER_REWRITE_PHASE: Server請(qǐng)求地址重寫階段
NGX_HTTP_FIND_CONFIG_PHASE:配置查找階段
NGX_HTTP_REWRITE_PHASE:Location請(qǐng)求地址重寫階段
NGX_HTTP_POST_REWRITE_PHASE:請(qǐng)求地址重寫提交階段
NGX_HTTP_PREACCESS_PHASE: 訪問(wèn)權(quán)限檢查準(zhǔn)備階段
NGX_HTTP_ACCESS_PHASE: 訪問(wèn)權(quán)限檢查階段
NGX_HTTP_POST_ACCESS_PHASE: 訪問(wèn)權(quán)限檢查提交階段
NGX_HTTP_TRY_FILES_PHASE: 內(nèi)容產(chǎn)生階段
NGX_HTTP_LOG_PHASE:日志模塊處理階段
在內(nèi)容產(chǎn)生階段,為了給一個(gè)request產(chǎn)生正確的response,Nginx必須把這個(gè)請(qǐng)求交給一個(gè)合適的content handler去處理赫蛇。如果這個(gè)request對(duì)應(yīng)的location在配置文件中被明確指定了一個(gè)content handler,那么Nginx就可以通過(guò)對(duì)location的匹配,直接找到這個(gè)對(duì)應(yīng)的handler雾叭,并把這request交給這個(gè)content handler去處理悟耘。這樣的配置指令包括perl、flv织狐、proxy_pass暂幼、mp4等筏勒。
如果一個(gè)request對(duì)應(yīng)的location并沒(méi)有直接配置的content handler,那么Nginx依次作如下嘗試:
(1) 如果一個(gè)location里面有配置random_index on,那么隨即選擇一個(gè)文件發(fā)送給客戶端。
(2) 如果一個(gè)location里面有配置index指令旺嬉,那么發(fā)送index指令指定的文件給客戶端管行。
(3) 如果一個(gè)location里面有配置autoindex on,那么就發(fā)送請(qǐng)求地址對(duì)應(yīng)的服務(wù)端路徑下的文件列表給客戶端邪媳。
(4) 如果這個(gè)request對(duì)應(yīng)的location上有設(shè)置gzip_static on,那么就查找是否有對(duì)應(yīng)的.gz文件存在捐顷,如果有的話,就發(fā)送這個(gè)客戶端(客戶端支持gzip的情況下).
(5) 請(qǐng)求的URI如果對(duì)應(yīng)的一個(gè)靜態(tài)文件雨效,static module就發(fā)送靜態(tài)文件的內(nèi)容到客戶端迅涮。
內(nèi)容產(chǎn)生階段完成以后,生成的輸出會(huì)被傳遞到filter模塊去進(jìn)行處理徽龟。filter模塊也是與location相關(guān)的叮姑。所有的filter模塊都被組織成了一條鏈。輸出會(huì)依次穿越所有的filter据悔,直到有一個(gè)filter模塊的返回值表明已經(jīng)處理完成戏溺。 接下來(lái)就可以發(fā)送response給客戶端了。