Nginx 學習總結

2020-08-11 18:55:44

以下所總結僅是學習記錄,如有不對的部分,還請及時指出,十分感謝

參考文件目錄都在末尾寫出了作者的鏈接,有興趣的可以直接點選

文章有點長,建議收藏後檢視

Nginx、WSGI、 uWSGI、 uwsgi 簡介

  • Nginx 簡介
  • Nginx 和 uWSGI 的關係
  • Nginx 與 Apache 的異同
  • Nginx的優勢
  • Nginx的模組與工作原理
  • Nginx 組態檔結構
  • Nginx 組態檔詳解
  • Nginx 代理
  • Nginx 負載均衡

Nginx、WSGI、 uWSGI、 uwsgi 簡介

當我們部署完一個應用程式,瀏覽網頁時具體的過程是怎樣的呢?首先我們得有一個 Web 伺服器來處理 HTTP 協定的內容,Web 伺服器獲得用戶端的請求,交給應用程式,應用程式處理完,返回給 Web 伺服器,這時 Web 伺服器再返回給用戶端。Web 伺服器與應用程式之間顯然要進行互動,這時就出現了很多 Web 伺服器與應用程式之間互動的規範,最早出現的是 CGI,後來又出現了改進 CGI 效能的FasgCGI,Java 專用的 Servlet 規範,Python 專用的 WSGI 規範等等。有了統一標準,程式的可移植性就大大提高了。這裏我們只介紹 WSGI。

WSGI 全稱是 Web Server Gateway Interface,也就是 Web 伺服器閘道器介面,它是 Python 語言定義出來的 Web 伺服器和 Web 應用程式之間的簡單而通用的介面,基於現存的 CGI 標準設計,後來在很多其他語言中也出現了類似的介面。 總的來說,WSGI 可以分爲伺服器和應用程式兩個部分,實際上可以將 WSGI 理解爲伺服器與應用程式之間的一座橋,橋的一邊是伺服器,另一邊是應用程式。

按照 web 元件分類,WSGI 內部可以分爲三類,web 應用程式,web 伺服器,web 中介軟體。應用程式端的部分通過Python 語言的各種 Web 框架實現,比如 Flask,Django這些,有了框架,開發者就不需要處理 WSGI,框架會幫忙解決這些,開發者只需處理 HTTP 請求和響應,web 伺服器的部分就要複雜一點,可以通過 uWSGI 實現,也可以用最常見的 Web 伺服器,比如 Apache、Nginx,但這些 Web 伺服器沒有內建 WSGI 的實現,是通過擴充套件完成的。如 Apache,通過擴充套件模組 mod_wsgi 來支援WSGI,Nginx可以通過代理的方式,將請求封裝好,交給應用伺服器,比如 uWSGI。uWSGI 可以完成 WSGI 的伺服器端,進程管理以及對應用的呼叫。WSGI 中介軟體的部分可以這樣理解:我們把 WSGI 看做橋,這個橋有兩個橋墩,一個是應用程式端,另一個是伺服器端,那麼橋面就是 WSGI 中介軟體,中介軟體同時具備伺服器、應用程式端兩個角色,當然也需要同時遵守 WSGI 伺服器和 WSGI 應用程式兩邊的限制和需要。更詳細的內容可以看PEP-333 中介軟體的描述

Flask 依賴的 Werkzeug 就是一個 WSGI 工具包,官方文件的定義是 Werkzeug 是爲 Python 設計的 HTTP和 WSGI 實用程式庫。我們需要注意的是,Flask 自帶的 Werkzeug 是用來開發的,並不能用於生產環境,Flask 是 Web 框架,而 Werkzeug 不是 Web框架,不是 Web 伺服器,它只是一個 WSGI 工具包,它在 Flask 的作用是作爲 Web 框架的底層庫,它方便了我們的開發。

我們將 uwsgi 和 uWSGI 放在一起講解。uWSGI 是一個 Web 伺服器程式,WSGI,上面已經談到,是一種協定,uwsgi 也是一種協定,uWSGI 實現了 uwsgi、WSGI、http 等協定。 uwsgi 的介紹可以看這裏,uwsgi 是 uWSGI 使用的一個自有的協定,它用4個位元組來定義傳輸數據型別描述。儘管都是協定,uwsgi 和 WSGI 並沒有聯繫,我們需要區分這兩個詞。

Nginx 簡介

