淺談nginx原理及配置

Nginx同Apache一樣都是一種WEB服務(wù)器?;赗EST架構(gòu)風(fēng)格,以統(tǒng)一資源描述符(Uniform Resources Identifier)URI或者統(tǒng)一資源定位符(Uniform Resources Locator)URL作為溝通依據(jù),通過HTTP協(xié)議提供各種網(wǎng)絡(luò)服務(wù)。Apache的發(fā)展時期很長,而且是毫無爭議的世界第一大服務(wù)器。它有著很多優(yōu)點:穩(wěn)定、開源、跨平臺等等。它出現(xiàn)的時間太長了,它興起的年代,互聯(lián)網(wǎng)產(chǎn)業(yè)遠遠比不上現(xiàn)在,所以它被設(shè)計為一個重量級的服務(wù)器。它不支持高并發(fā),在Apache上運行數(shù)以萬計的并發(fā)訪問,會導(dǎo)致服務(wù)器消耗大量內(nèi)存(新起線程會分配內(nèi)存)。操作系統(tǒng)對其進行進程或線程間的切換也消耗了大量的CPU資源,導(dǎo)致HTTP請求的平均響應(yīng)速度降低。Nginx是輕量級高并發(fā)服務(wù)器,開源、跨平臺且使用基于事件驅(qū)動架構(gòu),這些優(yōu)秀的設(shè)計帶來的極大的穩(wěn)定性。nginx的模塊根據(jù)其功能基本上可以分為以下幾種類型:

event module: 搭建了獨立于操作系統(tǒng)的事件處理機制的框架,及提供了各具體事件的處理。包括ngx_events_module, ngx_event_core_module和ngx_epoll_module等。nginx具體使用何種事件處理模塊,這依賴于具體的操作系統(tǒng)和編譯選項。

phase handler: 此類型的模塊也被直接稱為handler模塊。主要負責(zé)處理客戶端請求并產(chǎn)生待響應(yīng)內(nèi)容,比如ngx_http_static_module模塊,負責(zé)客戶端的靜態(tài)頁面請求處理并將對應(yīng)的磁盤文件準(zhǔn)備為響應(yīng)內(nèi)容輸出。

output filter: 也稱為filter模塊,主要是負責(zé)對輸出的內(nèi)容進行處理,可以對輸出進行修改。例如,可以實現(xiàn)對輸出的所有html頁面增加預(yù)定義的footbar一類的工作,或者對輸出的圖片的URL進行替換之類的工作。

upstream: upstream模塊實現(xiàn)反向代理的功能,將真正的請求轉(zhuǎn)發(fā)到后端服務(wù)器上,并從后端服務(wù)器上讀取響應(yīng),發(fā)回客戶端。upstream模塊是一種特殊的handler,只不過響應(yīng)內(nèi)容不是真正由自己產(chǎn)生的,而是從后端服務(wù)器上讀取的。

load-balancer: 負載均衡模塊,實現(xiàn)特定的算法,在眾多的后端服務(wù)器中,選擇一個服務(wù)器出來作為某個請求的轉(zhuǎn)發(fā)服務(wù)器。



一.正向代理及反向代理

在如今的網(wǎng)絡(luò)環(huán)境下,我們?nèi)绻捎诩夹g(shù)需要要去訪問國外的某些網(wǎng)站,此時你會發(fā)現(xiàn)位于國外的某網(wǎng)站我們通過瀏覽器是沒有辦法訪問的,此時大家可能都會用一個操作FQ進行訪問,F(xiàn)Q的方式主要是找到一個可以訪問國外網(wǎng)站的代理服務(wù)器,我們將請求發(fā)送給代理服務(wù)器,代理服務(wù)器去訪問國外的網(wǎng)站,然后將訪問到的數(shù)據(jù)傳遞給我們!上述這樣的代理模式稱為正向代理,正向代理最大的特點是客戶端非常明確要訪問的服務(wù)器地址;服務(wù)器只清楚請求來自哪個代理服務(wù)器,而不清楚來自哪個具體的客戶端;正向代理模式屏蔽或者隱藏了真實客戶端信息。客戶端必須設(shè)置正向代理服務(wù)器,當(dāng)然前提是要知道正向代理服務(wù)器的IP地址,還有代理程序的端口。正向代理,"它代理的是客戶端",是一個位于客戶端和原始服務(wù)器(origin server)之間的服務(wù)器。正向代理的用途:訪問原來無法訪問的資源,如Google;可以做緩存,加速訪問資源;對客戶端訪問授權(quán),上網(wǎng)進行認證;代理可以記錄用戶訪問記錄(上網(wǎng)行為管理),對外隱藏用戶信息。

