本文轉自:http://blog.csdn.net/na_tion/article/details/17527957javascript
nginx配置文件主要分爲六個區域:php
main section、events section、http section、sever section、location section、upstream section。css
main module:html
主要控制子進程的所屬用戶/用戶組、派生子進程數、錯誤日誌位置/級別、pid位置、子進程優先級、進程對應cpu、進程可以打開的文件描述符數目等。前端
user kingnet kingnet;
worker_processes 4;
error_log logs/error.log notice;
pid logs/nginx.pid;
# worker_priority -5;
# worker_cpu_affinity 0001 0010 0100 1000;
worker_rlimit_nofile 1024;
注:worker_cpu_affinity:指定進程對應cpu,上面配置是第一個進程對應cpu0,第二個進程對應cpu1,第三個進程對應cpu2,第四個進程對應cpu3,也能夠指定一個進程對應多個cpu。好比0101表示進程對應cpu0/cpu2。
worker_rlimit_nofile:指定每一個woker能夠打開的文件描述符數目,通常和worker_connections的值是相同的。
java
event module:控制nginx處理鏈接的方式。node
1234 events {
use epoll;
worker_connections 1024;
}
注:use:使用網絡IO模型,epoll模型比select模型效率高不少。
worker_connections:每一個worker可以處理的最大鏈接數,取決於ulimit -n的值。
nginx併發鏈接數:<worker_processes*worker_connections。
HTTP Access模塊提供了一個簡單的基於host名稱的訪問控制。經過該模塊,能夠容許或禁止指定的IP地址或IP地址段訪問某些虛擬主機或目錄
allow指令
語法:allow [address|CIDR|all]
使用環境:http,server,location
做用:容許指定的IP地址或IP地址段訪問某些虛擬主機或目錄
deny指令
語法:deny [address|CIDR|all]
使用環境:http,server,location
做用:禁止指定的IP地址或IP段訪問某些虛擬主機或目錄
匹配規則
控制規則按照聲明的順序進行檢查,首條匹配IP的訪問規則將被使用
演示用例
location / {
deny 192.168.1.1;
allow 192.168.1.0/24;
deny all;
}
解釋:
1.禁止192.168.1.1這個ip地址訪問
2.容許192.168.1.0/24這個地址段的ip訪問,可是因爲192.168.1.1首先匹配deny,所以192.168.1.1是沒法訪問的
3.當ip地址不匹配1,2兩條規則時,將禁止全部的ip地址訪問
http core主要用來控制處理客戶端的請求方式。
主要參數:
sendfile on;使用文件描述符拷貝數據,在內核狀態下完成
tcp_nopush on;在sendfile開啓時有效
keepalive_timeout 60; 長鏈接(一次鏈接能夠連續發送多個數據包)超時時間
tcp_nodelay on;在keepalive開啓時有效
client_body_buffer_size 128k; 指定鏈接請求實體的緩衝區大小
client_max_body_size 100m; 指定最大鏈接請求實體的大小
client_header_buffer_size 64k; 指定鏈接請求實體頭部的緩衝區大小
large_client_header_buffers 4 64k; 指定客戶端頭部比較大的使用緩衝區數量、大小
server_tokens off; 關閉nginx的版本信息
server_names_hash_max_size 1024; 名稱哈希表的最大值
linux
server_names_hash_bucket_size 256 名稱哈希表每一個頁面的大小nginx
注:依據/sys/devices/system/cpu/cpu0/cache/index1/size來決定hash表的大大小,通常是倍數關係。web
server_name參數:將http請求的主機頭與參數值匹配
域名遵循優先級規則:
完整匹配的名稱
名稱開始於一個文件通配符:*.example.com
名稱結束於一個文件通配符:www.example.*
使用正則表達式的名稱。
若是沒有匹配到,遵循下面優先級
listen指令標記爲default的server字段
第一個出現listen的server字段。
error_page參數:爲錯誤代碼指定相應的錯誤頁面
error_page 401 402 403 404 /40x.html;
若是出現40一、40二、40三、404錯誤則重定向到/40x.html頁面,這個頁面的位置須要結合匹配規則。
通常會爲錯誤頁面定義一個獨立的匹配規則,好比
location =/40x.html {
root html; #到html這個目錄尋找這個頁面
}
location參數:根據uri匹配。
語法規則: location [=|~|~*|^~] /uri/ { … }
= 開頭表示精確匹配
^~ 開頭表示uri以某個常規字符串開頭,理解爲匹配 url路徑便可。nginx不對url作編碼,所以請求爲/static/20%/aa,能夠被規則^~ /static/ /aa匹配到(注意是空格)。
~ 開頭表示區分大小寫的正則匹配
~* 開頭表示不區分大小寫的正則匹配
!~和!~*分別爲區分大小寫不匹配及不區分大小寫不匹配 的正則
/ 通用匹配,任何請求都會匹配到。
多個location配置的狀況下匹配順序爲(參考資料而來,還未實際驗證,試試就知道了,沒必要拘泥,僅供參考):
首先匹配 =,其次匹配^~, 其次是按文件中順序的正則匹配,最後是交給 / 通用匹配。當有匹配成功時候,中止匹配,按當前匹配規則處理請求。
例子,有以下匹配規則:
location = / {
#規則A
}
location = /login {
#規則B
}
location ^~ /static/ {
#規則C
}
location ~ \.(gif|jpg|png|js|css)$ {
#規則D
}
location ~* \.png$ {
#規則E
}
location !~ \.xhtml$ {
#規則F
}
location !~* \.xhtml$ {
#規則G
}
location / {
#規則H
}
那麼產生的效果以下:
訪問根目錄/, 好比http://localhost/ 將匹配規則A
訪問 http://localhost/login 將匹配規則B,http://localhost/register 則匹配規則H
訪問 http://localhost/static/a.html 將匹配規則C
訪問 http://localhost/a.gif, http://localhost/b.jpg 將匹配規則D和規則E,可是規則D順序優先,規則E不起做用,而 http://localhost/static/c.png 則優先匹配到規則C
訪問 http://localhost/a.PNG 則匹配規則E,而不會匹配規則D,由於規則E不區分大小寫。
訪問 http://localhost/a.xhtml 不會匹配規則F和規則G,http://localhost/a.XHTML不會匹配規則G,由於不區分大小寫。規則F,規則G屬於排除法,符合匹配規則可是不會匹配到,因此想一想看實際應用中哪裏會用到。
訪問 http://localhost/category/id/1111 則最終匹配到規則H,由於以上規則都不匹配,這個時候應該是nginx轉發請求給後端應用服務器,好比FastCGI(php),tomcat(jsp),nginx做爲方向代理服務器存在。
因此實際使用中,我的以爲至少有三個匹配規則定義,以下:
#直接匹配網站根,經過域名訪問網站首頁比較頻繁,使用這個會加速處理,官網如是說。
#這裏是直接轉發給後端應用服務器了,也能夠是一個靜態首頁
# 第一個必選規則
location = / {
proxy_pass http://tomcat:8080/index
}
# 第二個必選規則是處理靜態文件請求,這是nginx做爲http服務器的強項
# 有兩種配置模式,目錄匹配或後綴匹配,任選其一或搭配使用
location ^~ /static/ {
root /webroot/static/;
}
location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
root /webroot/res/;
}
#第三個規則就是通用規則,用來轉發動態請求到後端應用服務器
#非靜態文件請求就默認是動態請求,本身根據實際把握
#畢竟目前的一些框架的流行,帶.php,.jsp後綴的狀況不多了
location / {
proxy_pass http://tomcat:8080/
}
在nginx中配置proxy_pass時,若是是按照^~匹配路徑時,要注意proxy_pass後的url最後的/,當加上了/,至關因而絕對根路徑,則nginx不會把location中匹配的路徑部分代理走;若是沒有/,則會把匹配的路徑部分也給代理走。
location ^~ /static_js/
{
proxy_cache js_cache;
proxy_set_header Host js.test.com;
proxy_pass http://js.test.com/;
}
如上面的配置,若是請求的url是http://servername/static_js/test.html
會被代理成http://js.test.com/test.html
而若是這麼配置
location ^~ /static_js/
{
proxy_cache js_cache;
proxy_set_header Host js.test.com;
proxy_pass http://js.test.com;
}
則會被代理到http://js.test.com/static_js/test.htm
固然,咱們能夠用以下的rewrite來實現/的功能
location ^~ /static_js/
{
proxy_cache js_cache;
proxy_set_header Host js.test.com;
rewrite /static_js/(.+)$ /$1 break;
proxy_pass http://js.test.com;
}
一些可用的全局變量:
$args
$content_length
$content_type
$document_root
$document_uri
$host
$http_user_agent
$http_cookie
$limit_rate
$request_body_file
$request_method
$remote_addr
$remote_port
$remote_user
$request_filename
$request_uri
$query_string
$scheme
$server_protocol
$server_addr
$server_name
$server_port
$uri
例如:http://localhost:88/test1/test2/test.php
$host:localhost
$server_port:88
$request_uri:http://localhost:88/test1/test2/test.php
$document_uri:/test1/test2/test.php
$document_root:D:\nginx/html
$request_filename:D:\nginx/html/test1/test2/test.php
ReWrite語法
nginx的rewrite格式是:rewrite regex replacement flag
rewrite能夠放在server, location 和 if 模塊中。
nginx rewrite指令執行順序:
1.執行server塊的rewrite指令(這裏的塊指的是server關鍵字後{}包圍的區域,其它xx塊相似)
2.執行location匹配
3.執行選定的location中的rewrite指令
若是其中某步URI被重寫,則從新循環執行1-3,直到找到真實存在的文件
若是循環超過10次,則返回500 Internal Server Error錯誤
其中flag標記有四種格式:
last – 至關於Apache中的L
break – 停止Rewirte,不在繼續匹配
redirect – 返回臨時重定向的HTTP狀態302,至關於Apache中的R
permanent – 返回永久重定向的HTTP狀態301,至關於Apache中的R=301
一、下面是能夠用來判斷的表達式:
-f和!-f用來判斷是否存在文件
-d和!-d用來判斷是否存在目錄
-e和!-e用來判斷是否存在文件或目錄
-x和!-x用來判斷文件是否可執行
nginx 的 upstream目前支持 4 種方式的分配
1)、輪詢(默認)
每一個請求按時間順序逐一分配到不一樣的後端服務器,若是後端服務器down掉,能自動剔除。
2)、weight
指定輪詢概率,weight和訪問比率成正比,用於後端服務器性能不均的狀況,默認爲1。
2)、ip_hash
每一個請求按訪問ip的hash結果分配,這樣每一個訪客固定訪問一個後端服務器,能夠解決session的問題。
3)、fair(第三方)
按後端服務器的響應時間來分配請求,響應時間短的優先分配。
4)、url_hash(第三方): 按照url的hash結果來分配請求,使每一個url定向到同一個後端的服務器
在http節點裏添加:
#定義負載均衡設備的 Ip及設備狀態
upstream myServer {
server 127.0.0.1:9090 down;
server 127.0.0.1:8080 weight=2;
server 127.0.0.1:6060;
server 127.0.0.1:7070 backup;
}
#在須要使用負載的Server節點下添加
proxy_pass http://myServer;
#一個均衡服務器可配置多項,用空格隔開
upstream 每一個設備的狀態:
down 表示單前的server暫時不參與負載
weight 默認爲1.weight越大,負載的權重就越大。
max_fails :容許請求失敗的次數默認爲1.當超過最大次數時,返回proxy_next_upstream 模塊定義的錯誤
fail_timeout:max_fails 次失敗後,暫停的時間。
backup: 其它全部的非backup機器down或者忙的時候,請求backup機器。因此這臺機器壓力會最輕。
Nginx還支持多組的負載均衡,能夠配置多個upstream 來服務於不一樣的Server.
配置負載均衡比較簡單,可是最關鍵的一個問題是怎麼實現多臺服務器之間session的共享
下面有幾種方法(如下內容來源於網絡,第四種方法沒有實踐.)
1) 不使用session,換做cookie
若是程序邏輯不復雜,將session都改爲cookie
2) 應用服務器自行實現共享
能夠用數據庫或memcached來保存session,它的效率是不會很高的,不適用於對效率 要求高的場合。
3) ip_hash
nginx中的ip_hash技術可以將某個ip的請求定向到同一臺後端,這樣一來這個ip下的某個客戶端和某個後端就能創建起穩固的session,ip_hash是在upstream配置中定義的:
upstream backend {
server 127.0.0.1:8080 ;
server 127.0.0.1:9090 ;
ip_hash;
}
ip_hash是容易理解的,可是由於僅僅能用ip這個因子來分配後端,所以ip_hash是有缺陷的,不能在一些狀況下使用:
一、nginx不是最前端的服務器。ip_hash要求nginx必定是最前端的服務器,不然nginx得不到正確ip,就不能根據ip做hash。譬如使用的是squid爲最前端,那麼nginx取ip時只能獲得squid的服務器ip地址,用這個地址來做分流是確定錯亂的。
二、nginx的後端還有其它方式的負載均衡。假如nginx後端又有其它負載均衡,將請求又經過另外的方式分流了,那麼某個客戶端的請求確定不能定位到同一臺session應用服務器上。這麼算起來,nginx後端只能直接指向應用服務器,或者再搭一個squid,而後指向應用服務器。最好的辦法是用location做一次分流,將須要session的部分請求經過ip_hash分流,剩下的走其它後端去。
client_max_body_size 300m; //容許客戶端請求的最大的單個文件字節數
client_body_buffer_size 128k; //緩存區代理用戶端文件字節數
client_body_temp_path /dev/shm/client_body_temp; //請求試圖寫入到緩存文件的目錄路徑
proxy_connect_timeout600; //和後端服務器鏈接的超時時間,
proxy_read_timeout 600; //鏈接成功等待後端相應的時間,默認是60S
proxy_send_timeout 600; //後端服務器的回傳時間,規定服務器在必定的時間內傳送完。
proxy_buffer_size 16k; //代理服務器的緩存文件頭部文件大小,默認是4K
proxy_buffers 4 32k; //後端真是服務器的數量和大小
proxy_busy_buffers_size 64k; //當系統忙事,申請更大proxy_buffer
proxy_temp_file_write_size 64k; //寫入臨時目錄的文件大小
proxy_temp_path /dev/shm/proxy_temp; //指定一個目錄來緩存比較大的代理請求
proxy_pass http://cluster/; //指定須要代理的URL,
proxy_redirect off; //若是須要從後端打開location和Refresh字段,能夠開啓。 也就是說後端還有代理服務器時,須要打開
proxy_set_header X-Real-IP $remote_addr; //容許將發送到後端的服務器請求從新定義或者增長一個字段,這個能夠是變量也是文本組合。
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; //聯繫下面PS中所寫,在後端web中就算加上$http_x_Forwarded_for這條,也得不到用戶的IP,因此在 nginx反向代理添加Header頭信息 X-Forwarded-For在配合後端服務器日誌文件的$http_x_Forwarded_for這條就能夠得到用戶的IP地址了。
proxy_set_header Host $host; //首先說明 proxy_set_header 指令在向反向代理的後端Web服務器發起請求時添加指定的 Header頭信息,後端web服務器有多個基於 域名的虛擬主機時,經過頭信息Host,用於指定請求的域名,這樣後端web才能識別反向代理請求哪一個虛擬主機處理。
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503
http_504 http_404; 服務器頭部超時相應的各類狀態
例子:
upstream cluster {
server 192.168.100.238:80 weight=8 max_fails=2 fail_timeout=30s;
server 192.168.100.248:80 weight=8 max_fails=2 fail_timeout=30s;
}
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
...
nginx fastcgi和gzip模塊
fastcgi模塊:nginx協同fastcgi工做
fastcgi_connect_timeout 200;
fastcgi_send_timeout 200;
fastcgi_read_timeout 200;
fastcgi_buffer_size 4k;
fastcgi_buffers 16 4k;
fastcgi_busy_buffers_size 8k;
fastcgi_max_temp_file_size 16k;
fastcgi_intercept_errors on; php返回錯誤給nginx
說明:超時時間能夠設置的大一些,緩衝區大小也能夠設置大一些。
gzip模塊:數據壓縮傳輸
gzip on;
gzip_min_length 1k;
gzip_buffers 8 8k;
gzip_comp_level 2;
gzip_types text/plain application/x-javascript text/css application/xml;
gzip_vary on;
rewirite實例:
因爲rewrite執行效率比較低,一般用return語句替代,如:
rewrite (.*) http://www.example.org$1;
改成
retrun 301 https://www.example.org$request_uri;
Redirect語法
server {
listen 80;
server_name start.igrow.cn;
index index.html index.php;
root html;
if ($http_host !~ 「^star\.igrow\.cn$" {
rewrite ^(.*) http://star.igrow.cn$1 redirect;
}
}
防盜鏈
location ~* \.(gif|jpg|swf)$ {
valid_referers none blocked start.igrow.cn sta.igrow.cn;
if ($invalid_referer) {
rewrite ^/ http://$host/logo.png;
}
}
根據文件類型設置過時時間
location ~* \.(js|css|jpg|jpeg|gif|png|swf)$ {
if (-f $request_filename) {
expires 1h;
break;
}
}
禁止訪問某個目錄
location ~* \.(txt|doc)${
root /data/www/wwwroot/linuxtone/test;
deny all;
}
多目錄轉成參數abc.domian.com/sort/2 => abc.domian.com/index.php?act=sort&name=abc&id=2if ($host ~* (.*)\.domain\.com) {set $sub_name $1; rewrite ^/sort\/(\d+)\/?$ /index.php?act=sort&cid=$sub_name&id=$1 last;}目錄對換/123456/xxxx -> /xxxx?id=123456rewrite ^/(\d+)/(.+)/ /$2?id=$1 last;例以下面設定nginx在用戶使用ie的使用重定向到/nginx-ie目錄下:if ($http_user_agent ~ MSIE) {rewrite ^(.*)$ /nginx-ie/$1 break;}目錄自動加「/」if (-d $request_filename){rewrite ^/(.*)([^/])$ http://$host/$1$2/ permanent;}禁止htaccesslocation ~/\.ht { deny all; }禁止多個目錄location ~ ^/(cron|templates)/ { deny all;break; }禁止以/data開頭的文件能夠禁止/data/下多級目錄下.log.txt等請求;location ~ ^/data { deny all; }禁止單個目錄不能禁止.log.txt能請求location /searchword/cron/ { deny all; }禁止單個文件location ~ /data/sql/data.sql { deny all; }給favicon.ico和robots.txt設置過時時間;這裏爲favicon.ico爲99天,robots.txt爲7天並不記錄404錯誤日誌location ~(favicon.ico) { log_not_found off;expires 99d;break; } location ~(robots.txt) { log_not_found off;expires 7d;break; }設定某個文件的過時時間;這裏爲600秒,並不記錄訪問日誌location ^~ /html/scripts/loadhead_1.js { access_log off; root /opt/lampp/htdocs/web;expires 600;break; }文件反盜鏈並設置過時時間這裏的return 412 爲自定義的http狀態碼,默認爲403,方便找出正確的盜鏈的請求「rewrite ^/ http://leech.c1gstudio.com/leech.gif;」顯示一張防盜鏈圖片「access_log off;」不記錄訪問日誌,減輕壓力「expires 3d」全部文件3天的瀏覽器緩存location ~* ^.+\.(jpg|jpeg|gif|png|swf|rar|zip|css|js)$ {valid_referers none blocked *.c1gstudio.com *.c1gstudio.net localhost 208.97.167.194;if ($invalid_referer) { rewrite ^/ http://leech.c1gstudio.com/leech.gif; return 412; break;} access_log off; root /opt/lampp/htdocs/web;expires 3d;break; }只充許固定ip訪問網站,並加上密碼root /opt/htdocs/www;allow 208.97.167.194;allow 222.33.1.2;allow 231.152.49.4;deny all;auth_basic "C1G_ADMIN";auth_basic_user_file htpasswd;將多級目錄下的文件轉成一個文件,加強seo效果/job-123-456-789.html 指向/job/123/456/789.htmlrewrite ^/job-([0-9]+)-([0-9]+)-([0-9]+)\.html$ /job/$1/$2/jobshow_$3.html last;將根目錄下某個文件夾指向2級目錄如/shanghaijob/ 指向 /area/shanghai/若是你將last改爲permanent,那麼瀏覽器地址欄顯是/location/shanghai/rewrite ^/([0-9a-z]+)job/(.*)$ /area/$1/$2 last;上面例子有個問題是訪問/shanghai 時將不會匹配rewrite ^/([0-9a-z]+)job$ /area/$1/ last;rewrite ^/([0-9a-z]+)job/(.*)$ /area/$1/$2 last;這樣/shanghai 也能夠訪問了,但頁面中的相對連接沒法使用,如./list_1.html真實地址是/area/shanghia/list_1.html會變成/list_1.html,導至沒法訪問。那我加上自動跳轉也是不行咯(-d $request_filename)它有個條件是必需爲真實目錄,而個人rewrite不是的,因此沒有效果if (-d $request_filename){rewrite ^/(.*)([^/])$ http://$host/$1$2/ permanent;}知道緣由後就好辦了,讓我手動跳轉吧rewrite ^/([0-9a-z]+)job$ /$1job/ permanent;rewrite ^/([0-9a-z]+)job/(.*)$ /area/$1/$2 last;文件和目錄不存在的時候重定向:if (!-e $request_filename) {proxy_pass http://127.0.0.1;}域名跳轉server { listen 80; server_name jump.c1gstudio.com; index index.html index.htm index.php; root /opt/lampp/htdocs/www; rewrite ^/ http://www.c1gstudio.com/; access_log off; }多域名轉向server_name www.c1gstudio.com www.c1gstudio.net; index index.html index.htm index.php; root /opt/lampp/htdocs;if ($host ~ "c1gstudio\.net") {rewrite ^(.*) http://www.c1gstudio.com$1 permanent;}三級域名跳轉if ($http_host ~* "^(.*)\.i\.c1gstudio\.com$") {rewrite ^(.*) http://top.yingjiesheng.com$1;break;}域名鏡向server { listen 80; server_name mirror.c1gstudio.com; index index.html index.htm index.php; root /opt/lampp/htdocs/www; rewrite ^/(.*) http://www.c1gstudio.com/$1 last; access_log off; }某個子目錄做鏡向location ^~ /zhaopinhui { rewrite ^.+ http://zph.c1gstudio.com/ last; break; }