ngnix 手冊翻譯

翻譯了nginx的開始部分,以後有時間繼續。



開始指南

Nginx有一個主進程和多個工作進程。主進程的目的是讀取和評估配置並維護工作進程。工作進程處理請求任務。各個工作進程使用基於事件的模式和依賴操作系統機制在他們之間有效分發請求。工作進程數量在配置文件中定義。可以是固定的也可以更加cpu內核數量動態調整。

默認配置文件位置/usr/local/nginx/conf,/etc/nginx/usr/local/etc/nginx名字爲nginx.conf

Nginx –s signal

Signal參數有以下幾種

stop ---快速退出

quit---平穩退出(等待工作進程完成當前請求後退出)

reload ----重新加載配置文件(更改配置文件必須重新加載一下)

reopen---重新打開日誌文件

得到nginx進程列表 ps –ef|grep nginx

配置文件結構

Nginx由一些模塊組成。


服務靜態內容

Web服務一個重要任務是發佈文件(如圖像和靜態html網頁)。舉例:有兩個目錄中文件需發佈/data/www,/data/images則需要在http塊中加一個包含兩個locationserver塊。

http{

server {

}

}

多個server塊通過端口或server names區分。

server {
    location / {
        root /data/www;
    }
    location /images/ {
        root /data;
    }
}

查詢出錯原因請查看 access.log error.log在目錄/usr/local/nginx/var/log/nginx


設置一個簡單的代理服務器

在配置文件中添加如下內容:

server {
    listen 8080;
    root /data/up1;
    location / {
    }
}

這是一個代理服務和被代理服務在同一服務器上的實例。

也可以用如下方式:

server {
    location / {
        proxy_pass http://localhost:8080;
    }
    location /images/ {
        root /data;
    }
}

還可以使用正則表達式指定文件類型以~開始。

server {
    location / {
        proxy_pass http://localhost:8080/;
    }
    location ~ \.(gif|jpg|png)$ {
        root /data/images;
    }
}

設置fastcgi代理

Nginx可以路由請求到fastcgi服務器。

可用如下設置