Nginx 是高效的 Web 伺服器和反向代理伺服器,可以用作負載均衡(當有 n 個使用者存取伺服器時,可以實現分流,分擔伺服器的壓力),與 Apache 相比,Nginx 支援高併發,可以支援百萬級的 TCP 連線,十萬級別的併發連線,部署簡單,記憶體消耗少,成本低,但 Nginx 的模組沒有 Apache 豐富。Nginx 支援 uWSGI 的 uwsgi 協定,因此我們可以將 Nginx 與 uWSGI 結合起來,Nginx 通過 uwsgi_pass 將動態內容交給 uWSGI 處理。

Nginx 和 uWSGI 的關係

從上面的講解中,我們知道,uWSGI 可以起到 Web 伺服器的作用,那麼爲什麼有了 uWSGI 還需要 Nginx 呢?

最普遍的說法是 Nginx 對於處理靜態檔案更有優勢,效能更好。其實如果是小網站,沒有靜態檔案需要處理,只用 uWSGI 也是可以的,但加上 Nginx 這一層,優勢可以很具體:

  1. 對於運維來說比較方便,如果伺服器被某個 IP 攻擊,在 Nginx 組態檔黑名單中新增這個 IP 即可,如果只用 uWSGI,那麼就需要在程式碼中修改了。另一方面,Nginx 是身經百戰的 Web 伺服器了,在表現上 uWSGI 顯得更專業,比如說 uWSGI 在早期版本裡是不支援 https 的,可以說 Nginx 更安全。
  2. Nginx 的特點是能夠做負載均衡和 HTTP 快取,如果不止一臺伺服器,Nginx 基本就是必選項了,通過 Nginx,將資源可以分配給不同的伺服器節點,只有一臺伺服器,也能很好地提高效能,因爲 Nginx 可以通過 headers 的Expires or E-Tag,gzip 壓縮等方式很好地處理靜態資源,畢竟是 C 語言寫的,呼叫的是 native 的函數,針對 I/O做了優化,對於動態資源來說,Nginx 還可以實現快取的功能,配合 CDN 優化(這是 uWSGI 做不到的)。Nginx 支援epoll/kqueue 等高效網路庫,能夠很好地處理高併發短連線請求,效能比 uWSGI 不知道高到哪裏去了。
  3. 如果伺服器主機上執行了PHP,Python 等語言寫的多個應用,都需要監聽80埠,這時候 Nginx 就是必選項了。因爲我們需要一個轉發的服務。
WSGI:全稱是Web Server Gateway Interface,WSGI不是伺服器,python模組,框架,API或者任何軟體,只是一種規範,描述web server如何與web application通訊的規範。要實現WSGI協定,必須同時實現web server和web application,當前執行在WSGI協定之上的web框架有Bottle, Flask, Django。
uwsgi:與WSGI一樣是一種通訊協定,是uWSGI伺服器的獨佔協定,用於定義傳輸資訊的型別(type of information)
uWSGI:是一個web伺服器,實現了WSGI協定、uwsgi協定、http協定等。
WSGI協定主要包括server和application兩部分:
WSGI server負責從用戶端接收請求,將request轉發給application,將application返回的response返回給用戶端;
WSGI application接收由server轉發的request,處理請求,並將處理結果返回給server。application中可以包括多個棧式的中介軟體(middlewares),這些中介軟體需要同時實現server與application,因此可以在WSGI伺服器與WSGI應用之間起調節作用:對伺服器來說,中介軟體扮演應用程式,對應用程式來說,中介軟體扮演伺服器。
WSGI協定其實是定義了一種server與application解耦的規範,即可以有多個實現WSGI server的伺服器,也可以有多個實現WSGI application的框架,那麼就可以選擇任意的server和application組合實現自己的web應用。例如uWSGI和Gunicorn都是實現了WSGI server協定的伺服器,Django,Flask是實現了WSGI application協定的web框架,可以根據專案實際情況搭配使用

Nginx 與 Apache 的異同

Nginx和Apache一樣,都是一個HTTP伺服器軟體,功能實現上都採用模組化結構設計,都支援通用的語言介面,如PHP、Perl、Python等,同時還支援正、反向代理,虛擬主機,URL重寫,壓縮傳輸,SSL加密傳輸等。它們之間最大的差別是Apache處理速度很慢,且佔用很多記憶體資源,而Nginx卻恰恰相反;在功能實現上,Apache的所有模組都支援動、靜態編譯,而Nginx模組都是靜態編譯的,同時,Apache對Fcgi支援不好,而Nginx對Fcgi的支援非常的好;最重要的是,在處理連線方式上,Nginx支援epoll,而Apache卻不支援;在大小上,Nginx安裝包僅僅有幾百K,和Nginx比起來Apache絕對是龐然大物。在瞭解了Nginx和Apache之間的異同點後基本知道了Nginx作爲HTTP伺服器的優勢所在。

