說明本篇文章大部分參考此人的博文:http://freeloda.blog.51cto.com/2033581/1285722,建議若想繼續深入學習nginx時最好先看下此人所寫的文章,總結的很詳細,然後在找相關的書籍和查閱官方文檔學習。
一、NGINX介紹
1 簡介
傳統上基於進程或線程模型架構的web服務通過每進程或每線程處理併發連接請求,這勢必會在網絡和I/O操作時產生阻塞,其另一個必然結果則是對內存或CPU的利用率低下。生成一個新的進程/線程需要事先備好其運行時環境,這包括爲其分配堆內存和棧內存,以及爲其創建新的執行上下文等。這些操作都需要佔用CPU,而且過多的進程/線程還會帶來線程抖動或頻繁的上下文切換,系統性能也會由此進一步下降。另一種高性能web服務器/web服務器反向代理:Nginx(Engine X),nginx的主要着眼點就是其高性能以及對物理計算資源的高密度利用,因此其採用了不同的架構模型。受啓發於多種操作系統設計中基於“事件”的高級處理機制,nginx採用了模塊化、事件驅動、異步、單線程及非阻塞的架構,並大量採用了多路複用及事件通知機制。在nginx中,連接請求由爲數不多的幾個僅包含一個線程的進程worker以高效的迴環(run-loop)機制進行處理,而每個worker可以並行處理數千個的併發連接及請求。
2 Nginx 工作原理
Nginx會按需同時運行多個進程:一個主進程(master)和幾個工作進程(worker),配置了緩存時還會有緩存加載器進程(cache loader)和緩存管理器進程(cache manager)等。所有進程均是僅含有一個線程,並主要通過“共享內存”的機制實現進程間通信。主進程以root用戶身份運行,而worker、cache loader和cache manager均應以非特權用戶身份運行。
主進程主要完成如下工作:
讀取並驗正配置信息;
創建、綁定及關閉套接字;
啓動、終止及維護worker進程的個數;
無須中止服務而重新配置工作特性;
控制非中斷式程序升級,啓用新的二進制程序並在需要時回滾至老版本;
重新打開日誌文件;
編譯嵌入式perl腳本;
worker進程主要完成的任務包括:
接收、傳入並處理來自客戶端的連接;
提供反向代理及過濾功能;
nginx任何能完成的其它任務;
3 Nginx 架構
Nginx的代碼是由一個核心和一系列的模塊組成, 核心主要用於提供Web Server的基本功能,以及Web和Mail反向代理的功能;還用於啓用網絡協議,創建必要的運行時環境以及確保不同的模塊之間平滑地進行交互。不過,大多跟協議相關的功能和某應用特有的功能都是由nginx的模塊實現的。這些功能模塊大致可以分爲事件模塊、階段性處理器、輸出過濾器、變量處理器、協議、upstream和負載均衡幾個類別,這些共同組成了nginx的http功能。事件模塊主要用於提供OS獨立的(不同操作系統的事件機制有所不同)事件通知機制如kqueue或epoll等。協議模塊則負責實現nginx通過http、tls/ssl、smtp、pop3以及imap與對應的客戶端建立會話。在Nginx內部,進程間的通信是通過模塊的pipeline或chain實現的;換句話說,每一個功能或操作都由一個模塊來實現。例如,壓縮、通過FastCGI或uwsgi協議與upstream服務器通信,以及與memcached建立會話等。
4 Nginx 基礎功能
處理靜態文件,索引文件以及自動索引;
反向代理加速(無緩存),簡單的負載均衡和容錯;
FastCGI,簡單的負載均衡和容錯;
模塊化的結構。過濾器包括gzipping, byte ranges, chunked responses, 以及 SSI-filter 。在SSI過濾器中,到同一個 proxy 或者 FastCGI 的多個子請求併發處理;
SSL 和 TLS SNI 支持;
5 Nginx IMAP/POP3 代理服務功能
使用外部 HTTP 認證服務器重定向用戶到 IMAP/POP3 後端;
使用外部 HTTP 認證服務器認證用戶後連接重定向到內部的 SMTP 後端;
認證方法:
POP3: POP3 USER/PASS, APOP, AUTH LOGIN PLAIN CRAM-MD5;
IMAP: IMAP LOGIN;
SMTP: AUTH LOGIN PLAIN CRAM-MD5;
SSL 支持;
在 IMAP 和 POP3 模式下的 STARTTLS 和 STLS 支持;
6 Nginx 支持的操作系統
FreeBSD 3.x, 4.x, 5.x, 6.x i386; FreeBSD 5.x, 6.x amd64;
Linux 2.2, 2.4, 2.6 i386; Linux 2.6 amd64;
Solaris 8 i386; Solaris 9 i386 and sun4u; Solaris 10 i386;
MacOS X (10.4) PPC;
Windows 編譯版本支持 windows 系列操作系統;
7 Nginx 結構與擴展
一個主進程和多個工作進程,工作進程運行於非特權用戶;
kqueue (FreeBSD 4.1+), epoll (Linux 2.6+), rt signals (Linux 2.2.19+), /dev/poll (Solaris 7 11/99+), select, 以及 poll 支持;
kqueue支持的不同功能包括 EV_CLEAR, EV_DISABLE (臨時禁止事件), NOTE_LOWAT, EV_EOF, 有效數據的數目,錯誤代碼;
sendfile (FreeBSD 3.1+), sendfile (Linux 2.2+), sendfile64 (Linux 2.4.21+), 和 sendfilev (Solaris 8 7/01+) 支持;
輸入過濾 (FreeBSD 4.1+) 以及 TCP_DEFER_ACCEPT (Linux 2.4+) 支持;
10,000 非活動的 HTTP keep-alive 連接僅需要 2.5M 內存。
最小化的數據拷貝操作;
8 Nginx 其他HTTP功能
基於IP 和名稱的虛擬主機服務;
Memcached 的 GET 接口;
支持 keep-alive 和管道連接;
靈活簡單的配置;
重新配置和在線升級而無須中斷客戶的工作進程;
可定製的訪問日誌,日誌寫入緩存,以及快捷的日誌回捲;
4xx-5xx 錯誤代碼重定向;
基於 PCRE 的 rewrite 重寫模塊;
基於客戶端 IP 地址和 HTTP 基本認證的訪問控制;
PUT, DELETE, 和 MKCOL 方法;
支持 FLV (Flash 視頻);
帶寬限制;
9 爲什麼選擇Nginx
在高連接併發的情況下,Nginx是Apache服務器不錯的替代品: Nginx在美國是做虛擬主機生意的老闆們經常選擇的軟件平臺之一. 能夠支持高達 50,000 個併發連接數的響應, 感謝Nginx爲我們選擇了 epoll and kqueue 作爲開發模型。
Nginx作爲負載均衡服務器: Nginx 既可以在內部直接支持 Rails 和 PHP 程序對外進行服務, 也可以支持作爲 HTTP代理 服務器對外進行服務. Nginx採用C進行編寫, 不論是系統資源開銷還是CPU使用效率都比 Perlbal 要好很多。
作爲郵件代理服務器: Nginx 同時也是一個非常優秀的郵件代理服務器(最早開發這個產品的目的之一也是作爲郵件代理服務器), Last.fm 描述了成功並且美妙的使用經驗.
Nginx 是一個 [#installation 安裝] 非常的簡單 , 配置文件 非常簡潔(還能夠支持perl語法),Bugs 非常少的服務器: Nginx 啓動特別容易, 並且幾乎可以做到7*24不間斷運行,即使運行數個月也不需要重新啓動. 你還能夠 不間斷服務的情況下進行軟件版本的升級 。
Nginx 的誕生主要解決C10K問題
10 三種工作模型比較:
Web服務器要爲用戶提供服務,必須以某種方式,工作在某個套接字上。一般Web服務器在處理用戶請求是,一般有如下三種方式可選擇:多進程方式、多線程方式、異步方式。
多進程方式:爲每個請求啓動一個進程來處理。由於在操作系統中,生成進程、銷燬進程、進程間切換都很消耗CPU和內存,當負載高是,性能會明顯降低。而httpd的prefork模型就是使用此種方式工作,故其性能較低。
優點: 穩定性!由於採用獨立進程處理獨立請求,而進程之間是獨立的,單個進程問題不會影響其他進程,因此穩定性最好。
缺點: 資源佔用!當請求過大時,需要大量的進程處理請求,進程生成、切換開銷很大,而且進程間資源是獨立的,造成內存重複利用。
多線程方式:一個進程生成多個線程其中用多個線程處理用戶請求。由於線程開銷明顯小於進程,而且部分資源還可以共享,因此效率較高。而httpd的worker模型就是使用此種方式工作。
優點:開銷較小!線程間部分數據是共享的,且線程生成與線程間的切換所需資源開銷比進程間切換小得多。
缺點:穩定性!線程切換過快可能造成線程抖動,且線程過多會造成服務器不穩定。
異步方式(事件模型):使用非阻塞方式處理請求,是三種方式中開銷最小的。但異步方式雖然效率高,但要求也高,因爲多任務之間的調度如果出現問題,就可能出現整體故障,因此使用異步工作的,一般是一些功能相對簡單,但卻符合服務器任務調度、且代碼中沒有影響調度的錯誤代碼存在的程序。而httpd的event模型就是使用此種方式工作。
優點:性能最好!一個進程或線程處理多個請求,不需要額外開銷,性能最好,資源佔用最低。
缺點:穩定性!某個進程或線程出錯,可能導致大量請求無法處理,甚至導致整個服務宕機。
11 一個Web請求的處理過程:
客戶發起情況到服務器網卡;
服務器網卡接受到請求後轉交給內核處理;
內核根據請求對應的套接字,將請求交給工作在用戶空間的Web服務器進程
Web服務器進程根據用戶請求,向內核進行系統調用,申請獲取相應資源(如index.html)
內核發現web服務器進程請求的是一個存放在硬盤上的資源,因此通過驅動程序連接磁盤
內核調度磁盤,獲取需要的資源
內核將資源存放在自己的緩衝區中,並通知Web服務器進程
Web服務器進程通過系統調用取得資源,並將其複製到進程自己的緩衝區中
Web服務器進程形成響應,通過系統調用再次發給內核以響應用戶請求
內核將響應發送至網卡
網卡發送響應給用戶
通過這樣的一個複雜過程,一次請求就完成了。
簡單來說就是:用戶請求-->送達到用戶空間-->系統調用-->內核空間-->內核到磁盤上讀取網頁資源->返回到用戶空間->響應給用戶。上述簡單的說明了一下,客戶端向Web服務請求過程,在這個過程中,有兩個I/O過程,一個就是客戶端請求的網絡I/O,另一個就是Web服務器請求頁面的磁盤I/O。
二、安裝nginx
1、下載nginx並解壓
[root@Director ~]# wget http://nginx.org/download/nginx-1.8.0.tar.gz [root@Director ~]# tar -xf nginx-1.8.0.tar.gz
2、創建nginx運行用戶
[root@Director ~]# groupadd -g 108 -r nginx [root@Director ~]# useradd -u 108 -r -g 108 nginx [root@Director ~]# id nginx uid=108(nginx) gid=108(nginx) 組=108(nginx)
3、編譯安裝nginx
[root@Director ~]# cd nginx-1.8.0 [root@Director nginx-1.8.0]# ./configure --prefix=/usr --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx/nginx.pid --lock-path=/var/lock/nginx.lock --user=nginx --group=nginx --with-http_ssl_module --with-http_flv_module --with-http_stub_status_module --with-http_gzip_static_module --http-client-body-temp-path=/var/tmp/nginx/client/ --http-proxy-temp-path=/var/tmp/nginx/proxy/ --http-fastcgi-temp-path=/var/tmp/nginx/fcgi/ --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi --http-scgi-temp-path=/var/tmp/nginx/scgi --with-pcre [root@Director nginx-1.8.0]# make && make install
4、查看nginx命令安裝的路徑
[root@Director nginx-1.8.0]# which nginx /usr/sbin/nginx
查看nginx安裝版本:
[root@Director nginx-1.8.0]# nginx -v nginx version: nginx/1.8.0
查看nginx編譯選項:
[root@Director nginx-1.8.0]# nginx -V nginx version: nginx/1.8.0 built by gcc 4.4.7 20120313 (Red Hat 4.4.7-16) (GCC) built with OpenSSL 1.0.1e-fips 11 Feb 2013 TLS SNI support enabled configure arguments: --prefix=/usr --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx/nginx.pid --lock-path=/var/lock/nginx.lock --user=nginx --group=nginx --with-http_ssl_module --with-http_flv_module --with-http_stub_status_module --with-http_gzip_static_module --http-client-body-temp-path=/var/tmp/nginx/client/ --http-proxy-temp-path=/var/tmp/nginx/proxy/ --http-fastcgi-temp-path=/var/tmp/nginx/fcgi/ --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi --http-scgi-temp-path=/var/tmp/nginx/scgi --with-pcre
5、爲nginx提供SysV init腳本
[root@Director nginx-1.8.0]# vim /etc/init.d/nginx #!/bin/sh # # nginx - this script starts and stops the nginx daemon # # chkconfig: - 85 15 # description: Nginx is an HTTP(S) server, HTTP(S) reverse \ # proxy and IMAP/POP3 proxy server # processname: nginx # config: /etc/nginx/nginx.conf # config: /etc/sysconfig/nginx # pidfile: /var/run/nginx.pid # Source function library. . /etc/rc.d/init.d/functions # Source networking configuration. . /etc/sysconfig/network # Check that networking is up. [ "$NETWORKING" = "no" ] && exit 0 nginx="/usr/sbin/nginx" prog=$(basename $nginx) NGINX_CONF_FILE="/etc/nginx/nginx.conf" [ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx lockfile=/var/lock/subsys/nginx make_dirs() { # make required directories user=`nginx -V 2>&1 | grep "configure arguments:" | sed 's/[^*]*--user=\([^ ]*\).*/\1/g' -` options=`$nginx -V 2>&1 | grep 'configure arguments:'` for opt in $options; do if [ `echo $opt | grep '.*-temp-path'` ]; then value=`echo $opt | cut -d "=" -f 2` if [ ! -d "$value" ]; then # echo "creating" $value mkdir -p $value && chown -R $user $value fi fi done } start() { [ -x $nginx ] || exit 5 [ -f $NGINX_CONF_FILE ] || exit 6 make_dirs echo -n $"Starting $prog: " daemon $nginx -c $NGINX_CONF_FILE retval=$? echo [ $retval -eq 0 ] && touch $lockfile return $retval } stop() { echo -n $"Stopping $prog: " killproc $prog -QUIT retval=$? echo [ $retval -eq 0 ] && rm -f $lockfile return $retval } restart() { configtest || return $? stop sleep 1 start } reload() { configtest || return $? echo -n $"Reloading $prog: " killproc $nginx -HUP RETVAL=$? echo } force_reload() { restart } configtest() { $nginx -t -c $NGINX_CONF_FILE } rh_status() { status $prog } rh_status_q() { rh_status >/dev/null 2>&1 } case "$1" in start) rh_status_q && exit 0 $1 ;; stop) rh_status_q || exit 0 $1 ;; restart|configtest) $1 ;; reload) rh_status_q || exit 7 $1 ;; force-reload) force_reload ;; status) rh_status ;; condrestart|try-restart) rh_status_q || exit 0 ;; *) echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}" exit 2 esac
6、將腳本賦予執行權限並添加到服務啓動列表
[root@Director nginx-1.8.0]# chmod +x /etc/init.d/nginx [root@Director nginx-1.8.0]# chkconfig --add nginx [root@Director nginx-1.8.0]# chkconfig nginx on
7、啓動nginx查看監聽的端口
[root@Director nginx-1.8.0]# service nginx start 正在啓動 nginx: [確定] [root@Director nginx-1.8.0]# ss -tunlp |grep nginx tcp LISTEN 0 128 *:80 *:* users:(("nginx",4618,6),("nginx",4620,6))
8、瀏覽器輸入linux主機的IP查看是否安裝成功
9、將在vim打開nginx配置文件時實現語句高亮顯示
http://www.vim.org/scripts/script.php?script_id=1886
[root@Director ~]# mkdir -pv .vim/syntax [root@Director ~]# mv nginx.vim .vim/syntax [root@Director ~]# vim .vim/filetype.vim au BufRead,BufNewFile /etc/nginx/*,/usr/local/nginx/conf/* if &ft == '' | setfiletype nginx | endif
三、nginx配置文件
1、配置文件結構
Nginx配置文件主要分爲4部分:main(全局設置)、server(主機設置)、upstream(負載均衡服務器設置)和 location(URL匹配特定位置的設置)。main部分設置的指令將影響其他所有設置;server部分的指令主要用於指定主機和端口;upstream指令主要用於負載均衡,設置一系列的後端服務器;location部分用於匹配網頁位置。這四者之間的關係如下:server繼承main,location繼承server,upstream既不會繼承其他設置也不會被繼承。如下圖,
在這4個部分當中,每個部分都包含若干指令,這些指令主要包含Nginx的主模塊指令、事件模塊指令、HTTP核心模塊指令。同時每個部分還可以使用其他HTTP模塊指令,例如Http SSL模塊、Http Gzip Static模塊和Http Addition模塊等。
下面通過一個Nginx配置實例,詳細介紹nginx.conf每個指令的含義。爲了能更清楚地瞭解Nginx的結構和每個配置選項的含義,這裏按照功能點將Nginx配置文件分爲7個部分依次講解。下面就圍繞這7個部分進行介紹。
2、一般配置文件介紹
(1).Nginx 的全局配置文件
#user nobody; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/nginx.pid; worker_rlimit_nofile 65535; worker_rlimit_sigpending #; events { use epoll; worker_connections 1024; }
上面這段代碼中每個配置選項的含義解釋如下:
user是個主模塊指令,指定Nginx Worker進程運行用戶以及用戶組,默認由nobody賬號運行。
worker_processes 是個主模塊指令,指定了Nginx要開啓的進程數。每個Nginx進程平均耗費10MB~12MB內存。根據經驗,一般指定一個進程足夠了,如果是多核CPU,建議指定爲CPU核心數減一個進程數即可。(注,如果負載以CPU密集型應用爲主,如SSL或壓縮應用,則worker數應與CPU數相同;如果負載以IO密集型爲主,如響應大量內容給客戶端,則worker數應該爲CPU個數的1.5或2倍。)
error_log是個主模塊指令,用來定義全局錯誤日誌文件。日誌輸出級別有debug、info、notice、warn、error、crit可供選擇,其中,debug輸出日誌最爲最詳細,而crit輸出日誌最少。
pid 是個主模塊指令,用來指定進程id的存儲文件位置。
worker_rlimit_nofile 指定一個worker進程所能夠打開的最大文件句柄數。
worker_rlimit_sigpending 設定每個用戶能夠發往worker進程的信號的數量。
events指令用來設定Nginx的工作模式及連接數上限。
use是個事件模塊指令,用來指定Nginx的工作模式。Nginx支持的工作模式有select、poll、kqueue、epoll、rtsig和/dev/poll。其中select和poll都是標準的工作模式,kqueue和epoll是高效的工作模式,不同的是epoll用在Linux平臺上,而kqueue用在BSD系統中。此選擇建議還是由nginx自行選擇。
worker_connections也是個事件模塊指令,用於定義Nginx每個進程的最大連接數,默認是1024。最大客戶端連接數由worker_processes和worker_connections決定,即max_client=worker_processes*worker_connections,在作爲反向代理時變爲:max_clients = worker_processes * worker_connections/4。(注,進程的最大連接數受Linux系統進程的最大打開文件數限制,在執行操作系統命令“ulimit -n 65536”後worker_connections的設置才能生效。)
(2).HTTP服務器配置
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
下面詳細介紹這段代碼中每個配置選項的含義。
include是個主模塊指令,實現對配置文件所包含的文件的設定,可以減少主配置文件的複雜度。類似於Apache中的include方法。
default_type 屬於HTTP核心模塊指令,這裏設定默認類型爲二進制流,也就是當文件類型未定義時使用這種方式,例如在沒有配置PHP環境時,Nginx是不予解析的,此時,用瀏覽器訪問PHP文件就會出現下載窗口。
log_format是Nginx的HttpLog模塊指令,用於指定Nginx日誌的輸出格式。main爲此日誌輸出格式的名稱,可以在下面的access_log指令中引用。
client_max_body_size用來設置允許客戶端請求的最大的單個文件字節數。
client_header_buffer_size用於指定來自客戶端請求頭的headerbuffer大小。對於大多數請求,1KB的緩衝區大小已經足夠,如果自定義了消息頭或有更大的cookie,可以增加緩衝區大小。這裏設置爲32KB。
large_client_header_buffers用來指定客戶端請求中較大的消息頭的緩存最大數量和大小, “4”爲個數,“128K”爲大小,最大緩存爲4個128KB。
sendfile參數用於開啓高效文件傳輸模式。將tcp_nopush和tcp_nodely兩個指令設置爲on,用於防止網絡阻塞。
keepalive_timeout 用於設置客戶端連接保持活動的超時時間。在超過這個時間之後,服務器會關閉該連接。
client_header_timeout用於設置客戶端請求頭讀取超時時間。如果超過這個時間,客戶端還沒有發送任何數據,Nginx將返回“Request time out(408)”錯誤。
client_body_timeout用於設置客戶端請求主體讀取超時時間,默認值爲60。如果超過這個時間,客戶端還沒有發送任何數據,Nginx將返回“Request time out(408)”錯誤。
send_timeout用於指定響應客戶端的超時時間。這個超時僅限於兩個連接活動之間的時間,如果超過這個時間,客戶端沒有任何活動,Nginx將會關閉連接。
gzip用於設置開啓或者關閉gzip模塊,“gzip on”表示開啓gzip壓縮,實時壓縮輸出數據流。
(3).HttpGzip模塊配置
下面配置Nginx的HttpGzip模塊。這個模塊支持在線實時壓縮輸出數據流。要查看是否安裝了此模塊,需要使用下面的命令:nginx -V ,通過nginx -V 命令可以查看安裝Nginx時的編譯選項。下面是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_buffers表示申請4個單位爲16K的內存作爲壓縮結果流緩存,默認值是申請與原始數據大小相同的內存空間來存儲gzip壓縮結果。
gzip_comp_level用來指定gzip壓縮比,1 壓縮比最小,處理速度最快;9 壓縮比最大,傳輸速度快,但處理最慢,也比較消耗CPU資源。
gzip_types用來指定壓縮的類型,無論是否指定,“text/html”類型總是會被壓縮的。
gzip_vary選項可以讓前端的緩存服務器緩存經過gzip壓縮的頁面,例如,用Squid緩存經過Nginx壓縮的數據。
(4).負載均衡配置
下面設定負載均衡的服務器列表:
upstream test.net{ ip_hash; server 192.168.10.13:80; server 192.168.10.14:80 down; server 192.168.10.15:8009 max_fails=3 fail_timeout=20s; server 192.168.10.16:8080; }
upstream是Nginx的HTTP Upstream模塊,這個模塊通過一個簡單的調度算法來實現客戶端IP到後端服務器的負載均衡。在上面的設定中,通過upstream指令指定了一個負載均衡器的名稱test.net。這個名稱可以任意指定,在後面需要用到的地方直接調用即可。
Nginx的負載均衡模塊目前支持4種調度算法,下面進行分別介紹,其中後兩項屬於第三方調度算法。
輪詢(默認)。每個請求按時間順序逐一分配到不同的後端服務器,如果後端某臺服務器宕機,故障系統被自動剔除,使用戶訪問不受影響。
Weight。指定輪詢權值,Weight值越大,分配到的訪問機率越高,主要用於後端每個服務器性能不均的情況下。
ip_hash。每個請求按訪問IP的hash結果分配,這樣來自同一個IP的訪客固定訪問一個後端服務器,有效解決了動態網頁存在的session共享問題。
fair。這是比上面兩個更加智能的負載均衡算法。此種算法可以依據頁面大小和加載時間長短智能地進行負載均衡,也就是根據後端服務器的響應時間來分配請求,響應時間短的優先分配。Nginx本身是不支持fair的,如果需要使用這種調度算法,必須下載Nginx的upstream_fair模塊。
url_hash。此方法按訪問url的hash結果來分配請求,使每個url定向到同一個後端服務器,可以進一步提高後端緩存服務器的效率。Nginx本身是不支持url_hash的,如果需要使用這種調度算法,必須安裝Nginx 的hash軟件包。
在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。
(5).server虛擬主機配置
下面介紹對虛擬主機的配置。建議將對虛擬主機進行配置的內容寫進另外一個文件,然後通過include指令包含進來,這樣更便於維護和管理。
server{ listen 80; server_name 192.168.12.188 www.test.net; index index.html index.htm index.php; root /web/www/www.test.net charset gb2312; access_log logs/www.test.net.access.log main;
server標誌定義虛擬主機開始;
listen用於指定虛擬主機的服務器端口;
server_name用來指定IP地址或者域名,多個域名之間用空格分開;
index用於設定訪問的默認首頁地址;
root指令用於指定虛擬主機的網頁根目錄,這個目錄可以是相對路徑,也可以是絕對路徑;
charset用於設置網頁的默認編碼格式。
access_log用來指定此虛擬主機的訪問日誌存放路徑。最後的main用於指定訪問日誌的輸出格式。
(6).URL匹配配置
URL地址匹配是Nginx配置中最靈活的部分。 location支持正則表達式匹配,也支持條件判斷匹配,用戶可以通過location指令實現Nginx對動、靜態網頁的過濾處理。
格式:location [ = | ~ | ~* | ^~ ] uri { ... }
location URI {}:對當前路徑及子路徑下的所有對象都生效;
location = URI {}:精確匹配指定的路徑,不包括子路徑,因此,只對當前資源生效;
location ~ URI {},location ~* URI {}:模式匹配URI,此處的URI可使用正則表達式,~區分字符大小寫,~*不區分字符大小寫;
location ^~ URI {}:不使用正則表達式
案例1:
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { root /web/www/www.test.net; expires 30d; }
說明:上面這段設置是通過location指令來對網頁URL進行分析處理,所有擴展名爲.gif、.jpg、.jpeg、.png、.bmp、.swf的靜態文件都交給Nginx處理,而expires用來指定靜態文件的過期時間,這裏是30天。
案例2:
location ~ ^/(upload|html)/ { root /web/www/www.test.net; expires 30d; }
說明:上面這段設置是將upload和html下的所有文件都交給Nginx來處理,當然,upload和html目錄包含/web/www/www.test.net目錄中。
案例3:
location ~ .*.jsp$ { index index.jsp; proxy_pass http://localhost:8080; }
說明:在最後這段設置中,location是對此虛擬主機下動態網頁的過濾處理,也就是將所有以.jsp爲後綴的文件都交給本機的8080端口處理。
location [ = | ~ | ~* | ^~ ] 優先級
ocation = URI {}:精確匹配指定的路徑,不包括子路徑,因此,只對當前資源生效;(優先級最高)
location ^~ URI {}:不使用正則表達式;(優先級次之)
location ~ URI {},location ~* URI {}:模式匹配URI,此處的URI可使用正則表達式,~區分字符大小寫,~*不區分字符大小寫;(優先級次之)
location URI {}:對當前路徑及子路徑下的所有對象都生效;(優先級最低)
(7).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
要查看Nginx的運行狀態,可以輸入http://ip/ NginxStatus,然後輸入剛剛創建的用戶名和密碼就可以看到如下信息:
Active connections: 1 server accepts handled requests 393411 393411 393799 Reading: 0 Writing: 1 Waiting: 0
Active connections表示當前活躍的連接數。
第三行的3個數字表示 Nginx當前總共處理了393411個連接, 成功創建了393 411次握手,總共處理了393 799個請求。
最後一行的Reading表示Nginx讀取到客戶端Header信息數; Writing表示Nginx返回給客戶端的Header信息數;Waiting表示Nginx已經處理完、正在等候下一次請求指令時的駐留連接數。
補充說明:
error_page 404 /404.html; error_page 500 502 503 504 /50x.html; location = /50x.html { root html; }
在最後這段設置中,設置了虛擬主機的錯誤信息返回頁面,通過error_page指令可以定製各種錯誤信息的返回頁面。在默認情況下,Nginx會在主目錄的html目錄中查找指定的返回頁面。特別需要注意的是,這些錯誤信息的返回頁面大小一定要超過512KB,否則會被IE瀏覽器替換爲IE默認的錯誤頁面。好了,到這裏nginx的配置文件講解全部完成。下面我們來說一說nginx命令參數。
3、配置文件深入介紹
(1).優化性能相關的配置
worker_rlimit_nofile #; 指定一個worker進程所能夠打開的最大文件句柄數;
worker_rlimit_sigpending #; 設定每個用戶能夠發往worker進程的信號的數量;
worker_processes #; worker進程的個數;通常其數值應該爲CPU的物理核心數減1;
worker_cpu_affinity cpumask ...; CPU親源性及使各個woeker進程分別運行在指定的CPU上,注意CPU是使用掩碼格式來填寫。但是這種方法並不能禁止系統使用該CPU進行其他的操作,還需要結合系統調優及CPU隔離才能很好的使用此選項,從而有效的減少CPU的上下文切換。舉例:worker_processes 6; worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000;
ssl_engine device; 在存在ssl硬件加速器的服務器上,指定所使用的ssl硬件加速設備;
timer_resolution t; 每次內核事件調用返回時,都會使用gettimeofday()來更新nginx緩存時鐘;timer_resolution用於定義每隔多久纔會由gettimeofday()更新一次緩存時鐘;x86-64系統上,gettimeofday()代價已經很小,可以忽略此配置;
worker_priority nice; worker進程的優先級,默認爲0建議調小點,但不能過小。-20,19之間的值;
(2).事件相關的配置
accept_mutex [on|off] ; 是否打開Ningx的負載均衡鎖;此鎖能夠讓多個worker進輪流地、序列化地與新的客戶端建立連接;而通常當一個worker進程的負載達到其上限的7/8,master就儘可能不再將請求調度此worker;
lock_file /path/to/lock_file; lock文件
accept_mutex_delay #ms; accept鎖模式中,一個worker進程爲取得accept鎖的等待時長;如果某worker進程在某次試圖取得鎖時失敗了,至少要等待#ms才能再一次請求鎖;默認500ms。
multi_accept on|off; 是否允許一次性地響應多個用戶請求;默認爲Off;
use [epoll|rtsig|select|poll]; 定義使用的事件模型,建議讓nginx自動選擇;
worker_connections #; 每個worker能夠併發響應最大請求數;
(3).調試、定位nginx問題
daemon on|off; 是否讓ningx運行後臺;默認爲on,調試時可以設置爲off,使得所有信息去接輸出控制檯;
master_process on|off 是否以master/worker模式運行nginx;默認爲on;調試時可設置off以方便追蹤;
error_log /path/to/error_log level; 錯誤日誌文件及其級別;默認爲error級別;調試時可以使用debug級別,但要求在編譯時必須使用--with-debug啓用debug功能;
(4).虛擬主機相關的配置
server {} 定義一個虛擬主機;nginx支持使用基於主機名或IP的虛擬主機;
listen address[:port] [default_server] [ssl] [spdy] [proxy_protocol] [setfib=number] [fastopen=number] [backlog=number] [rcvbuf=size] [sndbuf=size] [accept_filter=filter] [deferred] [bind] [ipv6only=on|off] [so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]];
說明:
default_server:定義此server爲http中默認的server;如果所有的server中沒有任何一個listen使用此參數,那麼第一個server即爲默認server;
backlog=number:指明tcp協議的backlog隊列的大小,默認爲-1,表示不設置 後援隊列;
rcvbuf=SIZE: 接收緩衝大小;
sndbuf=SIZE: 發送緩衝大小;
ssl: https server;
server_name [...]; server_name可以跟多個主機名,名稱中可以使用通配符和正則表達式(通常以~開頭);當nginx收到一個請求時,會取出其首部的server的值,而後跟衆server_name進行比較;比較方式:
先做精確匹配;www.example.com
左側通配符匹配;*.example.com
右側通配符匹配;www.*
正則表達式匹配: ~^.*\.example\.com$
server_name_hash_bucket_size 32|64|128; 爲了實現快速主機查找,nginx使用hash表來保存主機名;
location [ = | ~ | ~* | ^~ ] uri { ... } | location @name { ... } 功能:允許根據用戶請求的URI來匹配指定的各location以進行訪問配置;匹配到時,將被location塊中的配置所處理;比如:http://www.example.com/images/logo.gif
=:精確匹配;
~:正則表達式模式匹配,匹配時區分字符大小寫
~*:正則表達式模式匹配,匹配時忽略字符大小寫
^~: URI前半部分匹配,不檢查正則表達式
location = / { [ configuration A ] } location / { [ configuration B ] } location /documents/ { [ configuration C ] } location ^~ /images/ { [ configuration D ] } location ~* \.(gif|jpg|jpeg)$ { [ configuration E ] }
http://www.example.com/index.html 匹配到B。
http://www.example.com/ 匹配到A。
http://www.example.com/documents/index.html 匹配到C。
http://www.example.com/images/index.html 匹配到D。
http://www.example.com/images/a.jpg 匹配到E。
匹配優先級: 字符字面量最精確匹配-->正則表達式檢索(由第一個匹配到所處理)-->按字符字面量。
(5).文件路徑定義
root path 設置web資源路徑,用於指定請求的根文檔目錄;
location / { root /www/htdocs; } location ^~ /images/ { root /web; }
匹配的文件路徑爲root: root/URI/
alias path 只能用於location中,用於路徑別名;
location / { root /www/htdocs; } location ^~ /images/ { alias /web; }
匹配的文件路徑爲alias: alias/
index file ...; 定義默認頁面,可參跟多個值;
error_page code ... [=[response]] uri; 當對於某個請求返回錯誤時,如果匹配上了error_page指令中設定的code,則重定向到新的URI中。即錯誤頁面重定向;
try_files path1 [path2 ...] uri; 自左至右嘗試讀取由path所指定路徑,在第一次找到即停止並返回;如果所有path均不存在,則返回最後一個uri;
(6).網絡連接相關的設置
keepalive_timeout time; 保持連接的超時時長;默認爲75秒;
keepalive_requests n; 在一次長連接上允許承載的最大請求數;
keepalive_disable [msie6 | safari | none ] 對指定的瀏覽器禁止使用長連接;
tcp_nodelay on|off; 對keepalive連接是否使用TCP_NODELAY選項;默認是啓用的,一般是啓動的。
client_header_timeout time; 讀取http請求首部的超時時長;
client_body_timeout time; 讀取http請求包體的超時時長;
send_timeout time; 發送響應的超時時長;
(7).對客戶端請求的限制
limit_except method ... { ... } ;指定對範圍之外的其它方法的訪問控制;
client_max_body_size SIZE; http請求包體的最大值;常用於限定客戶所能夠請求的最大包體;根據請求首部中的Content-Length來檢測,以避免無用的傳輸;
limit_rate speed; 限制客戶端每秒鐘傳輸的字節數;默認爲0,表示沒有限制;
limit_rate_after time; nginx向客戶發送響應報文時,如果時長超出了此處指定的時長,則後續的發送過程開始限速;
(8).文件操作的優化
sendfile on|off 是否啓用sendfile功能;
aio on|off 是否啓用aio功能;
open_file_cache max=N [inactive=time]|off 是否打開文件緩存功能;
max: 緩存條目的最大值;當滿了以後將根據LRU算法進行置換;
inactive: 某緩存條目在指定時長時沒有被訪問過時,將自動被刪除;默認爲60s;
緩存的信息包括: 文件句柄、文件大小和上次修改時間。 已經打開的目錄結構。 沒有找到或沒有訪問權限的信息;
open_file_cache_errors on|off 是否緩存文件找不到或沒有權限訪問等相關信息;
open_file_cache_valid time; 多長時間檢查一次緩存中的條目是否超出非活動時長,默認爲60s;
open_file_cache_min_use #; 在inactive指定的時長內被訪問超此處指定的次數地,纔不會被刪除;
(9).對客戶端請求的特殊處理
ignore_invalid_headers on|off 是否忽略不合法的http首部,默認爲on。off意味着請求首部中出現不合規的首部將拒絕響應,只能用於server和http;
log_not_found on|off 是否將文件找不到的信息也記錄進錯誤日誌中;
esolver address; 指定nginx使用的dns服務器地址;
resover_timeout time; 指定DNS解析超時時長,默認爲30s;
server_tokens on|off; 是否在錯誤頁面中顯示nginx的版本號;
(10).內存及磁盤資源分配
client_body_in_file_only on|clean|off HTTP的包體是否存儲在磁盤文件中;非off表示存儲,即使包體大小爲0也會創建一個磁盤文件;on表示請求結束後包體文件不會被刪除,clean表示會被刪除;
client_body_in_single_buffer on|off; HTTP的包體是否存儲在內存buffer當中;默認爲off;
cleint_body_buffer_size size; nginx接收HTTP包體的內存緩衝區大小;
client_body_temp_path dir-path [level1 [level2 [level3]]]; HTTP包體存放的臨時目錄;
client_header_buffer_size size; 正常情況下接收用戶請求的http報文header部分時分配的buffer大小;默認爲1k;
large_client_header_buffers number size; 存儲超大Http請求首部的內存buffer大小及個數;
connection_pool_size size; nginx對於每個建立成功的tcp連接都會預先分配一個內存池,此處即用於設定此內存池的初始大小;默認爲256;
request_pool_size size; nginx在處理每個http請求時會預先分配一個內存池,此處即用於設定此內存池的初始大小;默認爲4k;
(11).http核心模塊的內置變量
$uri: 當前請求的uri,不帶參數;
$request_uri: 請求的uri,帶完整參數;
$host: http請求報文中host首部;如果請求中沒有host首部,則以處理此請求的虛擬主機的主機名代替;
$hostname: nginx服務運行在的主機的主機名;
$remote_addr: 客戶端IP
$remote_port: 客戶端Port
$remote_user: 使用用戶認證時客戶端用戶輸入的用戶名;
$request_filename: 用戶請求中的URI經過本地root或alias轉換後映射的本地的文件路徑;
$request_method: 請求方法
$server_addr: 服務器地址
$server_name: 服務器名稱
$server_port: 服務器端口
$server_protocol: 服務器向客戶端發送響應時的協議,如http/1.1, http/1.0
$scheme: 在請求中使用scheme, 如https://www.magedu.com/中的https;
$http_HEADER: 匹配請求報文中指定的HEADER,$http_host匹配請求報文中的host首部
$sent_http_HEADER: 匹配響應報文中指定的HEADER,例如$http_content_type匹配響應報文中的content-type首部;
$document_root:當前請求映射到的root配置;