server {
    location / {
        fastcgi_pass  localhost:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param QUERY_STRING    $query_string;
    }
    location ~ \.(gif|jpg|png)$ {
        root /data/images;
    }

Query_string參數:被用來傳遞請求參數。









控制nginx

Nginx主進程id默認被寫入文件/usr/local/nginx/logs/nginxpid

更改配置

nginx –s HUP(新請求用更改後配置,未結束請求繼續用舊配置,所有請求結束後都開始用新配置)

連接處理方法

Nginx會自動選擇最有效的連接處理方法,也可以使用 use指令明確指定。有如下方法支持。

select:標準方法。支持模塊被自動構建。用—with-select_module—without-select_module啓用和禁用模塊。

poll:標準方法。--with-poll_module —without-poll_module

kqueue :freebsd4.1+OpenBSD 2.9 NetBSD 2.0 mac os x上用

epoll :有效方法用在linux 2.6+

rtsig:實時信號。用在linux 2.2.19+上有效。默認系統範圍事件隊列默認限制1024個信號。在高負載機器上需要增加它的限制可在/proc/sys/kernel/rtsig-maxkernel parameter中更改。在linux2.6.6-mm2中已沒有此參數。每個進程有他自己的隊列。每個隊列大小被RLIMIT_SIGPENDING限制。可用worker_rlimit_sigpending參數更改。

/dev/poll/ Solaris711/99+ HP/UX 11.22+ IRIX 6.5.15= andtru64 unix 5.1A+上有效。

Eventport solaris10上有效。




配置hashes

Nginx使用hash tables處理如 server namesmap directive’s 值,mime types 請求頭字符串名。Server names hash server_names_hash_max_size server_name_hash_bucker_size

Hash bucketsize 和一個處理器的緩存大小的倍數匹配。它可以加速key搜索,減少內存訪問次數。如果hash bucket大小等於處理器緩存大小那麼在最糟糕的情形下在搜索key的內存訪問次數是兩次。1.計算bucket地址,2。在bucket中搜索key。因此,如果nginx發出信息增加的話要麼增加hash max size 要麼增加bucket size 第一個參數首先被增加。

調試日誌

支持debugging log 在編譯時加上 --with-debug

./configure –with-debug

設置error_log 調試等級

error_log/path/to/log debug

重新定義log時不指定bebuglevel將會禁用調試日誌功能。

error_log /path/to/log debug;
http {
    server {
        error_log /path/to/log;

表明在server塊中禁用調試日誌。

還可以指定日誌服務器地址爲debug level

error_log /path/to/log;
events {
    debug_connection 192.168.1.1;
    debug_connection 192.168.10.0/24;
}
                   Nginx如何處理一個請求
server {
    listen      80;
    server_name example.org www.example.org;
    ...
}
server {
    listen      80;
    server_name example.net www.example.net;
    ...
}
server {
    listen      80;
    server_name example.com www.example.com;
    ...
}
上面配置文件根據請求頭的域“host”決定請求被路由到那個服務器。如果都不匹配則路由到第一個服務器(默認)。也可以明確指定那個是默認服務器。
server {
    listen      80 default_server;
    server_name example.net www.example.net;
    ...
}
如何定義阻止未定義的請求
server {
    listen      80;
    server_name "";
    return      444;
}
這樣未定義的host,將被丟棄。
0.8.48以後版本這是默認配置。



基於名字和ip的虛擬服務

server {
    listen      192.168.1.1:80;
    server_name example.org www.example.org;
    ...
}
server {
    listen      192.168.1.1:80;
    server_name example.net www.example.net;
    ...
}
server {
    listen      192.168.1.2:80;
    server_name example.com www.example.com;
    ...
}

在此配置中nginx先匹配請求中ip地址和端口,然後是“host”域。如果沒找到,請求被默認服務器處理。

一個默認服務是一個合適的偵聽端口,不同的端口可定義不同的默認服務器。

server {
    listen      192.168.1.1:80;
    server_name example.org www.example.org;
    ...
}
server {
    listen      192.168.1.1:80 default_server;
    server_name example.net www.example.net;
    ...
}
server {
    listen      192.168.1.2:80 default_server;
    server_name example.com www.example.com;
    ...
}


一個簡單的php站點配置

server {
    listen      80;
    server_name example.org www.example.org;
    root        /data/www;
    location / {
        index   index.html index.php;
    }
location ~* \.(gif|jpg|png)$ {
        expires 30d;
    }
    location ~ \.php$ {
        fastcgi_pass  localhost:9000;
        fastcgi_param SCRIPT_FILENAME
                      $document_root$fastcgi_script_name;
        include       fastcgi_params;
    }
}

Nignx首先搜索prefix location,不管列出順序如何。上面配置文件僅有的prefixlocation是“/”,由於它匹配任何請求,所以被最後執行。Nginx檢查列表中location的正則表達式,找到第一個匹配的表達式就會停止搜索,nginx會使用這個location。如果沒有匹配的,nginx用先前找到的特定的prefixlocation

注意:location測試的是URI請求行的一部分,沒有參數。

1.一個請求“/logo.gif”首先匹配 prefix location,然後匹配表達式“\.(gif|jpg|png)$”,因此被後一個location處理。使用指令root /data/www請求被映射到文件/data/www/logo.gif,然後被髮送到客戶端。

2.一個請求/index.php同樣首先匹配prefix location/“,然後匹配表達式\.(php)$。因此,被後一個表達式處理。請求被髮送到fastcgiserver 本機的localhost:9000.Thefastcgi_param指令設置FastCGI 參數SCRIPT_FILENAMEto “/data/www/index.php”,變量$document_root匹配root指令的值。變量$fastcgi_script_name匹配請求的URI,/index.php”.

3.請求/about.html只匹配prefixlocation,所以只被這個location處理。請求被映射到/data/www/about.html

4.處理請求“/“較複雜。他只匹配prefixlocation。因此只被這個location處理。然後index指令檢查index文件是存在,如果/data/www/index.html不存在,/data/www/index.php存在,那麼指令會做一個內部重定向到/index.php並被fastcgiserver 處理。

優化

1.完整的名字,2.以通配符開始的名字,3.以通配符結束的名字被存儲在綁定到端口的三張hash 表中。Hash 表大小可調。目的是名字能更快被找到。三張表按序搜索。含通配符名字hash表搜索較慢。正則表達式最慢而且不可擴展。

如果有大量服務名被定義,或不常用的長服務名被定義,調整server_names_hash_max_sizeandserver_names_hash_bucket_size指令httplevel中是有幫助的。可以是3264或其他值,取決於cpu 緩存大小。如果默認值是32server name被定義成too.long.server.name.example.org” nginx 未能啓動並顯示如下信息:

could not build the server_names_hash,
you should increase server_names_hash_bucket_size: 32

這個例子中指令值應被增加

http {
    server_names_hash_bucket_size  64;
...
如果出現如下信息;
could not build the server_names_hash,
you should increase either server_names_hash_max_size: 512
or server_names_hash_bucket_size: 32
這個例子中,首先嚐試設置server_names_hash_max_size的數量server names相當。如果沒有效果,或nginx啓動時間不可接受嘗試增加server_names_hash_bucket_size.


配置https服務器

配置https服務器,ssl參數必須被激活在serverlisteningsockets。服務器位置證書和私鑰應該被指定。

server {
    listen              443 ssl;
    server_name         www.example.com;
    ssl_certificate     www.example.com.crt;
    ssl_certificate_key www.example.com.key;
    ssl_protocols       SSLv3 TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers         HIGH:!aNULL:!MD5;
    ...
}

服務器證書是一個公共實體。它被髮送給每個客戶端。私鑰是安全實體應該被保存在一個受限制文件中。它必須可被master主進程讀取。私鑰可以和證書一起存儲在一個相同的文件中

ssl_certificate     www.example.com.cert;
    ssl_certificate_key www.example.com.cert;

這個例子中文件權限應該被約束,只有證書可以被髮送到客戶端。

https優化

ssl操作消耗更多的cpu資源。一個多處理系統有多個worker進程被運行數量不少於可用cpu內核數。Cpu集中操作在ssl握手期間。有兩種方法可以最小化操作和每個客戶端握手的數量。1.使keepalive連接可用,通過一個連接發送多個請求。2.爲並行的和後來的連接重新使用ssl session 參數避免ssl多次握手。Sessions被存儲於ssl session緩存中。被多個workers進程共享。在ssl_session_cache指令中配置。1m字節緩存可包含4000sessions。默認緩存超時是5分中。可在ssl_sessioni_timeout中設置。下面是一個簡單配置爲一個多核系統包含10m共享session 緩存的系統優化。

worker_processes auto;
http {
ssl_session_cache  shared:SSL:10m;
ssl_session_timeout 10m;
    server {
        listen              443 ssl;
        server_name         www.example.com;
keepalive_timeout  70;
        ssl_certificate     www.example.com.crt;
        ssl_certificate_key www.example.com.key;
        ssl_protocols       SSLv3 TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers         HIGH:!aNULL:!MD5;
        ...

Ssl證書鏈

一些瀏覽器可能拒絕一個衆所周知的證書權威機構簽發的證書,而其他瀏覽器沒有問題。可以使用證書鏈解決。服務器證書應該在bundle.crt之前。

$ cat www.example.com.crt bundle.crt > www.example.com.chained.crt

文件應該被用在ssl_certificate指令:

server {
    listen              443 ssl;
    server_name         www.example.com;
    ssl_certificate     www.example.com.chained.crt;
    ssl_certificate_key www.example.com.key;
    ...
}

如果順序錯了,nignix就不能啓動,顯示如下信息:

SSL_CTX_use_PrivateKey_file(" ... /www.example.com.key") failed
   (SSL: error:0B080074:x509 certificate routines:
    X509_check_private_key:key values mismatch)

確信服務器發送完全的證書鏈,使用openssl命令:

$ openssl s_client -connect www.godaddy.com:443
...
Certificate chain
 0 s:/C=US/ST=Arizona/L=Scottsdale/1.3.6.1.4.1.311.60.2.1.3=US
     /1.3.6.1.4.1.311.60.2.1.2=AZ/O=GoDaddy.com, Inc
     /OU=MIS Department/CN=www.GoDaddy.com
     /serialNumber=0796928-7/2.5.4.15=V1.0, Clause 5.(b)
   i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc.
     /OU=http://certificates.godaddy.com/repository
     /CN=Go Daddy Secure Certification Authority
     /serialNumber=07969287
 1 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc.
     /OU=http://certificates.godaddy.com/repository
     /CN=Go Daddy Secure Certification Authority
     /serialNumber=07969287
   i:/C=US/O=The Go Daddy Group, Inc.
     /OU=Go Daddy Class 2 Certification Authority
 2 s:/C=US/O=The Go Daddy Group, Inc.
     /OU=Go Daddy Class 2 Certification Authority
   i:/L=ValiCert Validation Network/O=ValiCert, Inc.
     /OU=ValiCert Class 2 Policy Validation Authority
     /CN=http://www.valicert.com//[email protected]
...

這個例子中www.godaddy.com對象(“s”)服務證書#0被一個發佈人(i)簽發,它自己的證書對象是#1,它的證書被證書是#2對象簽發。#2證書被衆所周知的發行人valicert公司簽發。他的證書被存儲在瀏覽器中。

如果證書鏈未被最加,僅有服務器證書#0被顯示。



單個http/https server

server {
    listen              80;
    listen              443 ssl;
    server_name         www.example.com;
    ssl_certificate     www.example.com.crt;
    ssl_certificate_key www.example.com.key;
    ...
}

基於名字的https server

server {
    listen          443 ssl;
    server_name     www.example.com;
    ssl_certificate www.example.com.crt;
    ...
}
server {
    listen          443 ssl;
    server_name     www.example.org;
    ssl_certificate www.example.org.crt;
    ...
}

這個配置中瀏覽器接受默認服務器證書。www.example.com不管請求的服務名。這是由於ssl proctol 腳本緣故。ssl 連接在瀏覽器發送http請求之前並且nginx不知道請求服務的名字。因此,它只可能提供默認服務證書。

解決這個問題最老的方法是制定單獨的ip爲每個https server

server {
    listen          192.168.1.1:443 ssl;
    server_name     www.example.com;
    ssl_certificate www.example.com.crt;
    ...
}
server {
    listen          192.168.1.2:443 ssl;
    server_name     www.example.org;
    ssl_certificate www.example.org.crt;
    ...
}


一個ssl證書和多個服務名

還有其他方法允許共享單個ip在多個https服務器之間。但是它們都有缺陷。

一個較好的方法是在配置文件中http level放置一個證書文件和他的私鑰文件,在所有服務中繼承它們單個內存拷貝。

ssl_certificate     common.crt;
ssl_certificate_key common.key;
server {
    listen          443 ssl;
    server_name     www.example.com;
    ...
}
server {
    listen          443 ssl;
    server_name     www.example.org;
    ...
}

服務名參考

一個更通用的在單個ip上運行多個https服務的方法是TLS Server NameIndication extension(SNI, RFC6066),它允許瀏覽器在握手期間傳遞一個請求服務名,因此,服務器知道要使用那個證書。當前只在下列瀏覽器中支持。

  • Opera 8.0;

  • MSIE 7.0 (but only on Windows Vista or higher);

  • Firefox 2.0 and other browsers using Mozilla Platform rv:1.8.1;

  • Safari 3.2.1 (Windows version supports SNI on Vista or higher);

  • and Chrome (Windows version supports SNI on Vista or higher, too).

使用sni,必須在nginxbuiltopenssl庫支持sni,同時在運行時動態鏈接。open ssl 0.9.8f已默認支持。使用下列命令查看nginx是否支持sni

$ nginx -V
...
TLS SNI support enabled
...

但是如果nginx動態鏈接到不支持sniopenssl會出現如下錯誤。

nginx was built with SNI support, however, now it is linked
dynamically to an OpenSSL library which has no tlsext support,
therefore SNI is not available


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