Nginx的優勢

通過上面的簡單介紹,Nginx作爲HTTP伺服器的優勢是顯而易見的,它有很多其它Web伺服器無法比擬的效能和優勢:
作爲Web伺服器,nginx處理靜態檔案、索引檔案以及自動索引效率非常高。
作爲代理伺服器,Nginx可以實現無快取的反向代理加速,提高網站執行速度。
作爲負載均衡伺服器,Nginx既可以在內部直接支援Rails和PHP,也可以支援HTTP代理伺服器,對外進行服務。同時支援簡單的容錯和利用演算法進行負載均衡。
在效能方面,Nginx是專門爲效能優化而開發的,在實現上非常注重效率。它採用內核Poll模型,可以支援更多的併發連線,最大可以支援對50 000個併發連線數的響應,而且佔用很低的記憶體資源。
在穩定性方面,Nginx採取了分階段資源分配技術,使得對CPU與記憶體的佔用率非常低。Nginx官方表示Nginx保持10 000個沒有活動的連線,這些連線只佔2.5M記憶體,因此,類似DOS這樣的攻擊對Nginx來說基本上是沒有任何作用的。
在高可用性方面,Nginx支援熱部署,啓動速度特別迅速,因此可以在不間斷服務的情況下,對軟體版本或者設定進行升級,即使執行數月也無需重新啓動,幾乎可以做到7×24小時的不間斷執行。

Nginx的模組與工作原理

Nginx由內核和模組組成,其中,內核的設計非常微小和簡潔,完成的工作也非常簡單,僅僅通過查詢組態檔將用戶端請求對映到一個location block(location是Nginx設定中的一個指令,用於URL匹配),而在這個location中所設定的每個指令將會啓動不同的模組去完成相應的工作。
Nginx的模組從結構上分爲核心模組、基礎模組和第三方模組, HTTP模組、EVENT模組和MAIL模組等屬於核心模組,HTTP Access模組、HTTP FastCGI模組、HTTP Proxy模組和HTTP Rewrite模組屬於基本模組,而HTTP Upstream Request Hash模組、Notice模組和HTTP Access Key模組屬於第三方模組,使用者根據自己的需要開發的模組都屬於第三方模組。正是有了這麼多模組的支撐,Nginx的功能纔會如此強大。
Nginx的模組從功能上分爲三類,分別是:
(1) Handlers(處理器模組)。此類模組直接處理請求,並進行輸出內容和修改headers資訊等操作。handlers處理器模組一般只能有一個。
(2) Filters (過濾器模組)。此類模組主要對其他處理器模組輸出的內容進行修改操作,最後由Nginx輸出。
(3) Proxies (代理類模組)。就是Nginx的HTTP Upstream之類的模組,這些模組主要與後端一些服務比如fastcgi等操作互動,實現服務代理和負載均衡等功能。
下圖展示了Nginx的模組下一次常規的HTTP請求和響應的過程。

在这里插入图片描述

在工作方式上,Nginx分爲單工作進程和多工作進程兩種模式。在單工作進程模式下,除主進程外,還有一個工作進程,工作進程是單執行緒的;在多工作進程模式下,每個工作進程包含多個執行緒。Nginx預設爲單工作進程模式。
Nginx的模組直接被編譯進Nginx,因此屬於靜態編譯方式。啓動Nginx後,Nginx的模組被自動載入,不像在Apache一樣,首先將模組編譯爲一個so檔案,然後在組態檔中指定是否進行載入。在解析組態檔時,Nginx的每個模組都有可能去處理某個請求,但是同一個處理請求只能由一個模組來完成。

Nginx 組態檔結構

Nginx的組態檔是一個純文字檔案,它一般位於Nginx安裝目錄的conf目錄下,整個組態檔是以block的形式組織的。每個block一般以一個大括號「{}」來表示,block可以分爲幾個層次,整個組態檔中Main指令位於最高層,在Main層下面 下麪可以有Events、HTTP等層級,而在HTTP層中又包含有Server層,即server block,server block中又可分爲location層,並且一個server block中可以包含多個location block。
一個完整的組態檔結構如下圖所示。

在这里插入图片描述

Nginx 組態檔詳解

Nginx安裝完畢後,會產生相應的安裝目錄,一般爲/etc/nginx/conf,其中nginx.conf爲Nginx的主組態檔。這裏重點介紹下nginx.conf這個組態檔。

