1. 程式人生 > >nginx的基本詳解

nginx的基本詳解

http服務 直接 應用 linu 展示 red IE name #error

nginx簡介

  Nginx是lgor Sysoev為俄羅斯訪問量第二的rambler.ru站點設計開發的。從2004年發布至今,憑借開源的力量,已經接近成熟與完善。Nginx功能豐富,可作為HTTP服務器,也可作為反向代理服務器,郵件服務器。支持FastCGI、SSL、Virtual Host、URL Rewrite、Gzip等功能。並且支持很多第三方的模塊擴展。

  nginx可以作為反向代理、負載均衡和web緩存使用,本節主要講解nginx的負載均衡功能,按照不同的負載策略可以分發到不同的後端服務器。負載均衡的結構圖如下圖所示:

技術分享圖片

配置文件詳解

1、全局塊

  配置影響nginx全局的指令。一般有運行nginx服務器的用戶組,nginx進程pid存放路徑,日誌存放路徑,配置文件引入,允許生成worker process數等。

user
語法: user user [group]
缺省值: nobody nobody
指定Nginx Worker進程運行用戶,默認是nobody帳號。

error_log
語法: error_log file [ debug | info | notice | warn | error | crit ]
缺省值: ${prefix}/logs/error.log
指定錯誤日誌的存放位置和級別。