多個客戶端給服務(wù)器發(fā)送的請求,Nginx服務(wù)器接收到之后,按照一定的規(guī)則分發(fā)給了后端的業(yè)務(wù)處理服務(wù)器進行處理了。此時請求的來源也就是客戶端是明確的,但是請求具體由哪臺服務(wù)器處理的并不明確了,Nginx扮演的就是一個反向代理角色。客戶端是無感知代理的存在的,反向代理對外都是透明的,訪問者并不知道自己訪問的是一個代理。因為客戶端不需要任何配置就可以訪問。反向代理,"它代理的是服務(wù)端",主要用于服務(wù)器集群分布式部署的情況下,反向代理隱藏了服務(wù)器的信息。反向代理的作用:保證內(nèi)網(wǎng)的安全,通常將反向代理作為公網(wǎng)訪問地址,Web服務(wù)器是內(nèi)網(wǎng);負載均衡,通過反向代理服務(wù)器來優(yōu)化網(wǎng)站的負載。



二.nginx負載均衡原理

當(dāng)前大多數(shù)的互聯(lián)網(wǎng)系統(tǒng)都使用了服務(wù)器集群技術(shù),集群是將相同服務(wù)部署在多臺服務(wù)器上構(gòu)成一個集群整體對外提供服務(wù),這些集群可以是 Web 應(yīng)用服務(wù)器集群,也可以是數(shù)據(jù)庫服務(wù)器集群,還可以是分布式緩存服務(wù)器集群等等。客戶端發(fā)送的、Nginx反向代理服務(wù)器接收到的請求數(shù)量,就是我們說的負載量。請求數(shù)量按照一定的規(guī)則進行分發(fā)到不同的服務(wù)器處理的規(guī)則,就是一種均衡規(guī)則。所以將服務(wù)器接收到的請求按照規(guī)則分發(fā)的過程,稱為負載均衡。

負載均衡在實際項目操作過程中,有硬件負載均衡和軟件負載均衡兩種,硬件負載均衡也稱為硬負載,如F5負載均衡,相對造價昂貴成本較高,但是數(shù)據(jù)的穩(wěn)定性安全性等等有非常好的保障,如中國移動中國聯(lián)通這樣的公司才會選擇硬負載進行操作;更多的公司考慮到成本原因,會選擇使用軟件負載均衡,軟件負載均衡是利用現(xiàn)有的技術(shù)結(jié)合主機硬件實現(xiàn)的一種消息隊列分發(fā)機制。

LVS、Nginx、HAProxy 是目前使用最廣泛的三種軟件負載均衡軟件。目前關(guān)于網(wǎng)站架構(gòu)一般比較合理流行的架構(gòu)方案:Web 前端采用 Nginx/HAProxy+Keepalived 作負載均衡器;后端采用 MySQ L數(shù)據(jù)庫一主多從和讀寫分離,采用 LVS+Keepalived 的架構(gòu)。

1.LVS

LVS 是 Linux Virtual Server 的簡稱,也就是 Linux 虛擬服務(wù)器?,F(xiàn)在 LVS 已經(jīng)是 Linux 標(biāo)準(zhǔn)內(nèi)核的一部分。LVS 的服務(wù)器集群由三部分組成:最前端的負載均衡層,中間的服務(wù)器集群層,最底端的數(shù)據(jù)共享存儲層。LVS 是四層負載均衡,也就是說建立在 OSI 模型的第四層——傳輸層之上,傳輸層上有我們熟悉的 TCP/UDP,LVS 支持 TCP/UDP 的負載均衡,它的效率是非常高的。LVS 的轉(zhuǎn)發(fā)主要通過修改 IP 地址(NAT 模式,分為源地址修改 SNAT 和目標(biāo)地址修改 DNAT)、修改目標(biāo) MAC(DR 模式)來實現(xiàn)。

NAT(Network Address Translation)是一種外網(wǎng)和內(nèi)網(wǎng)地址映射的技術(shù)。當(dāng)包到達 LVS 時,LVS 做目標(biāo)地址轉(zhuǎn)換(DNAT),將目標(biāo) IP 改為 RS(RealServer) 的 IP。RS 接收到包以后,仿佛是客戶端直接發(fā)給它的一樣。RS 處理完,返回響應(yīng)時,源 IP 是 RS IP,目標(biāo) IP 是客戶端的 IP。這時 RS 的包通過網(wǎng)關(guān)(LVS)中轉(zhuǎn),LVS 會做源地址轉(zhuǎn)換(SNAT),將包的源地址改為 VIP,這樣,這個包對客戶端看起來就仿佛是 LVS 直接返回給它的。

