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