Nginx組態檔主要分成四部分:main(全域性設定)、server(主機設定)、upstream(負載均衡伺服器設定)和 location(URL匹配特定位置的設定)。main部分設定的指令將影響其他所有設定;server部分的指令主要用於指定主機和埠;upstream指令主要用於負載均衡,設定一系列的後端伺服器;location部分用於匹配網頁位置。這四者之間的關係式:server繼承main,location繼承server,upstream既不會繼承其他設定也不會被繼承。
在這四個部分當中,每個部分都包含若幹指令,這些指令主要包含Nginx的主模組指令、事件模組指令、HTTP核心模組指令,同時每個部分還可以使用其他HTTP模組指令,例如Http SSL模組、HttpGzip Static模組和Http Addition模組等。
下面 下麪通過一個Nginx設定範例,詳細介紹下nginx.conf每個指令的含義。爲了能更清楚地瞭解Nginx的結構和每個設定選項的含義,這裏按照功能點將Nginx組態檔分爲7個部分逐次講解,下面 下麪就圍繞這7個部分進行介紹。

Nginx的全域性設定

下面 下麪這段內容是對Nginx的全域性屬性設定,程式碼如下:

 user  nobody nobody;
 worker_processes  4;
 error_log  logs/error.log  notice;
 pid        logs/nginx.pid;
 worker_rlimit_nofile 65535;
 events{
  use epoll;
  worker_connections      65536;
       }

對上面這段程式碼中每個設定選項的含義解釋如下:

對上面這段程式碼中每個設定選項的含義解釋如下:

  • user是個主模組指令,指定Nginx Worker進程執行使用者以及使用者組,預設由nobody賬號執行。

  • worker_processes是個主模組指令,指定了Nginx要開啓的進程數。每個Nginx進程平均耗費10M~12M記憶體。根據經驗,一般指定一個進程足夠了,如果是多核CPU,建議指定和CPU的數量一樣的進程數即可。

  • error_log是個主模組指令,用來定義全域性錯誤日誌檔案。日誌輸出級別有debug、info、notice、warn、error、crit可供選擇,其中,debug輸出日誌最爲最詳細,而crit輸出日誌最少。

  • pid是個主模組指令,用來指定進程id的儲存檔案位置。

  • worker_rlimit_nofile用於指定一個nginx進程可以開啓的最多檔案描述符數目,這裏是65535,需要使用命令「ulimit -n 65535」來設定。

  • events指令是設定Nginx的工作模式及連線數上限。

    events{
    use epoll;
    worker_connections      65536;
    }
    

    use是個事件模組指令,用來指定Nginx的工作模式。Nginx支援的工作模式有select、poll、kqueue、epoll、rtsig和/dev/poll。其中select和poll都是標準的工作模式,kqueue和epoll是高效的工作模式,不同的是epoll用在Linux平臺上,而kqueue用在BSD系統中。對於Linux系統,epoll工作模式是首選。
    worker_connections也是個事件模組指令,用於定義Nginx每個進程的最大連線數,預設是1024.最大用戶端連線數由worker_processes和worker_connections決定,即Max_client=worker_processes*worker_connections,在作爲反向代理時,max_clients變爲:max_clients = worker_processes * worker_connections/4。
    進程的最大連線數受Linux系統進程的最大開啓檔案數限制,在執行操作系統命令「ulimit -n 65536」後worker_connections的設定才能 纔能生效。

HTTP伺服器設定

接下來開始進行HTTP伺服器設定。
下面 下麪這段內容是Nginx對HTTP伺服器相關屬性的設定,程式碼如下:

http{
include      conf/mime.types;
default_type  application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] '
 '"$request" $status $bytes_sent '
 '"$http_referer" "$http_user_agent" '
 '"$gzip_ratio"';
 log_format download '$remote_addr - $remote_user [$time_local] '
 '"$request" $status $bytes_sent '
 '"$http_referer" "$http_user_agent" '
 '"$http_range" "$sent_http_content_range"';
client_max_body_size  20m;
client_header_buffer_size    32K;
large_client_header_buffers  4 32k;
Sendfile  on;
tcp_nopush     on;
tcp_nodelay    on;
keepalive_timeout 60;
client_header_timeout  10;
client_body_timeout    10;
send_timeout          10;

