Web 服務(wù)器:NGINX
前面講過的 Httpd 和 Tomcat 以及這個(gè)小節(jié)所講的 Nginx 都是 Web 服務(wù)器,他們?nèi)甙l(fā)展到今天并沒有很明顯地成為某個(gè)產(chǎn)品一枝獨(dú)秀的強(qiáng)壟斷局面,因?yàn)樗麄冇懈髯缘奶攸c(diǎn)和適用的場(chǎng)合,在某些場(chǎng)合他們甚至可以共用達(dá)到互補(bǔ)的功能。
1. Nginx 簡介
Nginx 是由俄羅斯工程師伊戈?duì)枴べ愃饕蜷_發(fā)的,同樣是開源免費(fèi)的。雖然它和 Httpd 與 Tomcat 都稱為 Web 服務(wù)器,但是它的功能強(qiáng)大得簡直不像是個(gè) Web 服務(wù)器,比如它的反向代理和負(fù)載均衡,幾乎成了現(xiàn)在 Web 應(yīng)用的必備基礎(chǔ)設(shè)施。與此同時(shí)它的高并發(fā)處理能力也是很強(qiáng)大的,是 Httpd 強(qiáng)有力的競(jìng)爭者。至于實(shí)現(xiàn) Servlet 規(guī)范的 Tomcat 倒是替代不了,因?yàn)?Nginx 不支持。
三種服務(wù)器各自適用場(chǎng)景:
Nginx:適合靜態(tài)內(nèi)容服務(wù)和反向代理服務(wù)器;它的特點(diǎn)是并發(fā)能力強(qiáng),但是不適合 CPU 密集的請(qǐng)求,因?yàn)椴l(fā)場(chǎng)景的 CPU 上下文的切換花銷挺高的。所以很適合當(dāng)網(wǎng)關(guān)做代理來分發(fā)請(qǐng)求的場(chǎng)景。
Httpd:適合Rewrite 場(chǎng)景比較多,對(duì) CPU 資源有一定要求的場(chǎng)景;并發(fā)能力相對(duì)弱些,可以借助 Nginx 的分發(fā)做負(fù)載均衡,水平擴(kuò)展 Httpd 的服務(wù)能力。
Tomcat:Java 應(yīng)用容器,同樣可以借助 Nginx 實(shí)現(xiàn)水平服務(wù)的擴(kuò)展;
選擇 Nginx 的理由:
- 輕量且并發(fā)能力強(qiáng);
- 反向代理服務(wù)器的大規(guī)模可擴(kuò)展事件驅(qū)動(dòng)架構(gòu);
- 多重身份:Web 服務(wù)器,可代理七層協(xié)議的負(fù)載均衡服務(wù)器,可作為郵件代理服務(wù)器。
2. Nginx 支持高并發(fā)的原理
前面我們也說了,Nginx 的并發(fā)能力非常好,那么它能支持這么大的并發(fā)量與其他的 Web 服務(wù)器差別在哪里呢?
一般的 Web 服務(wù)器在解決并發(fā)問題時(shí),通常采用多線程或者多進(jìn)程來處理請(qǐng)求。這種處理機(jī)制在訪問量小的時(shí)候處理能力確實(shí)不錯(cuò),但是當(dāng)并發(fā)量大了線程或者進(jìn)程頻繁地切換對(duì)資源是一種非常大的損耗。
但是 Nginx 卻是單線程的,它采用 事件驅(qū)動(dòng) + IO 多路復(fù)用的處理模型。
- 單線程可以解決線程切換的損耗和多線程的資源競(jìng)爭問題;
- 事件驅(qū)動(dòng): Nginx 在啟動(dòng)后,master 進(jìn)程 fork() 多個(gè)相互獨(dú)立的 worker 進(jìn)程,請(qǐng)求的事件由 work 進(jìn)程去處理;
- IO 多路復(fù)用: 一個(gè)請(qǐng)求的處理過程并不是獨(dú)占一個(gè) work 進(jìn)程,當(dāng)請(qǐng)求有阻塞等待的時(shí)候,work 進(jìn)程會(huì)空出來去處理其它的請(qǐng)求。
3. 反向代理
代理一詞在我們生活中很常見,有反向代理肯定也有正向代理。他們之間的主要區(qū)別是,正向代理客戶端明確地知道自己最終訪問的是誰,反向代理客戶端就只了解到代理服務(wù),不清楚具體誰在提供服務(wù)。以下列舉 2 個(gè)例子說明:
-
反向代理:你去商店買東西,東西是商家到廠里進(jìn)貨過來的,你不需要知道具體的廠家,只要關(guān)心你所需要的商品;Nginx 就是一個(gè)典型的反向代理服務(wù)器,所有人都只知道
Nginx
的服務(wù)地址,Nginx
再負(fù)載到后端去請(qǐng)求別到服務(wù)。 -
正向代理:你在網(wǎng)上點(diǎn)了外賣,你清楚地知道是哪個(gè)商家提供的食品,但是這個(gè)外賣并不是你直接去拿的,是經(jīng)由外賣小哥幫你送來的,這個(gè)過程中你和食品店的老板都知道雙方的存在,那么外賣小哥就是你的一個(gè)正向代理而已。
3.1 反向代理的好處
- 可以隱藏后端的具體服務(wù),提高了系統(tǒng)的安全級(jí)別;
- 可以實(shí)現(xiàn)服務(wù)的負(fù)載均衡,請(qǐng)求經(jīng)代理轉(zhuǎn)發(fā)到不同的服務(wù)提供者,可以無限擴(kuò)容后端服務(wù),提高并發(fā)處理能力;
- 結(jié)合監(jiān)控服務(wù),可以智能地移除故障機(jī)器上面的服務(wù),提高可靠性。
4. Nginx 配置
反向代理你可以簡單的理解為轉(zhuǎn)發(fā),轉(zhuǎn)發(fā)重要的一點(diǎn)是要配置轉(zhuǎn)發(fā)規(guī)則。Nginx 配置的默認(rèn)位置是在 /conf/nginx.conf
,配置中關(guān)于 Http 的主要配置如下:
http {
....
server {
listen 80;#監(jiān)聽端口
server_name localhost;#域名
# 禁止訪問隱藏文件
# Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac).
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
# 默認(rèn)請(qǐng)求
location / {
# 首先嘗試將請(qǐng)求作為文件提供,然后作為目錄,然后回退到顯示 404。
# try_files 指令將會(huì)按照給定它的參數(shù)列出順序進(jìn)行嘗試,第一個(gè)被匹配的將會(huì)被使用。
# try_files $uri $uri/ =404;
try_files $uri $uri/ /index.php?path_info=$uri&$args =404;
access_log off;
expires max;
}
# 所有動(dòng)態(tài)請(qǐng)求都轉(zhuǎn)發(fā)給tomcat處理
location ~ .(jsp|do)$ {
proxy_pass http://test;
}
upstream test { # 負(fù)載均衡配置
server localhost:8080;
server localhost:8081;
}
}
- Http:某臺(tái)虛擬服務(wù)器;
- Server : 定義了服務(wù)器監(jiān)聽哪個(gè)端口,哪個(gè)域名(可以有多個(gè)域名解析到同一臺(tái)服務(wù)器上面);
- Location :根據(jù)請(qǐng)求路徑,做不同的響應(yīng)和轉(zhuǎn)發(fā);
- Upstream : 里面可以配置多個(gè)監(jiān)聽的服務(wù)地址,請(qǐng)求過來可以依次亦或根據(jù)配置的權(quán)重進(jìn)行輪詢,從而達(dá)到負(fù)載均衡的效果;
Nginx 修改完配置可以不用重啟,運(yùn)行下面命令重新加載下配置。
nginx -s reload
5. 小結(jié)
Nginx 總體使用起來比較簡單,它的并發(fā)模型有別于一般的 Web 服務(wù)端,是用單線程的事件驅(qū)動(dòng) + IO 復(fù)用模型,這種模型適合處理 IO 密集型不適合 CPU 密集型的場(chǎng)景,Httpd 正好相反。所以 Nginx 特別適合充當(dāng)一個(gè)請(qǐng)求轉(zhuǎn)發(fā)的代理角色。Nginx 的 Work 數(shù)量和每個(gè) Work 能同時(shí)處理的請(qǐng)求數(shù)量都是可以在配置調(diào)整的,這個(gè)可以根據(jù)具體的服務(wù)器性能做相應(yīng)的優(yōu)化調(diào)整。Work 的數(shù)量一般是對(duì)應(yīng)服務(wù)器的 CPU 核數(shù)。