location的模式匹配按照優先級由低到高有以下四種:
1:location = URI { }花括號在的規則只對當前URI匹配,如果爲目錄只對目錄匹配
2:location ^~URI { }不用正則表達式進行逐字符匹配
3:location ~* URI{ }不區分大小寫花括號在的規則對URI進行模式匹配,URI可以用正則表達式
location ~ URI { }區分大小寫花括號在的規則對URI進行模式匹配,URI可以用正則表達式
4:location URI { }花括號中的規則對URI中所有路徑包括子目錄都匹配
location URI { } 花括號中的規則對URI中所有路徑包括子目錄都匹配
如 location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
}
所有的以.php結尾的URI都有fastcgi轉發到本機的9000端口處理(php監聽在9000端口)
不用模式匹配的location定義
location /forum/ {
proxy_pass http://192.168.139.8:8080/bbs/;
}
如訪問www.baidu.com/forum/ 則相當於訪問後端的http://192.168.139.8:8080/bbs/
使用模式匹配定義location時,後面的http://路徑只能寫到端口處,不能出現URI
如 location ~* ^/forum {
proxy_pass http://192.168.139.8:8080;
}
不區分大小寫匹配所有以forum開頭的URI,轉發到 http://192.168.139.8:8080/forum
如訪問www.baidu.com/forum相當於訪問http://192.168.139.8:8080/forum
[root@node2 html]# vim /etc/nginx/nginx.conf
location /forum {
proxy_pass http://192.168.139.8/bbs;
}
[root@node2 html]# service nginx reload
[root@node4 bbs]# vim /var/www/html/bbs/index.html
<h1>Nginx on Backup</h1>
[root@node4 bbs]# service httpd restart
[root@node2 html]# vim /etc/nginx/nginx.conf
location ~ ^/hehe {
proxy_pass http://192.168.139.8;
}
[root@node2 html]# service nginx reload
[root@node4 bbs]# vim /var/www/html/hehe/index.html
<h1>This Backup Server</h1>
[root@node4 html]# service httpd restart
將所有的請求都轉發到後端192.168.139.8/bbs/
location / {
proxy_pass http://192.168.139.8/bbs;
}
通過分析後端server的日誌可以看到所有的訪問client_ip都是來自node2(node2只是個代理服務器,記錄他的ip不能進行client來源分析)沒有記錄真正的client_ip
[root@node4 bbs]# tail /var/log/httpd/access_log
192.168.139.4 - - [24/Dec/2016:18:05:59 +0800] "GET /hehe HTTP/1.0" 301 313 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36"
192.168.139.4 - - [24/Dec/2016:18:05:59 +0800] "GET /hehe/ HTTP/1.0" 200 28 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36"
日誌變量有:
$remote_addr client_ip
$remote_port client_port
$remote_user client_user (基於用戶認證時)
$request_body 請求主題
$request_method 請求方法
put get post delete options trace connection head
$server_addr server_ip
$server_port server_port
$server_name server_name
$server_protol http1.0/1.1
$uri 請求的正真uri
定義日誌記錄client來源
location ~ ^/hehe {
proxy_pass http://192.168.139.8;
proxy_set_header X-Real-IP $remote_ddr;
}
real-ip由前端代理服務器傳過來了,但也要改一下後端server的日誌記錄格式
[root@node4 html]# vim /etc/httpd/conf/httpd.conf
LogFormat "%{X-Real-IP}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
[root@node4 html]# service httpd restart
瀏覽器多訪問幾次 http://192.168.139.4/hehe/
[root@node4 html]# tail /var/log/httpd/access_log
192.168.139.1 - - [24/Dec/2016:18:23:28 +0800] "GET /hehe/ HTTP/1.0" 304 - "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36"
192.168.139.1 - - [24/Dec/2016:18:23:28 +0800] "GET /hehe/ HTTP/1.0" 304 - "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36"
192.168.139.1 - - [24/Dec/2016:18:23:28 +0800] "GET /hehe/ HTTP/1.0" 304 - "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36"
192.168.139.1 - - [24/Dec/2016:18:23:29 +0800] "GET /hehe/ HTTP/1.0" 304 - "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36"
可以看到client_ip 192.168.139.1(而不是node2的IP_192.168.139.4)
Nginx的upstream端定義:將多個server做成一個負載均衡的集羣,默認使用wrr調度算法(權重一樣則爲rr,權重爲0 ,則不加入集羣)
[root@node2 html]# vim /etc/nginx/nginx.conf
upstream my_web_server { #upstream在server外定義
my_web_server爲集羣名,要引用 server 192.168.139.8 weight=1;
server 192.168.139.9 weight=1;
}
location / {
root /web/html;
index index.html index.htm;
proxy_pass http://my_web_server/; #轉發到my_web_server集羣
proxy_set_header X-Real_IP $remote_addr;
}
[root@node2 html]# service nginx reload
刷新
upstream還可以爲後端server做健康狀態檢查,萬一兩個後端server都掛了,準備一個sorry頁面
[root@node2 html]# vim /etc/nginx/nginx.conf
upstream my_web_server {
server 192.168.139.8 weight=1 max_fails=2 fail_timeout=2 ;
server 192.168.139.9 weight=1 max_fails=2 fail_timeout=2 ;
server 127.0.0.1:8080 backup ;
}
server { listen 8080;
server_name localhost;
root /web/error;
index index.html;
}
[root@node2 html]# vim /web/error/index.html
<h1>Sorry......</h1>
[root@node2 html]# service nginx reload
[root@node4 html]# service httpd stop
[root@node5 html]# service httpd stop
[root@node4 html]# service httpd start
[root@node5 ~]# service httpd start
Nginx支持三種負載均衡的調度算法:
1:wrr(weight round robin 加權輪調) 如果權重相同則爲rr(輪調),每個請求按時間順序逐一分配到不同的後端服務器,如果後端某臺服務器宕機,故障系統被自動剔除,使用戶訪問不受影響。Weight 指定輪詢權值,Weight值越大,分配到的訪問機率越高,主要用於後端每個服務器性能不均的情況下
2:ip_hash (ip_哈希) server端會將client的訪問IP做一個哈希運算,並將結果保存在本地內存中的哈希表中,這樣對IP運算結果的相同的client會被始終分發給通一個後端RS_Server,從而不會出現client因爲訪問的是不同server造成的沒有session信息的問題(其實要根本解決session問題,還是要加一個共享存儲,比如那臺server掛了,這時client請求肯定會發給其他server,可以將session信息保存在memory cache中實現session共享)
3:least_conn (最小連接數)比較當前節點上活動連接數+非活動連接數,輸小給誰發,這是一種動態調度算法,如active*256+inactive
注:使用ip_hash時要將backup去掉,萬一定向到backup_server上,即使RS_Server恢復正常,也不會再給轉發
[root@node2 html]# vim /etc/nginx/nginx.conf
upstream my_web_server {
server 192.168.139.8 weight=1 max_fails=2 fail_timeout=2 ;
server 192.168.139.9 weight=1 max_fails=2 fail_timeout=2 ;
ip_hash;
}
[root@node2 html]# service nginx reload
一直刷新都是定向在node4
爲了減輕後端RS的壓力,Nginx應該啓用本地緩存,其緩存有兩種形式
1:在共享內存中,緩存鍵和緩存對象的元數據(主要用於在內存中查找數據)
2:在磁盤空間中,存儲數據(如靜態、或者經過靜態處理的動態數據)在磁盤中,爲了提高效率,可以用SSD作爲本地磁盤,且可以將多塊SSD做成一個Raid0,那速度老快了
根據請求方法進行緩存
proxy_cache_methods GET HEAD POST;#這三種請求方法的請求進行緩存
根據狀態碼進行緩存
proxy_cache_valid 200 302 10m ;#狀態碼爲200 302 的請求緩存10min
proxy_cache_valid 404 1m; #狀態碼爲200 的請求緩存1min
proxy_cache_valid any 5m; #其他的狀態碼緩存5min
根據相同請求的次數進行緩存
proxy_cache_min_uses 5; #只有當相同請求出現5次纔對其進行緩存
更詳細的緩存介紹請看官網 https://www.nginx.com/resources/admin-guide/content-caching/
proxy_cache_path ; 緩存的保存路徑,不能定義在server{ }段中
keys_zone=first:20m; 用來存儲鍵的區域名叫first,大小爲20M
max_size=1G ; 最多用1 G的內存進行緩存,如果緩存空間滿了,Nginx的cache_manager進程會根據最近最少連接原則進行緩存清除
[root@node2 html]# vim /etc/nginx/nginx.conf
upstream my_web_server {
server 192.168.139.8 weight=1 max_fails=2 fail_timeout=2 ;
server 192.168.139.9 weight=1 max_fails=2 fail_timeout=2 ;
ip_hash;
}
proxy_cache_path /nginx/cache/my_cache levels=1:2 keys_zone=first:20M;
server {
listen 80;
server_name localhost;
add_header X_cache "$upstream_cache_status from $server_addr"
配置文件時;前忘了加"結果一直 nginx: [emerg] unexpected end of file, expecting "}" in /etc/nginx/nginx.con,差點將整個文件刪了^_^
location / {
root /web/html;
index index.html index.htm;
proxy_pass http://my_web_server/;
proxy_set_header X-Real_IP $remote_addr;
proxy_cache first;
proxy_cache_valid 200 10m;
}
.......
}
[root@node2 html]# mkdir -pv /nginx/cache/my_cache
[root@node2 html]# service nginx reload
瀏覽器訪問:192.168.139.4 Ctrl+F5 強制刷新頁面,按F12鍵,彈出開發者頁面,點擊Network便可看到下面內容,在Response Headers段 HIT from 192.168.139.4 (從192.168.139.4命中)
Request URL:
http://192.168.139.4/
Request Method:
GET
Status Code:
304 Not Modified
Remote Address:
192.168.139.4:80
Response Headersview source
Connection:
keep-alive
Date:
Sat, 24 Dec 2016 12:31:37 GMT
ETag:
"dfea9-17-54411d5f3b69e"
Last-Modified:
Tue, 20 Dec 2016 07:17:58 GMT
Server:
nginx/1.10.2
X-cache:
HIT from 192.168.139.4
Request Headersview source
Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,p_w_picpath/webp,*/*;q=0.8
Accept-Encoding:
gzip, deflate, sdch
Accept-Language:
zh-CN,zh;q=0.8
Cache-Control:
max-age=0
Connection:
keep-alive
Host:
192.168.139.4
If-Modified-Since:
Tue, 20 Dec 2016 07:17:58 GMT
If-None-Match:
"dfea9-17-54411d5f3b69e"
Upgrade-Insecure-Requests:
1
User-Agent:
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36
刪除本地緩存再刷新一次
[root@node2 5b]# rm /nginx/cache/my_cache/b/5b/d0f1246dc67a25097fa3a295a393f5bb
Connection:
keep-alive
Date:
Sat, 24 Dec 2016 12:38:29 GMT
ETag:
"dfea9-17-54411d5f3b69e"
Last-Modified:
Tue, 20 Dec 2016 07:17:58 GMT
Server:
nginx/1.10.2
X-cache:
MISS from 192.168.139.4 #MISS代表緩存未命中
再刷新一次
Connection:
keep-alive
Date:
Sat, 24 Dec 2016 12:39:37 GMT
ETag:
"dfea9-17-54411d5f3b69e"
Last-Modified:
Tue, 20 Dec 2016 07:17:58 GMT
Server:
nginx/1.10.2
X-cache:
HIT from 192.168.139.4 #緩存又命中了
miss :緩存未命中
hit :緩存命中
expired : 緩存已過期
updating :緩存內容已經更新
stale : 緩存已經失效
除了以上緩存外,還有fastcgi_cache,可以緩存php腳本處理的結果,及php代碼編譯的opcode,但一般來說動態響應內容往往不一樣,只能講那些經常請求的動態資源進行緩存,這時可以根據最少相同訪問次數來設定緩存,fastcgi也有自己的緩存配置(將盡量多的動態資源進行靜態化,是一個好的大型站點必須做好的事)
open_log_cache: 還有日誌緩存
open_file_cache:將文件的元數據緩存再Nginx的內存中
對於一個大型站點來說,一個集羣組可能不能滿足其需求,這時就需要多個集羣組進行不同的分工處理不同的請求,可以採取如下操作解決
1:專門處理php動態請求的集羣
upstream php_servers {
server 192.168.139.11....;
server 192.168.139.12.....;
......
}
2:專門處理圖片請求的集羣
upstream img_servers {
server 192.168.139.20....;
server 192.168.139.21.....;
......
}
3:處理其他請求的集羣
upstream other_servers {
server 192.168.139.30....;
server 192.168.139.31.....;
......
}
定義location,根據URI進行匹配(記住location幾種模式匹配優先級奧^_^)
location / {
proxy_pass http://other_servers;
}
location ~* \.php$ {
fastcgi_pass http://img_servers;
}
location ~* "\.(jpg|gpeg|gif|png)$" {
proxy_pass http://php_server;
}