下面 下麪詳細介紹下這段程式碼中每個設定選項的含義:

  • include是個主模組指令,實現對組態檔所包含的檔案的設定,可以減少主組態檔的複雜度。類似於Apache中的include方法。
  • default_type屬於HTTP核心模組指令,這裏設定預設型別爲二進制流,也就是當檔案型別未定義時使用這種方式,例如在沒有設定PHP環境時,Nginx是不予解析的,此時,用瀏覽器存取PHP檔案就會出現下載視窗。
    下面 下麪的程式碼實現對日誌格式的設定。
    log_format main '$remote_addr - remoteuser[remote_user [time_local] ’
    ‘"$request" $status KaTeX parse error: Double superscript at position 14: bytes_sent ' '̲"http_referer" 「KaTeX parse error: Double superscript at position 20: …_user_agent" ' '̲"gzip_ratio」’;
    log_format download '$remote_addr - remoteuser[remote_user [time_local] ’
    ‘"$request" $status KaTeX parse error: Double superscript at position 14: bytes_sent ' '̲"http_referer" 「KaTeX parse error: Double superscript at position 20: …_user_agent" ' '̲"http_range」 「$sent_http_content_range」’;
  • log_format是Nginx的HttpLog模組指令,用於指定Nginx日誌的輸出格式。main爲此日誌輸出格式的名稱,可以在下面 下麪的access_log指令中參照。
  • client_max_body_size用來設定允許用戶端請求的最大的單個檔案位元組數。
  • client_header_buffer_size用於指定來自用戶端請求頭的headerbuffer大小。對於大多數請求,1K的緩衝區大小已經足夠,如果自定義了訊息頭或有更大的Cookie,可以增加緩衝區大小。這裏設定爲32K。
  • large_client_header_buffers用來指定用戶端請求中較大的訊息頭的快取最大數量和大小, 「4」爲個數,「128K」爲大小,最大快取量爲4個128K。
  • sendfile參數用於開啓高效檔案傳輸模式。將tcp_nopush和tcp_nodelay兩個指令設定爲on用於防止網路阻塞。
  • keepalive_timeout設定用戶端連線保持活動的超時時間。在超過這個時間之後,伺服器會關閉該連線。
  • client_header_timeout設定用戶端請求頭讀取超時時間。如果超過這個時間,用戶端還沒有發送任何數據,Nginx將返回「Request time out(408)」錯誤。
  • client_body_timeout設定用戶端請求主體讀取超時時間。如果超過這個時間,用戶端還沒有發送任何數據,Nginx將返回「Request time out(408)」錯誤,預設值是60。
  • send_timeout指定響應用戶端的超時時間。這個超時僅限於兩個連線活動之間的時間,如果超過這個時間,用戶端沒有任何活動,Nginx將會關閉連線。

HttpGzip模組設定

下面 下麪設定Nginx的HttpGzip模組。這個模組支援線上實時壓縮輸出數據流。要檢視是否安裝了此模組,需要使用下面 下麪的命令:

[root@localhost conf]# /etc/nginx/sbin/nginx  -V
nginx version: nginx/0.7.65

configure arguments: --with-http_stub_status_module --with-http_gzip_static_module --prefix=/etc/nginx
通過/etc/nginx/sbin/nginx  -V命令可以檢視安裝Nginx時的編譯選項,由輸出可知,我們已經安裝了HttpGzip模組。

下面 下麪是HttpGzip模組在Nginx設定中的相關屬性設定:

gzip  on;
gzip_min_length  1k;
gzip_buffers     4  16k;
gzip_http_version  1.1;
gzip_comp_level  2;
gzip_types  text/plain application/x-javascript text/css application/xml;
gzip_vary  on;
  • gzip用於設定開啓或者關閉gzip模組,「gzip on」表示開啓GZIP壓縮,實時壓縮輸出數據流。
  • gzip_min_length設定允許壓縮的頁面最小位元組數,頁面位元組數從header頭的Content-Length中獲取。預設值是0,不管頁面多大都進行壓縮。建議設定成大於1K的位元組數,小於1K可能會越壓越大。
  • gzip_buffers表示申請4個單位爲16K的記憶體作爲壓縮結果流快取,預設值是申請與原始數據大小相同的記憶體空間來儲存gzip壓縮結果。
  • gzip_http_version用於設定識別HTTP協定版本,預設是1.1,目前大部分瀏覽器已經支援GZIP解壓,使用預設即可。
  • gzip_comp_level用來指定GZIP壓縮比,1 壓縮比最小,處理速度最快;9 壓縮比最大,傳輸速度快,但處理最慢,也比較消耗cpu資源。
  • gzip_types用來指定壓縮的型別,無論是否指定,「text/html」型別總是會被壓縮的。
  • gzip_vary選項可以讓前端的快取伺服器快取經過GZIP壓縮的頁面,例如用Squid快取經過Nginx壓縮的數據