include
語法: include file | *
缺省值: none
include 指令還支持像下面配置一樣的全局包含的方法,例如包含一個目錄下所有以".conf"結尾的文件: include vhosts/*.conf;
pid

語法: pid file
進程id存儲文件。可以使用 kill -HUP cat /var/log/nginx.pid/ 對Nginx進行配置文件重新加載。

worker_processes
語法: worker_processes number
缺省值: 1,指定工作進程數。nginx可以使用多個worker進程(建議與本機CPU核心數一致)。

  實例

user  root root;
worker_processes  24;
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
error_log  logs/error.log  info;
pid        logs/nginx.pid;

2、events塊

  配置影響nginx服務器或與用戶的網絡連接。有每個進程的最大連接數,選取哪種事件驅動模型處理連接請求,是否允許同時接受多個網路連接,開啟多個網絡連接序列化等。

events

{
use epoll;
使用epoll的I/O 模型。linux建議epoll,FreeBSD建議采用kqueue,window下不指定。
補充說明:與apache相類,nginx針對不同的操作系統,有不同的事件模型
A)標準事件模型
Select、poll屬於標準事件模型,如果當前系統不存在更有效的方法,nginx會選擇select或poll
B)高效事件模型
Kqueue:使用於FreeBSD 4.1+, OpenBSD 2.9+, NetBSD 2.0 和 MacOS X.使用雙處理器的MacOS X系統使用kqueue可能會造成內核崩潰。
Epoll:使用於Linux內核2.6版本及以後的系統。
/dev/poll:使用於Solaris 7 11/99+,HP/UX 11.22+ (eventport),IRIX 6.5.15+ 和 Tru64 UNIX 5.1A+。
Eventport:使用於Solaris 10。 為了防止出現內核崩潰的問題, 有必要安裝安全補丁。

worker_connections 204800;
每個工作進程的最大連接數量。根據硬件調整,和前面工作進程配合起來用,盡量大,但是別把cpu跑到100%就行。每個進程允許的最多連接數,理論上每臺nginx服務器的最大連接數為。worker_processes*worker_connections

keepalive_timeout 60;
keepalive超時時間。

client_header_buffer_size 4k;
客戶端請求頭部的緩沖區大小。這個可以根據你的系統分頁大小來設置,一般一個請求頭的大小不會超過1k,不過由於一般系統分頁都要大於1k,所以這裏設置為分頁大小。
分頁大小可以用命令getconf PAGESIZE 取得。

open_file_cache max=65535 inactive=60s;
#這個是指多長時間檢查一次緩存的有效信息。
#語法:open_file_cache_valid time 默認值:open_file_cache_valid 60 使用字段:http, server, location 這個指令指定了何時需要檢查open_file_cache中緩存項目的有效信息.

open_file_cache_valid 80s;
#open_file_cache指令中的inactive參數時間內文件的最少使用次數,如果超過這個數字,文件描述符一直是在緩存中打開的,如上例,如果有一個文件在inactive時間內一次沒被使用,它將被移除。

open_file_cache_min_uses 1;
#語法:open_file_cache_min_uses number 默認值:open_file_cache_min_uses 1 使用字段:http, server, location  這個指令指定了在open_file_cache指令無效的參數中一定的時間範圍內可以使用的最小文件數,如果使用更大的值,文件描述符在cache中總是打開狀態.

open_file_cache_errors on;
#語法:open_file_cache_errors on | off 默認值:open_file_cache_errors off 使用字段:http, server, location 這個指令指定是否在搜索一個文件是記錄cache錯誤.
}

  實例

events {
    worker_connections  65535;
}

3、http塊

  可以嵌套多個server,配置代理,緩存,日誌定義等絕大多數功能和第三方模塊的配置。如文件引入,mime-type定義,日誌自定義,是否使用sendfile傳輸文件,連接超時時間,單連接請求數等。

1)http中的全局變量

http
{
include mime.types;
設定mime類型,類型由mime.type文件定義
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"‘;
log_format log404 ‘$status [$time_local] $remote_addr $host$request_uri $sent_http_location‘;
日誌格式設置。
$remote_addr與$http_x_forwarded_for用以記錄客戶端的ip地址;
$remote_user:用來記錄客戶端用戶名稱;
$time_local: 用來記錄訪問時間與時區;
$request: 用來記錄請求的url與http協議;
$status: 用來記錄請求狀態;成功是200,
$body_bytes_sent :記錄發送給客戶端文件主體內容大小;
$http_referer:用來記錄從那個頁面鏈接訪問過來的;
$http_user_agent:記錄客戶瀏覽器的相關信息;
通常web服務器放在反向代理的後面,這樣就不能獲取到客戶的IP地址了,通過$remote_add拿到的IP地址是反向代理服務器的iP地址。反向代理服務器在轉發請求的http頭信息中,可以增加x_forwarded_for信息,用以記錄原有客戶端的IP地址和原來客戶端的請求的服務器地址。

access_log  logs/host.access.log  main;
access_log  logs/host.access.404.log  log404;
用了log_format指令設置了日誌格式之後,需要用access_log指令指定日誌文件的存放路徑;

server_names_hash_bucket_size 128;
#保存服務器名字的hash表是由指令server_names_hash_max_size 和server_names_hash_bucket_size所控制的。參數hash bucket size總是等於hash表的大小,並且是一路處理器緩存大小的倍數。在減少了在內存中的存取次數後,使在處理器中加速查找hash表鍵值成為可能。如果hash bucket size等於一路處理器緩存的大小,那麽在查找鍵的時候,最壞的情況下在內存中查找的次數為2。第一次是確定存儲單元的地址,第二次是在存儲單元中查找鍵 值。因此,如果Nginx給出需要增大hash max size 或 hash bucket size的提示,那麽首要的是增大前一個參數的大小.

client_header_buffer_size 4k;
客戶端請求頭部的緩沖區大小。這個可以根據你的系統分頁大小來設置,一般一個請求的頭部大小不會超過1k,不過由於一般系統分頁都要大於1k,所以這裏設置為分頁大小。分頁大小可以用命令getconf PAGESIZE取得。

large_client_header_buffers 8 128k;
客戶請求頭緩沖大小。nginx默認會用client_header_buffer_size這個buffer來讀取header值,如果header過大,它會使用large_client_header_buffers來讀取。

open_file_cache max=102400 inactive=20s;
這個指令指定緩存是否啟用。
例: open_file_cache max=1000 inactive=20s; 

open_file_cache_valid 30s; 
語法:open_file_cache_valid time 默認值:open_file_cache_valid 60 使用字段:http, server, location 這個指令指定了何時需要檢查open_file_cache中緩存項目的有效信息.

open_file_cache_min_uses 2; 
語法:open_file_cache_min_uses number 默認值:open_file_cache_min_uses 1 使用字段:http, server, location 這個指令指定了在open_file_cache指令無效的參數中一定的時間範圍內可以使用的最小文件數,如果使用更大的值,文件描述符在cache中總是打開狀態.

open_file_cache_errors on;
語法:open_file_cache_errors on | off 默認值:open_file_cache_errors off 使用字段:http, server, location 這個指令指定是否在搜索一個文件是記錄cache錯誤.

client_max_body_size 300m;
設定通過nginx上傳文件的大小

sendfile on;
sendfile指令指定 nginx 是否調用sendfile 函數(zero copy 方式)來輸出文件,對於普通應用,必須設為on。如果用來進行下載等應用磁盤IO重負載應用,可設置為off,以平衡磁盤與網絡IO處理速度,降低系統uptime。

tcp_nodelay on;
tcp_nopush on;
此選項允許或禁止使用socke的TCP_CORK的選項,此選項僅在使用sendfile的時候使用

keys_zone=cache_one:200m inactive=1d max_size=30g;
#設置內存緩存空間大小為200MB,1天沒有被訪問的內容自動清除,硬盤緩存空間大小為30GB。

keepalive_timeout 120;
keepalive超時時間。

client_body_buffer_size 512k;
如果把它設置為比較大的數值,例如256k,那麽,無論使用firefox還是IE瀏覽器,來提交任意小於256k的圖片,都很正常。如果註釋該指令,使用默認的client_body_buffer_size設置,也就是操作系統頁面大小的兩倍,
8k或者16k,問題就出現了。無論使用firefox4.0還是IE8.0,提交一個比較大,200k左右的圖片,都返回500 Internal Server Error錯誤 #http_proxy模塊
。。。。。。 #gzip模塊 。。。。。。 upstream bakend { 。。。。。。。 } #server模塊 。。。。。 }

2)gzip模塊

gzip_static on;
gzip_http_version   1.0;
gzip_proxied        expired no-cache no-store private auth;
gzip_vary           on;
gzip  on;
gzip_types text/plain text/css text/xml application/xml application/xml+rss application/json;
gzip_min_length 1100;
gzip_buffers 4 8k;

  gzip on|off
  # 默認值: gzip off
  # 開啟或者關閉gzip模塊

  gzip_static on|off

  # nginx對於靜態文件的處理模塊
  # 該模塊可以讀取預先壓縮的gz文件,這樣可以減少每次請求進行gzip壓縮的CPU資源消耗。該模塊啟用後,nginx首先檢查是否存在請求靜態文件的gz結尾的文件,如果有則直接返回該gz文件內容。為了要兼容不支持gzip的瀏覽器,啟用gzip_static模塊就必須同時保留原始靜態文件和gz文件。這樣的話,在有大量靜態文件的情況下,將會大大增加磁盤空間。我們可以利用nginx的反向代理功能實現只保留gz文件。
  #可以google"nginx gzip_static"了解更多

  gzip_comp_level 4

  # 默認值:1(建議選擇為4)
  # gzip壓縮比/壓縮級別,壓縮級別 1-9,級別越高壓縮率越大,當然壓縮時間也就越長(傳輸快但比較消耗cpu)。

  gzip_buffers 4 16k
  # 默認值: gzip_buffers 4 4k/8k
  # 設置系統獲取幾個單位的緩存用於存儲gzip的壓縮結果數據流。 例如 4 4k 代表以4k為單位,按照原始數據大小以4k為單位的4倍申請內存。 4 8k 代表以8k為單位,按照原始數據大小以8k為單位的4倍申請內存。
  # 如果沒有設置,默認值是申請跟原始數據相同大小的內存空間去存儲gzip壓縮結果。

  gzip_types mime-type [mime-type ...]

  # 默認值: gzip_types text/html (默認不對js/css文件進行壓縮)
  # 壓縮類型,匹配MIME類型進行壓縮
  # 不能用通配符 text/*
  # (無論是否指定)text/html默認已經壓縮
  # 設置哪壓縮種文本文件可參考 conf/mime.types

  gzip_min_length 1k
  # 默認值: 0 ,不管頁面多大都壓縮
  # 設置允許壓縮的頁面最小字節數,頁面字節數從header頭中的Content-Length中進行獲取。
  # 建議設置成大於1k的字節數,小於1k可能會越壓越大。 即: gzip_min_length 1024

  gzip_http_version 1.0|1.1

  # 默認值: gzip_http_version 1.1(就是說對HTTP/1.1協議的請求才會進行gzip壓縮)
  # 識別http的協議版本。由於早期的一些瀏覽器或者http客戶端,可能不支持gzip自解壓,用戶就會看到亂碼,所以做一些判斷還是有必要的。
  # 註:99.99%的瀏覽器基本上都支持gzip解壓了,所以可以不用設這個值,保持系統默認即可。
  # 假設我們使用的是默認值1.1,如果我們使用了proxy_pass進行反向代理,那麽nginx和後端的upstream server之間是用HTTP/1.0協議通信的,如果我們使用nginx通過反向代理做Cache Server,而且前端的nginx沒有開啟gzip,同時,我們後端的nginx上沒有設置gzip_http_version為1.0,那麽Cache的url將不會進行gzip壓縮

  gzip_proxied [off|expired|no-cache|no-store|private|no_last_modified|no_etag|auth|any] ...
  # 默認值:off
  # Nginx作為反向代理的時候啟用,開啟或者關閉後端服務器返回的結果,匹配的前提是後端服務器必須要返回包含"Via"的 header頭。
  off - 關閉所有的代理結果數據的壓縮
  expired - 啟用壓縮,如果header頭中包含 "Expires" 頭信息
  no-cache - 啟用壓縮,如果header頭中包含 "Cache-Control:no-cache" 頭信息
  no-store - 啟用壓縮,如果header頭中包含 "Cache-Control:no-store" 頭信息
  private - 啟用壓縮,如果header頭中包含 "Cache-Control:private" 頭信息
  no_last_modified - 啟用壓縮,如果header頭中不包含 "Last-Modified" 頭信息
  no_etag - 啟用壓縮 ,如果header頭中不包含 "ETag" 頭信息
  auth - 啟用壓縮 , 如果header頭中包含 "Authorization" 頭信息
  any - 無條件啟用壓縮

  gzip_vary on
  # 和http頭有關系,加個vary頭,給代理服務器用的,有的瀏覽器支持壓縮,有的不支持,所以避免浪費不支持的也壓縮,所以根據客戶端的HTTP頭來判斷,是否需要壓縮

  gzip_disable "MSIE [1-6]."

  #禁用IE6的gzip壓縮,又是因為杯具的IE6。當然,IE6目前依然廣泛的存在,所以這裏你也可以設置為“MSIE [1-5].”

  #IE6的某些版本對gzip的壓縮支持很不好,會造成頁面的假死,今天產品的同學就測試出了這個問題後來調試後,發現是對img進行gzip後造成IE6的假死,把對img的gzip壓縮去掉後就正常了為了確保其它的IE6版本不出問題,所以建議加上gzip_disable的設置

3)upstream模塊

    作為負載均衡池,可以為一個請求分配多個負載,防止單臺服務器宕機後請求無法處理,負載均衡的策略有:輪詢、加權輪詢和哈希一致,配置如下:

#加權輪詢
upstream back_openaccess {
                server 10.159.39.136:12080 weight=2 max_fails=3 fail_timeout=10s;
                server 10.159.39.137:12080 weight=2 max_fails=3 fail_timeout=10s;
        }
#ip_hash
upstream back_openadmin {
                ip_hash;
		server 10.159.39.136:12081;
                server 10.159.39.137:12081;
        }

  加權輪詢配置參數:

  down 表示單前的server暫時不參與負載.

  weight 默認為1.weight越大,負載的權重就越大。

  max_fails :允許請求失敗的次數默認為1.當超過最大次數時,返回proxy_next_upstream 模塊定義的錯誤.

  fail_timeout : max_fails次失敗後,暫停的時間。

  backup: 其它所有的非backup機器down或者忙的時候,請求backup機器。所以這臺機器壓力會最輕。

  max_conns:限制分配給某臺Server處理的最大連接數量,超過這個數量,將不會分配新的連接給它。默認為0,表示不限制。註意:1.5.9之後的版本才有這個配置

4)server模塊

    server {
        listen       80;
        server_name  "127.0.0.1";
        root   /kingdee/www/;
        #Open underscores_in_headers
        underscores_in_headers on;
        proxy_redirect off;  
        include  conf.d/*.conf;

	location /ngs {
        	stub_status on;
        	access_log on;
        }

        location /upss {
        	check_status;
        	access_log off;
        }
    }

  listen:監聽端口,默認80,小於1024的要以root啟動。可以為listen *:80listen 127.0.0.1:80等形式。

  server_name:服務器名,如localhost、www.example.com,可以通過正則匹配。

  root:設定響應的根目錄。

  include:引入其他的配置文件。  

  underscores_in_headers:支持讀取非nginx標準的用戶自定義header的,但是需要在http或者server下開啟header。

  proxy_redirect:語法:proxy_redirect [ default|off|redirect replacement ] ,默認值:proxy_redirect default ,修改被代理服務器返回的響應頭。例如:proxy_redirect http://localhost:8000/two/ http://frontend/one/;將Location字段重寫為http://frontend/one/。

  location:根據請求的RUI設置配置,進行負載均衡。location中的配置參數如下:

     1、proxy_set_header參數:語法為:proxy_set_header Field Value。常見的設置如:

      proxy_set_header Host $proxy_host;

       獲取nginx配置中的server_name值。

      proxy_set_header X-Real-IP $remote_addr;

      有了這個配置就可以在web服務器端獲得用戶的真實ip

      proxy_set_header X-Forwarded-For $remote_addr;

      我們先看看這裏有個X-Forwarded-For變量,這是一個squid開發的,用於識別通過HTTP代理或負載平衡器原始IP一個連接到Web服務器的客戶機地址的非rfc標準,如果有做X-Forwarded-For設置

      的話,每次經過proxy轉發都會有記錄,格式就是client1, proxy1, proxy2,以逗號隔開各個地址,由於他是非rfc標準,所以默認是沒有的,需要強制添加,在默認情況下經過proxy轉發的請求,在後端看

      來遠程地址都是proxy端的ip 。也就是說在默認情況下我們使用request.getAttribute("X-Forwarded-For")獲取不到用戶的ip,如果我們想要通過這個變量獲得用戶的ip,我們需要自己在nginx添加配置。

    2、proxy_pass:轉發的代理路徑

        情況一、location /test/ {
      proxy_pass http://t6:8300;
         }
        情況二、location /test/ {
      proxy_pass http://t6:8300/;
        }

        針對情況2,如果訪問url = http://server/test/test.jsp,則被nginx代理後,請求路徑會變為 http://proxy_pass/test.jsp,直接訪問server的根資源

        針對情況1,如果訪問url = http://server/test/test.jsp,則被nginx代理後,請求路徑會便問http://proxy_pass/test/test.jsp,將test/ 作為根路徑,請求test/路徑下的資源  

5)proxy_buffer模塊

proxy_buffer_size 256k;
設置從被代理服務器讀取的第一部分應答的緩沖區大小,通常情況下這部分應答中包含一個小的應答頭,默認情況下這個值的大小為指令proxy_buffers中指定的一個緩沖區的大小,不過可以將其設置為更小
proxy_buffers 4 256k;
設置用於讀取應答(來自被代理服務器)的緩沖區數目和大小,默認情況也為分頁大小,根據操作系統的不同可能是4k或者8k
proxy_busy_buffers_size 256k;
proxy_connect_timeout 90; 
後端服務器連接的超時時間_發起握手等候響應超時時間

proxy_read_timeout 180;
連接成功後_等候後端服務器響應時間_其實已經進入後端的排隊之中等候處理(也可以說是後端服務器處理請求的時間)

proxy_send_timeout 180;
後端服務器數據回傳時間_就是在規定時間之內後端服務器必須傳完所有的數據

proxy_temp_file_write_size 256k;
設置在寫入proxy_temp_path時數據的大小,預防一個工作進程在傳遞文件時阻塞太長

proxy_temp_path /data0/proxy_temp_dir;
proxy_temp_path和proxy_cache_path指定的路徑必須在同一分區

  1. proxy_buffering

  語法:proxy_buffering on|off

  默認值:proxy_buffering 0n

  該 指令開啟從後端被代理服務器的響應內容緩沖。如果緩沖區開啟,nginx假定被代理的後端服務器會以最快速度響應,並把內容保存在由指令 proxy_buffer_size 和 proxy_buffers指定的緩沖區裏邊.如果響應內容無法放在內存裏邊,那麽部分內容會被寫到磁盤上。如果緩沖區被關閉了,那麽響應內容會按照獲取 內容的多少立刻同步傳送到客戶端。nginx不嘗試計算被代理服務器整個響應內容的大小,nginx能從服務器接受的最大數據,是由指令 proxy_buffer_size指定的.對於基於長輪詢(long-polling)的Comet 應用來說,關閉 proxy_buffering 是重要的,不然異步響應將被緩存導致Comet無法工作。

  2. proxy_buffers

  語法:proxy_buffers 數量 大小

  默認值:proxy_buffers 8 4k/8k

  該指令設置緩沖區的大小和數量,從被代理的後端服務器取得的響應內容,會放置到這裏. 默認情況下,一個緩沖區的大小等於內存頁面大小,可能是4K也可能是8K,這取決於平臺。

  3. proxy_buffer_size

  語法:proxy_buffer_size the size

  默認值:proxy_buffer_size 4k/8k

  該指令設置緩沖區大小,從代理後端服務器取得的第一部分的響應內容,會放到這裏.小的響應header通常位於這部分響應內容裏邊.默認來說,該緩沖區大小等於指令 proxy_buffers所設置的;但是,你可以把它設置得更小.

  4. proxy_busy_buffers_size

  語法:proxy_busy_buffers_size 大小

  默認值:proxy_busy_buffers_size proxy_buffer_size*2

  buffer 工作原理

  1. 所有的proxy buffer參數是作用到每一個請求的。每一個請求會安按照參數的配置獲得自己的buffer。proxy buffer不是global而是per request的。

  2. proxy_buffering 是為了開啟response buffering of the proxied server,開啟後proxy_buffers和proxy_busy_buffers_size參數才會起作用。

  3. 無論proxy_buffering是否開啟,proxy_buffer_size(main buffer)都是工作的,proxy_buffer_size所設置的buffer_size的作用是用來存儲upstream端response的header。

  4. 在proxy_buffering 開啟的情況下,Nginx將會盡可能的讀取所有的upstream端傳輸的數據到buffer,直到proxy_buffers設置的所有buffer們 被寫滿或者數據被讀取完(EOF)。此時nginx開始向客戶端傳輸數據,會同時傳輸這一整串buffer們。同時如果response的內容很大的 話,Nginx會接收並把他們寫入到temp_file裏去。大小由proxy_max_temp_file_size控制。如果busy的buffer 傳輸完了會從temp_file裏面接著讀數據,直到傳輸完畢。

  5. 一旦proxy_buffers設置的buffer被寫入,直到buffer裏面的數據被完整的傳輸完(傳輸到客戶端),這個buffer將會一直處 在busy狀態,我們不能對這個buffer進行任何別的操作。所有處在busy狀態的buffer size加起來不能超過proxy_busy_buffers_size,所以proxy_busy_buffers_size是用來控制同時傳輸到客戶 端的buffer數量的。4、server塊:配置虛擬主機的相關參數,一個http中可以有多個server。

Nginx的部分模塊

stub_status模塊

  stub_status模塊主要用來展示nginx的狀態信息也就是nginx的統計信息。配置信息如下:

location /ngs {
    stub_status on;
    access_log on;
        }

  在輸入域名/ngs後會展示nginx的統計信息如下:

技術分享圖片

  Active connections: 當前nginx正在處理的活動連接數.
  Server accepts handled requests request_time: nginx總共處理了13057 個連接,成功創建13057 握手(證明中間沒有失敗的),總共處理了11634 個請求,總共請求時間2230854。
  Reading: nginx讀取到客戶端的Header信息數.
  Writing: nginx返回給客戶端的Header信息數.
  Waiting: 開啟keep-alive的情況下,這個值等於 active – (reading + writing),意思就是nginx已經處理完成,正在等候下一次請求指令的駐留連接。所以,在訪問效率高,請求很快被處理完畢的情況下,Waiting數比較多是正常的.如果reading +writing數較多,則說明並發訪問量非常大,正在處理過程中。

nginx的基本詳解