DR 模式下需要 LVS 和 RS 集群綁定同一個 VIP(RS 通過將 VIP 綁定在 loopback 實現(xiàn)),一個請求過來時,LVS 只需要將網(wǎng)絡(luò)幀的 MAC 地址修改為某一臺 RS 的 MAC,該包就會被轉(zhuǎn)發(fā)到相應(yīng)的 RS 處理,注意此時的源 IP 和目標(biāo) IP 都沒變,LVS 只是做了一下移花接木。RS 收到 LVS 轉(zhuǎn)發(fā)來的包時,鏈路層發(fā)現(xiàn) MAC 是自己的,到上面的網(wǎng)絡(luò)層,發(fā)現(xiàn) IP 也是自己的,于是這個包被合法地接受,RS 感知不到前面有 LVS 的存在。而當(dāng) RS 返回響應(yīng)時,只要直接向源 IP(即用戶的 IP)返回即可,不再經(jīng)過 LVS。DR 模式具有較好的性能,也是目前大型網(wǎng)站使用最廣泛的一種負載均衡手段。


LVS?抗負載能力強、是工作在傳輸層上僅作分發(fā)之用,沒有流量的產(chǎn)生,這個特點也決定了它在負載均衡軟件里的性能最強的,對內(nèi)存和 cpu 資源消耗比較低;配置性比較低,這是一個缺點也是一個優(yōu)點,因為沒有可太多配置的東西,所以并不需要太多接觸,大大減少了人為出錯的幾率;工作穩(wěn)定,因為其本身抗負載能力很強,自身有完整的雙機熱備方案,如 LVS + Keepalived;因為 LVS 工作在傳輸層,所以它幾乎可以對所有應(yīng)用做負載均衡,包括 http、數(shù)據(jù)庫、在線聊天室等等。

2.nginx

Nginx 負載均衡主要是對七層網(wǎng)絡(luò)通信模型中的第七層應(yīng)用層上的 http、https 進行支持。Nginx 是以反向代理的方式進行負載均衡的。Nginx 實現(xiàn)負載均衡的分配策略有很多,Nginx 的 upstream 目前支持以下幾種方式:

輪詢(默認):每個請求按時間順序逐一分配到不同的后端服務(wù)器,如果后端服務(wù)器 down 掉,能自動剔除。

weight:指定輪詢幾率,weight 和訪問比率成正比,用于后端服務(wù)器性能不均的情況。

ip_hash:每個請求按訪問 ip 的 hash 結(jié)果分配,這樣每個訪客固定訪問一個后端服務(wù)器,可以解決 session 的問題。

fair(第三方):按后端服務(wù)器的響應(yīng)時間來分配請求,響應(yīng)時間短的優(yōu)先分配。

url_hash(第三方):按訪問 url 的 hash 結(jié)果來分配請求,使每個 url 定向到同一個后端服務(wù)器,后端服務(wù)器為緩存時比較有效。

Nginx 負載均衡主要優(yōu)點有:跨平臺、配置異常簡單、事件驅(qū)動、非阻塞、高并發(fā)連接、Master/Worker 結(jié)構(gòu)、內(nèi)存消耗小、內(nèi)置的健康檢查功能(如果 Nginx 代理的后端的某臺 Web 服務(wù)器宕機了,不會影響前端訪問)、節(jié)省帶寬(支持 GZIP 壓縮,可以添加瀏覽器本地緩存的 Header 頭)、穩(wěn)定性高。

Nginx 負載均衡主要缺點有:Nginx 僅能支 持http、https 、tcp、 Email等協(xié)議,這樣就在適用范圍上面小些;對后端服務(wù)器的健康檢查,只支持通過端口來檢測,不支持通過 ur l來檢測;不支持 Session 的直接保持,但能通過 ip_hash 來解決。

3.HAProxy

