- 默認啓動Nginx時,使用的配置文件是: 安裝路徑/conf/nginx.conf 文件可以在啓動nginx的時候,通過-c來指定要讀取的配置文件
- 常見的配置文件有如下幾個:
- nginx.conf:應用程序的基本配置文件
- mime.types:MIME類型關聯的擴展文件
- fastcgi.conf:與fastcgi相關的配置
- proxy.conf:與proxy相關的配置
- sites.conf:配置Nginx提供的網站,包括虛擬主機
- Nginx的進程結構
- 啓動Nginx的時候,會啓動一個Master進程,這個進程不處理任何客戶端的請求,主要用來產生worker進程,一個worker進程用來處理一個request。
- Nginx模塊分爲:核心模塊、事件模塊、標準Http模塊、可選Http模塊、郵件模塊、第三方模塊和補丁等
- Nginx基本模塊:所謂基本模塊,指的是Nginx默認的功能模塊,它們提供的指令,允許你使用定義Nginx基本功能的變量,在編譯的時候不能被禁用,包括:
- 核心模塊:基本功能和指令,如進程管理和安全
- 事件模塊:在Nginx內配置網絡使用的能力
- 配置模塊:提供包含機制常見的核心模塊指令,大部分都是放置在配置文件的頂部具體的指令,請參看nginx的官方文檔,非常詳細,參見:http://nginx.org/en/docs/ngx_core_module.html還有下面這個網站,也是非常不錯的:http://www.howtocn.org/nginx:directiveindex
- 常見的events模塊指令,大部分都是放置在配置文件的頂部具體的指令,在上面那個文檔裏面,命令的context爲events的就是events模塊指令,只能在events裏面使用,核心模塊指令,重點看看:error_log、include、pid、user、worker_cpu_affinity、worker_processes
error_log日誌有6個級別:debug|info|notice|warn|error|crit |
Nginx支持將不同的虛擬主機的日誌記錄在不同的地方,如下示例:
http{
error_log logs/http_error.log error;
server{
server_name one;
access_log logs/one_access.log;
error_log logs/one_error.log error;
}
server{
server_name two;
access_log logs/two_access.log;
error_log logs/two_error.log error;
}
}
注意:error_log off不是禁用日誌,而是創建一個名爲off的日誌,要禁用日誌,可以這麼寫:error_log/dev/null crit;
- Nginx的HTTP配置主要包括三個區塊,結構如下:
http { //這個是協議級別 include mime.types; application/octet-stream; default_type keepalive_timeout 65; gzip on; server { //這個是服務器級別 listen 80; localhost; server_name location / { //這個是請求級別 root index } html{ index.html index.htm; } }
- Nginx的HTTP核心模塊,包括大量的指令和變量,大都很重要,具體參見:
- http://nginx.org/en/docs/http/ngx_http_core_module.html
Location區段
- Location區段,通過指定模式來與客戶端請求的URI相匹配,基本語法如下:
location [=|~|~*|^~|@] pattern{……}
1:沒有修飾符 表示:必須以指定模式開始,如:
server {
server_name henry.com;
location /abc {
……
}
}
那麼,如下是對的:
http://henry.com/abc
http://henry.com/abc?p1=11&p2=22
http://henry.com/abc/
http://henry.com/abcde
2:= 表示:必須與指定的模式精確匹配,如:
server {
server_name henry.com;
location = /abc {
……
}
}
那麼,如下是對的:
http://henry.com/abc
http://henry.com/abc?p1=11&p2=22
如下是錯的:
http://henry.com/abc/
http://henry.com/abcde
3:~ 表示:指定的正則表達式要區分大小寫,如:
server {
server_name henry.com;
location ~ ^/abc$ {
……
}
}
那麼,如下是對的:
http://henry.com/abc
http://henry.com/abc?p1=11&p2=22
如下是錯的:
http://henry.com/ABC
http://henry.com/abc/
http://henry.com/abcde
4:~* 表示:指定的正則表達式不區分大小寫,如:
server {
server_name henry.com;
location ~* ^/abc$ {
……
}
}
那麼,如下是對的:
http://henry.com/abc
http://henry.com/ABC
http://henry.com/abc?p1=11&p2=22
如下是錯的:
http://henry.com/abc/
http://henry.com/abcde
5:^~ 類似於無修飾符的行爲,也是以指定模式開始,不同的是,如果模式匹配,那麼就停止搜索其他模式了。
6:@ :定義命名location區段,這些區段客戶段不能訪問,只可以由內部產生的請求來訪問,如try_files或error_page等
- 查找順序和優先級
- 帶有“=“的精確匹配優先
- 沒有修飾符的精確匹配
- 正則表達式按照他們在配置文件中定義的順序
- 帶有“^~”修飾符的,開頭匹配
- 帶有“~” 或“~*” 修飾符的,如果正則表達式與URI匹配
- 沒有修飾符的,如果指定字符串與URI開頭匹配
location = / {
# 只匹配 / 的查詢.
[ configuration A ]
}
location / {
# 匹配任何以 / 開始的查詢,但是正則表達式與一些較長的字符串將被首先匹配。
[ configuration B ]
}
location ^~ /images/ {
# 匹配任何以 /images/ 開始的查詢並且停止搜索,不檢查正則表達式。
[ configuration C ]
}
location ~* \.(gif|jpg|jpeg)$ {
# 匹配任何以gif, jpg, or jpeg結尾的文件,但是所有 /images/ 目錄的請求將在Configuration C中 處理。
[ configuration D ]
}
各請求的處理如下例:
- / → configuration A
- /documents/document.html → configuration B
- /images/1.gif → configuration C
- /documents/1.jpg → configuration D
- Nginx通常被用作後端服務器的反向代理,這樣就可以很方便的實現動靜分離,以及負載均衡,從而大大提高服務器的處理能力。Http Proxy模塊,功能很多,最常用的是proxy_pass,最好還是都看看。
- 如果要使用proxy_cache的話,需要集成第三方的ngx_cache_purge模塊,用來清除指定的URL緩存。這個集成需要在安裝nginx的時候去做,形如:./configure --add-module=../ngx_cache_purge-1.0 ……
動靜分離
- Nginx實現動靜分離,其實就是在反向代理的時候,如果是靜態資源,那麼就直
接從Nginx發佈的路徑去讀取,而不需要從後臺服務器獲取了。
- 但是要注意:這種情況下需要保證後端跟前端的程序保持一致,可以使用Rsync
做服務端自動同步或者使用NFS、MFS分佈式共享存儲
負載均衡
- Nginx通過upstream模塊來實現簡單的負載均衡
- 在upstream塊內,定義一個服務器列表,默認的方式是輪詢,如果要確定同一個訪問者發出的請求總是由同一個後端服務器來處理,可以設置ip_hash,如:
upstream cctest1.com {
ip_hash
server 127.0.0.1:9080 weight=5;
server 127.0.0.1:8080 weight=5;
server 127.0.0.1:1111;
}
請注意:這個方法本質還是輪詢,而且由於客戶端的ip可能是不斷變化的,比如動態ip,代理,翻牆等等,因此ip_hash並不能完全保證同一個客戶端總是由同一個服務器來處理。
- 更多指令和配置,請參考Nginx的http負載均衡模塊
Geo和GeoIP模塊
- 這兩個模塊主要用於做全局的負載均衡,可以根據不同的客戶端ip來訪問不同的服務器,示例如下:
http{
geo $geo{
default default;
202.103.10.1/24 A;
179.9.0.3/24 B;
upstream default.server{
server 192.168.0.100;
}
upstream A.server{
server 192.168.0.101;
}
upstream B.server{
server 192.168.0.102;
}
server{
listen 80;
location / {
proxy_pass http://$geo.server$request_uri;
}
}
}
Rewrite模塊配置
- Rewrite模塊:用來執行URL重定向。這個機制有利於去掉惡意訪問的url,也有利於搜索引擎優化(SEO)。
- Nginx使用的語法源於Perl兼容正則表達式(PCRE)庫,基本語法如下:
- ^ :必須以^後的實體開頭
- $ :必須以$前的實體結尾
- . :匹配任意字符
- [ ] :匹配指定字符集內的任意字符
- [^ ] :匹配任何不包括在指定字符集內的任意字符串
- | :匹配 | 之前或之後的實體
- () :分組,組成一組用於匹配的實體,通常會有|來協助
- 捕獲子表達式,可以捕獲放在()之間的任何文本,比如:
- ^(.*)(hello|sir)$ 字符串爲“hi sir” 捕獲的結果: $1=hi $2=sir這些被捕獲的數據,在後面就可以當變量一樣使用了
- 內部請求
- 外部請求是客戶端的url,內部請求是Nginx通過特殊的指令觸發。比如:error_page、index、rewrite、try_files、include等等
- 內部請求分成兩種類型
- 內部重定向:URI被改變,可能會匹配到其他的Location
- 子請求:比如使用Addition模塊,指令add_after_body允許你在原始的URI之後指定一個URI,會把該URI被處理後的結果,插入到原始的URI的body中。
- 內部重定向示例:
server {
server_name herny.com;
location /abc/ {
rewrite ^/abc/(.*)$ /bcd/$1
}
location /bcd/{
internal;
root pages;
}
}
n 條件結構的基本語法:
1:沒有操作符:指定的字符串或者變量不爲空,也不爲0開始的字符串,取true
2:= , != ,例:if($request_method = POST){…}
3:~,~*,!~,!~* ,例:if($uri ~* “\.jsp$”){…}
4:-f,!-f :用來測試指定文件是否存在,例:if(-f $request_filename){…}
5:-d,!-d :用來測試指定目錄是否存在
6:-e,!-e:用來測試指定文件、目錄或者符號鏈接是否存在
7:-x,!-x:用來測試指定文件是否存在和是否可以執行
8:break:跳出if塊
9:return:終止處理,並返回一個指定的http狀態碼
10:set:初始化或者重定義一個變量
- Http Index模塊,都看看
- Http Referer模塊,都看看,可用於防盜鏈
- Http Limit Zone模塊,都看看,可用於會話的連接數控制,如限制每個IP的併發連接數等
- Http Access模塊,用於簡單的訪問控制,都看看
- Http Charset模塊,重點看看:charset
- Gzip模塊,可以都看看
- Http Browser模塊,用於按照請求頭中的“User-agent”來創建一些變量,好爲不同的瀏覽器創建不同的內容,暫時瞭解即可
- Memcached模塊,這是把Nginx當作Memcached的客戶端,用來連接Memcached的模塊。暫時不用看
- Http Addition模塊,可以在當前location內容之前或後添加內容,暫時不用看
- Http Empty Gif模塊,這個模塊在內存中保存一個能夠很快傳遞的1×1透明GIF,暫時不用看
- Http Auth Basic模塊,基於Http Basic認證的方式來保護虛擬主機或目錄,暫時不用看
- Http AutoIndex模塊,用於提供自動目錄列表,該模塊只有在找不到默認的index文件的時候才啓用,暫時不用看
- Http Fcgi模塊,用於與FastCGI進程交互,暫時不用看
- FLV Stream模塊,支持當Http下載方式播放Flv時,可以支持進度條拖放,暫時不用看。
- SSL模塊,暫時不用看
- 郵件模塊,暫時不用看
- 還有很多的模塊,這裏就不再一一介紹了
- server配置爲監聽ip和端口
server{
listen 127.0.0.1:9080;
server_name 127.0.0.1;
}
server配置爲監聽域名和端口
server{
listen 80;
server_name www.henry.com henry.com *.henry.com;
}
向後臺服務器傳遞客戶端的真實ip
location ~ \.(jsp|action|mvc)$ {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://henry.com;
}
- 在負載均衡裏面,實現後端服務器故障轉移的配置
location ~ \.(jsp|action|mvc)$ {
proxy_next_upstream http_502 http_504 timeout;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://server_pool;
}
- 簡單的防盜鏈
location / {
……
valid_referers blocked henry.com *.henry.com;
if($invalid_referer){
rewrite ^/ http://henry.com;
}
}
- 簡單的限制下載速度
location / {
limit_rate 256K;
使用proxy_cache的配置
http{#下面這兩個path指定的路徑必須在同一個分區
proxy_temp_path /cachetemp/proxy_temp_path;
#設置名稱爲mycache,內存緩存100m,自動清除1天未使用的內容,硬盤緩存空間1g
proxy_cache_path /cachetemp/proxy_cache_path levels=1:2 keys_zone=mycache:100m
inactive=1d max_size=1g;
server{
location ~ .*\.(gif|jpg|html|js|css)$ {
proxy_cache mycache; #使用名稱爲mycache的緩存
#對不同的Http狀態碼設置不同的緩存時間
proxy_cache_valid 200 304 24h;
proxy_cache_valid 301 302 10m;
proxy_cache_valid any 1m;
#設置緩存的key值
proxy_cache_key $host$uri$is_args$args;
}
}
}
Nginx的配置優化
如果沒有足夠的實力和必要去自己改寫Nginx,那麼Nginx的優化主要就是:優化Nginx的配置,做到合理高效的使用
- 優化的方向和目標,無外乎:
- 儘量提高單臺機器處理效率
- 儘量降低單臺機器的負載
- 儘量降低磁盤I/O
- 儘量降低網絡I/O
- 儘量減少內存使用
- 儘量高效利用CPU
- 生產環境下,應該使Nginx模塊最小化,就是用到哪幾個就開哪幾個,這個需要在編譯安裝Nginx的時候做。用戶和組,生產環境下,最好是專爲Nginx創建用戶和組,並單獨設置權限,這樣會更安全。例如: user nginx nginx
- worker_processes :通常配置成cpu的總核數,或者其2倍,性能會更好。這可以減少進程間切換帶來的消耗。
- 還可以同時使用worker_cpu_affinity來綁定cpu,使得每個worker進程獨享一個cpu,實現完全的併發,性能更好,不過這個只對linux系統有效。
- events裏面的事件模型,Linux推薦使用epoll模型,FreeBSD推薦採用kqueue
- worker_rlimit_nofile:描述一個nginx進程打開的最多的文件數目。配置成跟linux內核下文件打開數一致就可以了。可以通過ulimit -n 來查看,新裝的系統默認是1024,CentOS中可以如下方式進行修改:在/etc/security/limits.conf最後增加:
- * soft nofile 65535
- * hard nofile 65535
- * soft nproc 65535
- * hard nproc 65535
- worker_connections:每個進程允許的最多連接數,默認是1024,可以設置大一些。理論上併發總數是worker_processes和worker_connections的乘積,
- worker_connections值的設置跟物理內存大小有關,因爲系統可以打開的最大文件數和內存大小成正比,一般1GB內存的機器上可以打開的文件數大約是10萬左右,所以,
- worker_connections 的值需根據 worker_processes 進程數目和系統可以打開的最大文件總數進行適當地進行設置。
- keepalive_timeout:設置到65左右就可以
- client_header_buffer_size:設置請求的緩存,設置爲4k,通常爲系統分頁大小的整數倍,可以通過getconf PAGESIZE 來查看系統分頁大小。
- 對打開文件設置緩存
- open_file_cache max=建議設置成和每個進程打開的最大文件數一致 inactive=60s;
- open_file_cache_valid 90s;
- open_file_cache_min_uses 2;
- open_file_cache_errors on;
- 儘量開啓Gzip壓縮,gzip_comp_level通常設置成3-5,高了浪費CPU
- Error日誌優化:運行期間設置爲crit,可以減少I/O
- access日誌優化:如果使用了其他統計軟件,可以關閉日誌,來減少磁盤寫,或者寫入內存文件,提高I/O效率。
- sendfile指令指定 nginx 是否調用 sendfile 函數(zero copy 方式)來輸出文件,通常應設置成on,如果是下載等應用磁盤IO重負載應用,可設置爲 off
- Buffers size優化:如果buffer size太小就會到導致nginx使用臨時文件存儲response,這會引起磁盤讀寫IO,流量越大問題越明顯。
- client_body_buffer_size 處理客戶端請求體buffer大小。用來處理POST提交數據,上傳文件等。client_body_buffer_size 需要足夠大以容納需要上傳的POST數據。同理還有後端的buffer數據。
- worker_priority進程優先級設置:Linux系統中,優先級高的進程會佔用更多的系統資源,這裏配置的是進程的靜態優先級,取值範圍-20到+19,-20級別最高。因此可以把這個值設置小一點,但不建議比內核進程的值低(通常爲-5)
- 合理設置靜態資源的瀏覽器緩存時間,儘量用瀏覽器緩存
- 負載均衡鎖accept_mutex,建議開啓,默認就是開啓的
- 如果使用SSL的話,而且服務器上有SSL硬件加速設備的話,請開啓硬件加速。