負載均衡設定

下面 下麪設定負載均衡的伺服器列表:

upstream ixdba.net{
ip_hash;
server 192.168.12.133:80;
server 192.168.12.134:80  down;
server 192.168.12.135:8009  max_fails=3  fail_timeout=20s;
server 192.168.12.136:8080;
}

upstream是Nginx的HTTP Upstream模組,這個模組通過一個簡單的排程演算法來實現用戶端IP到後端伺服器的負載均衡。在上面的設定中,通過upstream指令指定了一個負載均衡器的名稱ixdba.net。這個名稱可以任意指定,在後面需要的地方直接呼叫即可。

  • 在HTTP Upstream模組中,可以通過server指令指定後端伺服器的IP地址和埠,同時還可以設定每個後端伺服器在負載均衡排程中的狀態。常用的狀態有:
    down,表示當前的server暫時不參與負載均衡。
  • backup,預留的備份機器。當其他所有的非backup機器出現故障或者忙的時候,纔會請求backup機器,因此這臺機器的壓力最輕。
  • max_fails,允許請求失敗的次數,預設爲1。當超過最大次數時,返回proxy_next_upstream 模組定義的錯誤。
  • fail_timeout,在經歷了max_fails次失敗後,暫停服務的時間。max_fails可以和fail_timeout一起使用。
  • 注意 當負載排程演算法爲ip_hash時,後端伺服器在負載均衡排程中的狀態不能是weight和backup。

server虛擬主機設定

下面 下麪介紹對虛擬主機的設定。建議將對虛擬主機進行設定的內容寫進另外一個檔案,然後通過include指令包含進來,這樣更便於維護和管理:

server{
listen          80;
server_name    192.168.12.188  www.ixdba.net;
index index.html index.htm index.jsp;
root  /web/wwwroot/www.ixdba.net
charset gb2312;
  • server標誌定義虛擬主機開始,listen用於指定虛擬主機的伺服器端口,server_name用來指定IP地址或者域名,多個域名之間用空格分開。Index用於設定存取的預設首頁地址,root指令用於指定虛擬主機的網頁根目錄,這個目錄可以是相對路徑,也可以是絕對路徑。Charset用於設定網頁的預設編碼格式。
  • access_log logs/www.ixdba.net.access.log main;
  • access_log用來指定此虛擬主機的存取日誌存放路徑,最後的main用於指定存取日誌的輸出格式。

URL匹配設定

URL地址匹配是進行Nginx設定中最靈活的部分。 location支援正則表達式匹配,也支援條件判斷匹配,使用者可以通過location指令實現Nginx對動、靜態網頁進行過濾處理。
以下這段設定是通過location指令來對網頁URL進行分析處理,所有擴充套件名以.gif、.jpg、.jpeg、.png、.bmp、.swf結尾的靜態檔案都交給nginx處理,而expires用來指定靜態檔案的過期時間,這裏是30天

location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$  {
                root    /web/wwwroot/www.ixdba.net;
               expires 30d;
        }

以下這段設定是將upload和html下的所有檔案都交給nginx來處理,當然,upload和html目錄包含在/web/wwwroot/www.ixdba.net目錄中。

        location ~ ^/(upload|html)/  {
                root    /web/wwwroot/www.ixdba.net;
                expires 30d;
        }

在最後這段設定中,location是對此虛擬主機下動態網頁的過濾處理,也就是將所有以.jsp爲後綴的檔案都交給本機的8080埠處理

location ~ .*.jsp$ {
    index index.jsp;      
    proxy_pass http://localhost:8080;
}

StubStatus模組設定

StubStatus模組能夠獲取Nginx自上次啓動以來的工作狀態,此模組非核心模組,需要在Nginx編譯安裝時手工指定才能 纔能使用此功能。
以下指令實指定啓用獲取Nginx工作狀態的功能

        location /NginxStatus {
                        stub_status      on;
access_log              logs/NginxStatus.log;
                        auth_basic              "NginxStatus";
      auth_basic_user_file    ../htpasswd;
        }

stub_status設定爲「on」表示啓用StubStatus的工作狀態統計功能。access_log 用來指定StubStatus模組的存取日誌檔案。auth_basic是Nginx的一種認證機制 機製。auth_basic_user_file用來指定認證的密碼檔案,由於Nginx的auth_basic認證採用的是與Apache相容的密碼檔案,因此需要用Apache的htpasswd命令來生成密碼檔案,例如要新增一個webadmin使用者,可以使用下面 下麪方式生成密碼檔案:
/usr/local/apache/bin/htpasswd -c /opt/nginx/conf/htpasswd webadmin
會得到以下提示資訊:
New password:
輸入密碼之後,系統會要求再次輸入密碼。確認之後新增使用者成功。

要檢視Nginx的執行狀態,可以輸入http://ip/ NginxStatus,然後輸入剛剛建立的使用者名稱和密碼就可以看到如下資訊:

Active connections: 1
server accepts handled requests
 393411 393411 393799
Reading: 0 Writing: 1 Waiting: 0

Active connections表示當前活躍的連線數,第三行的三個數位表示 Nginx當前總共處理了393411個連線, 成功建立393411次握手, 總共處理了393799個請求。最後一行的Reading表示Nginx讀取到用戶端Header資訊數, Writing表示Nginx返回給用戶端的Header資訊數,「Waiting」表示Nginx已經處理完,正在等候下一次請求指令時的駐留連線數。

在最後這段設定中,設定了虛擬主機的錯誤資訊返回頁面,通過error_page指令可以定製各種錯誤資訊的返回頁面。在預設情況下,Nginx會在主目錄的html目錄中查詢指定的返回頁面,特別需要注意的是,這些錯誤資訊的返回頁面大小一定要超過512K,否者會被ie瀏覽器替換爲ie預設的錯誤頁面。

    error_page 404       /404.html;
    error_page  500 502 503 504 /50x.html;
    location = /50x.html {
      root  html;
    }
}
}

