高性能web服務器nginx(一)之基本概念

說明本篇文章大部分參考此人的博文: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請求的處理過程:

wKioL1XxR_LxouA5AAFFm5Xgto4627.jpg

  1. 客戶發起情況到服務器網卡;

  2. 服務器網卡接受到請求後轉交給內核處理;

  3. 內核根據請求對應的套接字,將請求交給工作在用戶空間的Web服務器進程

  4. Web服務器進程根據用戶請求,向內核進行系統調用,申請獲取相應資源(如index.html)

  5. 內核發現web服務器進程請求的是一個存放在硬盤上的資源,因此通過驅動程序連接磁盤

  6. 內核調度磁盤,獲取需要的資源

  7. 內核將資源存放在自己的緩衝區中,並通知Web服務器進程

  8. Web服務器進程通過系統調用取得資源,並將其複製到進程自己的緩衝區中

  9. Web服務器進程形成響應,通過系統調用再次發給內核以響應用戶請求

  10. 內核將響應發送至網卡

  11. 網卡發送響應給用戶

通過這樣的一個複雜過程,一次請求就完成了。

簡單來說就是:用戶請求-->送達到用戶空間-->系統調用-->內核空間-->內核到磁盤上讀取網頁資源->返回到用戶空間->響應給用戶。上述簡單的說明了一下,客戶端向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查看是否安裝成功

wKiom1XxRe7h3GRbAAHMQXGnLD8536.jpg

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既不會繼承其他設置也不會被繼承。如下圖,

wKiom1XxRgnBfvyEAADHEM44eYk919.jpg

在這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配置; 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章