HAProxy 支持兩種代理模式 TCP(四層)和HTTP(七層),也是支持虛擬主機的。HAProxy 的優(yōu)點能夠補充 Nginx 的一些缺點,比如支持 Session 的保持,Cookie 的引導(dǎo);同時支持通過獲取指定的 url 來檢測后端服務(wù)器的狀態(tài)。單純從效率上來講 HAProxy 會比 Nginx 有更出色的負載均衡速度,在并發(fā)處理上也是優(yōu)于 Nginx 的。HAProxy 負載均衡策略非常多:Round-robin(輪循)、Weight-round-robin(帶權(quán)輪循)、source(原地址保持)、RI(請求URL)、rdp-cookie(根據(jù)cookie)。

三.nginx支持高并發(fā)原理

同步異步、阻塞非阻塞:

同步與異步,重點在于消息通知的方式;阻塞與非阻塞,重點在于等消息時候的行為。同步阻塞:小明在柜臺干等著拿奶茶;同步非阻塞:小明在柜臺邊刷微博邊等著拿奶茶;異步阻塞:小明拿著小票啥都不干,一直等著店員通知他拿奶茶;異步非阻塞:小明拿著小票,刷著微博,等著店員通知他拿奶茶。

select、poll、epoll:

當(dāng)連接有I/O流事件產(chǎn)生的時候,就會去喚醒進程去處理。select與poll原理是一樣的,只不過select只能觀察1024個連接,poll可以觀察無限個連接,進程并不知道是哪個連接產(chǎn)生的I/O流事件,于是進程就挨個去問:“請問是你有事要處理嗎?”......問了99999遍,哦,原來是第100000個進程有事要處理。那么,前面這99999次就白問了,白白浪費寶貴的CPU時間片了。epoll當(dāng)連接有I/O流事件產(chǎn)生的時候,epoll就會去告訴進程哪個連接有I/O流事件產(chǎn)生,然后進程就去處理這個連接的IO事件。Nginx是基于epoll的,異步非阻塞的服務(wù)器程序。Apache處理一個請求是同步阻塞的模式,每到達一個請求,Apache都會去fork一個子進程去處理這個請求,直到這個請求處理完畢。

nginx進程模型:


多進程:一個 Master 進程、多個 Worker 進程

Master 進程:管理 Worker 進程,加載配置文件,初始化監(jiān)聽的 socket,fork 出多個 Worker 進程

對外接口:接收外部的操作(信號)

對內(nèi)轉(zhuǎn)發(fā):根據(jù)外部的操作的不同,通過信號管理 Worker

監(jiān)控:監(jiān)控 worker 進程的運行狀態(tài),worker 進程異常終止后,自動重啟 worker 進程

Worker 進程:所有 Worker 進程都是平等的,在 nginx.conf 中配置,一般設(shè)置為核心數(shù),充分利用 CPU 資源,同時,避免進程數(shù)量過多,避免進程競爭 CPU 資源,增加上下文切換的損耗;網(wǎng)絡(luò)請求,由 Worker 進程處理,競爭新的連接,獲勝方通過三次握手,建立 Socket 連接,并處理請求。

四.nginx配置

nginx.conf的內(nèi)容通常是這樣的:

...

...? ? ? ? ? ? #核心摸塊

events {? ? ? ? #事件模塊

? ...

}

http {? ? # http 模塊

? ? server {? ? ? # server塊

? ? ? ? location [PATTERN] {? # location塊

? ? ? ? ? ? ...

? ? ? ? }

? ? ? ? location [PATTERN] {

? ? ? ? ? ? ...

? ? ? ? }

? ? }

? ? server {

? ? ? ...

? ? }

}

mail {? ? # mail 模塊

? ? server {? ? # server塊

? ? ? ? ? ...

? ? }

}

核心模塊

user admin; #配置用戶或者組

worker_processes 4; #允許生成的進程數(shù),默認為1

pid /nginx/pid/nginx.pid; #指定 nginx 進程運行文件存放地址

error_log log/error.log debug; #錯誤日志路徑,級別

事件模塊

events {

? ? accept_mutex on; #設(shè)置網(wǎng)路連接序列化,防止驚群現(xiàn)象發(fā)生,默認為on

? ? multi_accept on; #設(shè)置一個進程是否同時接受多個網(wǎng)絡(luò)連接,默認為off

? ? use epoll; #事件驅(qū)動模型select|poll|kqueue|epoll|resig

? ? worker_connections 1024; #最大連接數(shù),默認為512

}

http 模塊