Nginx 代理

Nginx是一款自由的、開源的、高效能的HTTP伺服器和反向代理伺服器;同時也是一個IMAP、POP3、SMTP代理伺服器;Nginx可以作爲一個HTTP伺服器進行網站的發佈處理,另外Nginx可以作爲反向代理進行負載均衡的實現。

關於代理

說到代理,首先我們要明確一個概念,所謂代理就是一個代表、一個渠道;

此時就涉及到兩個角色,一個是被代理角色,一個是目標角色,被代理角色通過這個代理存取目標角色完成一些任務的過程稱爲代理操作過程;如同生活中的專賣店~客人到adidas專賣店買了一雙鞋,這個專賣店就是代理,被代理角色就是adidas廠家,目標角色就是使用者。

正向代理

說反向代理之前,我們先看看正向代理,正向代理也是大家最常接觸的到的代理模式,我們會從兩個方面來說關於正向代理的處理模式,分別從軟體方面和生活方面來解釋一下什麼叫正向代理。

在如今的網路環境下,我們如果由於技術需要要去存取國外的某些網站,此時你會發現位於國外的某網站我們通過瀏覽器是沒有辦法存取的,此時大家可能都會用一個代理進行存取,代理的方式主要是找到一個可以存取國外網站的代理伺服器,我們將請求發送給代理伺服器,代理伺服器去存取國外的網站,然後將存取到的數據傳遞給我們!

上述這樣的代理模式稱爲正向代理,正向代理最大的特點是用戶端非常明確要存取的伺服器地址;伺服器只清楚請求來自哪個代理伺服器,而不清楚來自哪個具體的用戶端;正向代理模式遮蔽或者隱藏了真實用戶端資訊。

總結來說:正向代理,「它代理的是用戶端」,是一個位於用戶端和原始伺服器(origin server)之間的伺服器,爲了從原始伺服器取得內容,用戶端向代理髮送一個請求並指定目標(原始伺服器),然後代理向原始伺服器轉交請求並將獲得的內容返回給用戶端。用戶端必須要進行一些特別的設定才能 纔能使用正向代理。

正向代理的用途:
(1)存取原來無法存取的資源,如Google
(2) 可以做快取,加速存取資源
(3)對用戶端存取授權,上網進行認證
(4)代理可以記錄使用者存取記錄(上網行爲管理),對外隱藏使用者資訊

反向代理

明白了什麼是正向代理,我們繼續看關於反向代理的處理方式,舉例如我大天朝的某寶網站,每天同時連線到網站的存取人數已經爆表,單個伺服器遠遠不能滿足人民日益增長的購買慾望了,此時就出現了一個大家耳熟能詳的名詞:分佈式部署;也就是通過部署多臺伺服器來解決存取人數限制的問題;某寶網站中大部分功能也是直接使用Nginx進行反向代理實現的,並且通過封裝Nginx和其他的元件之後起了個高大上的名字:Tengine,有興趣的童鞋可以存取Tengine的官網檢視具體的資訊:http://tengine.taobao.org/。