http {

? ? include? ? ? mime.types;? #文件擴展名與文件類型映射表

? ? default_type? application/octet-stream; #默認文件類型,默認為text/plain

? ? access_log off; #取消服務(wù)日志

? ? sendfile on;? #允許 sendfile 方式傳輸文件,默認為off,可以在http塊,server塊,location塊

? ? sendfile_max_chunk 100k;? #每個進程每次調(diào)用傳輸數(shù)量不能大于設(shè)定的值,默認為0,即不設(shè)上限

? ? keepalive_timeout 65;? #連接超時時間,默認為75s,可以在http,server,location塊

? ? server

? ? {

? ? ? ? ? ? keepalive_requests 120; #單連接請求上限次數(shù)

? ? ? ? ? ? listen 80; #監(jiān)聽端口

? ? ? ? ? ? server_name? 127.0.0.1;? #監(jiān)聽地址

? ? ? ? ? ? index index.html index.htm index.php;

? ? ? ? ? ? root your_path;? #根目錄

? ? ? ? ? ? location ~ .php$

? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? fastcgi_pass unix:/var/run/php/php7.1-fpm.sock;

? ? ? ? ? ? ? ? ? #fastcgi_pass 127.0.0.1:9000;

? ? ? ? ? ? ? ? ? fastcgi_index index.php;

? ? ? ? ? ? ? ? ? include fastcgi_params;

? ? ? ? ? ? }

? ? }

}

location 查找規(guī)則

location = / {

? # 精確匹配 / ,主機名后面不能帶任何字符串

? [ config A ]

}

location? / {

? # 因為所有的地址都以 / 開頭,所以這條規(guī)則將匹配到所有請求

? # 但是正則和最長字符串會優(yōu)先匹配

? [ config B ]

}

location /documents/ {

? # 匹配任何以 /documents/ 開頭的地址,匹配符合以后,還要繼續(xù)往下搜索

? # 只有后面的正則表達式?jīng)]有匹配到時,這一條才會采用這一條

? [ config C ]

}

location ~ /documents/Abc {

? # 匹配任何以 /documents/Abc 開頭的地址,匹配符合以后,還要繼續(xù)往下搜索

? # 只有后面的正則表達式?jīng)]有匹配到時,這一條才會采用這一條

? [ config CC ]

}

location ^~ /images/ {

? # 匹配任何以 /images/ 開頭的地址,匹配符合以后,停止往下搜索正則,采用這一條

? [ config D ]

}

location ~* .(gif|jpg|jpeg)$ {

? # 匹配所有以 gif,jpg或jpeg 結(jié)尾的請求

? # 然而,所有請求 /images/ 下的圖片會被 config D 處理,因為 ^~ 到達不了這一條正則

? [ config E ]

}

location /images/ {

? # 字符匹配到 /images/,繼續(xù)往下,會發(fā)現(xiàn) ^~ 存在

? [ config F ]

}

location /images/abc {

? # 最長字符匹配到 /images/abc,繼續(xù)往下,會發(fā)現(xiàn) ^~ 存在

? # F與G的放置順序是沒有關(guān)系的

? [ config G ]

}

location ~ /images/abc/ {

? # 只有去掉 config D 才有效:先最長匹配 config G 開頭的地址,繼續(xù)往下搜索,匹配到這一條正則,采用

? ? [ config H ]

}

正則查找優(yōu)先級從高到低依次如下:

“ = ” 開頭表示精確匹配,如 A 中只匹配根目錄結(jié)尾的請求,后面不能帶任何字符串。

“ ^~ ” 開頭表示uri以某個常規(guī)字符串開頭,不是正則匹配。

“ ~ ” 開頭表示區(qū)分大小寫的正則匹配。

“ ~* ”開頭表示不區(qū)分大小寫的正則匹配。

“ / ” 通用匹配, 如果沒有其它匹配,任何請求都會匹配到。

負載均衡配置

Nginx 的負載均衡需要用到 upstream模塊,可通過以下配置來實現(xiàn):

upstream test-upstream {

? ? ip_hash; # 使用 ip_hash 算法分配

? ? server 192.168.1.1; # 要分配的 ip

? ? server 192.168.1.2;

}

server {

? ? location / {

? ? ? ? proxy_pass http://test-upstream;

? ? }

}

上面的例子定義了一個 test-upstream的負載均衡配置,通過 proxy_pass反向代理指令將請求轉(zhuǎn)發(fā)給該模塊進行分配處理。

參考文章:

一篇文章搞懂Nginx是什么,能干什么

大圖詳解負載神器 LVS、Nginx及HAProxy工作原理

深入 Nginx 之配置篇

Nginx為什么高效?一文搞明白Nginx核心原理

nginx、swoole高并發(fā)原理初探

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容