多個用戶端給伺服器發送的請求,Nginx伺服器接收到之後,按照一定的規則分發給了後端的業務處理伺服器進行處理了。此時~請求的來源也就是用戶端是明確的,但是請求具體由哪臺伺服器處理的並不明確了,Nginx扮演的就是一個反向代理角色。

用戶端是無感知代理的存在的,反向代理對外都是透明的,存取者並不知道自己存取的是一個代理。因爲用戶端不需要任何設定就可以存取。

反向代理,「它代理的是伺服器端」,主要用於伺服器叢集分佈式部署的情況下,反向代理隱藏了伺服器的資訊。

反向代理的作用:
(1)保證內網的安全,通常將反向代理作爲公網存取地址,Web伺服器是內網
(2)負載均衡,通過反向代理伺服器來優化網站的負載

專案場景

一般在專案中正向代理和反向代理都是同時出現的,正向代理代理用戶端的請求去存取目標伺服器,目標伺服器是一個反向代理伺服器,反向代理了多臺真實的業務處理伺服器:

多個用戶端請求		----->		正向代理		----->		反向代理		----->		多個伺服器

在正向代理中,Proxy和Client同屬於一個LAN(圖中方框內),隱藏了用戶端資訊;

在反向代理中,Proxy和Server同屬於一個LAN(圖中方框內),隱藏了伺服器端資訊;

實際上,Proxy在兩種代理中做的事情都是替伺服器代爲收發請求和響應,不過從結構上看正好左右互換了一下,所以把後出現的那種代理方式稱爲反向代理了。

Nginx 負載均衡

負載均衡

我們已經明確了所謂代理伺服器的概念,那麼接下來,Nginx扮演了反向代理伺服器的角色,它是以依據什麼樣的規則進行請求分發的呢?不同的專案應用場景,分發的規則是否可以控制呢?

這裏提到的用戶端發送的、Nginx反向代理伺服器接收到的請求數量,就是我們說的負載量。

請求數量按照一定的規則進行分發到不同的伺服器處理的規則,就是一種均衡規則。

所以~將伺服器接收到的請求按照規則分發的過程,稱爲負載均衡。

負載均衡在實際專案操作過程中,有硬體負載均衡和軟體負載均衡兩種,硬體負載均衡也稱爲硬負載,如F5負載均衡,相對造價昂貴成本較高,但是數據的穩定性安全性等等有非常好的保障,如中國移動中國聯通這樣的公司纔會選擇硬負載進行操作;更多的公司考慮到成本原因,會選擇使用軟體負載均衡,軟體負載均衡是利用現有的技術結合主機硬體實現的一種訊息佇列分發機制 機製。

Nginx支援的負載均衡排程演算法方式如下:

  1. weight輪詢(預設):接收到的請求按照順序逐一分配到不同的後端伺服器,即使在使用過程中,某一臺後端伺服器宕機,Nginx會自動將該伺服器剔除出佇列,請求受理情況不會受到任何影響。 這種方式下,可以給不同的後端伺服器設定一個權重值(weight),用於調整不同的伺服器上請求的分配率;權重數據越大,被分配到請求的機率越大;該權重值,主要是針對實際工作環境中不同的後端伺服器硬體設定進行調整的。
  2. ip_hash:每個請求按照發起用戶端的ip的hash結果進行匹配,這樣的演算法下一個固定ip地址的用戶端總會存取到同一個後端伺服器,這也在一定程度上解決了叢集部署環境下session共用的問題。
  3. fair:智慧調整排程演算法,動態的根據後端伺服器的請求處理到響應的時間進行均衡分配,響應時間短處理效率高的伺服器分配到請求的概率高,響應時間長處理效率低的伺服器分配到的請求少;結合了前兩者的優點的一種排程演算法。但是需要注意的是Nginx預設不支援fair演算法,如果要使用這種排程演算法,請安裝upstream_fair模組。
  4. url_hash:按照存取的url的hash結果分配請求,每個請求的url會指向後端固定的某個伺服器,可以在Nginx作爲靜態伺服器的情況下提高快取效率。同樣要注意Nginx預設不支援這種排程演算法,要使用的話需要安裝Nginx的hash軟體包。

參考:

http://blog.360converter.com/archives/1005

https://www.cnblogs.com/fengchong/p/10230266.html

https://blog.csdn.net/a3192048/article/details/89737337

https://blog.51cto.com/ixdba/790611

https://blog.51cto.com/ixdba/778469

https://blog.51cto.com/ixdba/778462

https://blog.51cto.com/ixdba/793571

https://blog.51cto.com/ixdba/798913

https://blog.51cto.com/ixdba/803475