目錄
- Nginx概述
- Nginx調(diào)度算法
- Nginx指令使用
- Nginx負(fù)載均衡配置參數(shù)
1. Nginx概述
Nginx是一個(gè)免費(fèi)的,開(kāi)源的,高性能的服務(wù)器和反向代理服務(wù)器軟件,同時(shí)它也可以為IMAP和POP3服務(wù)器代理,以其高性能,穩(wěn)定性,豐富的功能,結(jié)構(gòu)簡(jiǎn)單,低資源消耗的特性換來(lái)廣大運(yùn)維者所喜愛(ài)。
Nginx與傳統(tǒng)的服務(wù)器不同,不依賴線程來(lái)處理請(qǐng)求。相反,它使用一個(gè)更可擴(kuò)展事件驅(qū)動(dòng)架構(gòu)(異步)。這種結(jié)構(gòu)資源消耗較小,但更重要的是,可以承受較大的請(qǐng)求負(fù)荷。即使你不希望處理成千上萬(wàn)的請(qǐng)求,你仍然可以受益于Nginx的高性能和小的內(nèi)存占用,以及其豐富的功能。
1.1 Nginx的反向代理
反向代理指以代理服務(wù)器來(lái)接受Internet上的連接請(qǐng)求,然后將請(qǐng)求轉(zhuǎn)發(fā)給內(nèi)部網(wǎng)絡(luò)上的服務(wù)器,并將從服務(wù)器上得到的結(jié)果返回給Internet上請(qǐng)求連接到客戶端,此時(shí)代理服務(wù)器對(duì)外就表現(xiàn)為一個(gè)服務(wù)器,而此種工作模式類似于LVS-NET模型。
反向代理也可以理解為web服務(wù)器加速,它是一種通過(guò)在繁忙的web服務(wù)器和外部網(wǎng)絡(luò)之間增加的一個(gè)高速web緩沖服務(wù)器,用來(lái)降低實(shí)際的web服務(wù)器的負(fù)載的一種技術(shù)。反向代理是針對(duì)web服務(wù)器提高加速功能,所有外部網(wǎng)絡(luò)要訪問(wèn)服務(wù)器時(shí)的所有請(qǐng)求都要通過(guò)它,這樣反向代理服務(wù)器負(fù)責(zé)接收客戶端的請(qǐng)求,然后到源服務(wù)器上獲取內(nèi)容,把內(nèi)容返回給用戶,并把內(nèi)容保存在本地,以便日后再收到同樣的信息請(qǐng)求時(shí),它會(huì)將本地緩存里的內(nèi)容直接發(fā)給用戶,已減少后端web服務(wù)器的壓力,提高響應(yīng)速度。因此Nginx還具有緩存功能。
1.2 反向代理的工作流程
- 用戶通過(guò)域名發(fā)出訪問(wèn)請(qǐng)求,該域名被解析為反向代理服務(wù)器的IP地址;
- 反向代理服務(wù)器接收用戶的請(qǐng)求;
- 反向代理服務(wù)器在本地緩存查找是否存在當(dāng)前用戶所請(qǐng)求的內(nèi)容,找到則直接把內(nèi)容返回給用戶;
- 如果本地沒(méi)有用戶請(qǐng)求的內(nèi)容,反向代理服務(wù)器會(huì)以自己的身份去后端服務(wù)器請(qǐng)求同樣的信息內(nèi)容,并把信息內(nèi)容發(fā)給用戶,如果信息內(nèi)容是可以被緩存的,則會(huì)將該內(nèi)容緩存在代理服務(wù)器的本地緩存中。
1.3 反向代理的好處
- 解決了網(wǎng)站服務(wù)器對(duì)外可見(jiàn)的問(wèn)題,提高了網(wǎng)站服務(wù)器的安全性;
- 節(jié)約了有限的IP地址資源,后端服務(wù)器均可使用私有IP地址與代理服務(wù)器進(jìn)行通信;
- 加速了網(wǎng)站的訪問(wèn)速度,減輕了真是web服務(wù)器的負(fù)荷。
2. Nginx調(diào)度算法
Nginx的upstream指令用于指定proxy_pass和fastcgi_pass所使用的后端服務(wù)器,即nginx的反向代理功能,因此可以將兩者結(jié)合起來(lái)使用以達(dá)到負(fù)載均衡的目的,而Nginx也支持多種調(diào)度算法:
2.1 輪詢(默認(rèn))
每個(gè)請(qǐng)求按時(shí)間順序逐一分配到不同的后端服務(wù)器,如果后端服務(wù)器down掉,則會(huì)跳過(guò)該服務(wù)器分配至下一個(gè)監(jiān)控的服務(wù)器。并且它無(wú)需記錄當(dāng)前所有連接的狀態(tài),所以它是一種無(wú)狀態(tài)調(diào)度。
2.2 Weight
指定在輪詢的基礎(chǔ)上加上權(quán)重,weight和訪問(wèn)比率成正比,即用于表明后端服務(wù)器的性能好壞,若后端服務(wù)器性能較好則可將大部分請(qǐng)求分配給它,已實(shí)現(xiàn)其力所能及。
例如:
我后端服務(wù)器172.23.136.148配置:E5520*2 CPU,8G內(nèi)存
后端服務(wù)器172.23.136.148配置:Xeon(TM)2.80GHz * 2,4G內(nèi)存
我希望在有30個(gè)請(qǐng)求到達(dá)前端時(shí),其中20個(gè)請(qǐng)求交給172.23.136.148處理,剩余10個(gè)請(qǐng)求交給172.23.136.149處理,就可做如下配置:
upstream web_poll {
server 172.23.136.148 weight=10;
server 172.23.136.149 weight=5;
}
2.3 ip_hash
每個(gè)請(qǐng)求按訪問(wèn)ip的hash結(jié)果分配,當(dāng)新的請(qǐng)求到達(dá)時(shí),先將其客戶端IP通過(guò)哈希算法進(jìn)行哈希出一個(gè)值,在隨后的請(qǐng)求客戶端IP的哈希值只要相同,就會(huì)被分配至同一個(gè)后端服務(wù)器,該調(diào)度算法可以解決session的問(wèn)題,但有時(shí)會(huì)導(dǎo)致分配不均即無(wú)法保證負(fù)載均衡。
例如:
upstream web_pool {
ip_hash;
server 172.23.136.148:80;
server 172.23.136.149:80;
}
2.4 fair(第三方)
按后端服務(wù)器的響應(yīng)時(shí)間來(lái)分配請(qǐng)求,響應(yīng)時(shí)間短的優(yōu)先分配。
upstream web_pool {
server 172.23.136.148;
server 172.23.136.149;
fair;
}
2.5 url_hash(第三方)
按訪問(wèn)url的hash結(jié)果來(lái)分配請(qǐng)求,使每個(gè)url定向到同一個(gè)后端服務(wù)器,后端服務(wù)器為緩存時(shí)比較有效。
例:在upstream中加入hash語(yǔ)句,server語(yǔ)句中不能寫入weight等其他的參數(shù),hash_method是使用的hash算法
upstream web_pool {
server squid1:3128;
server squid2:3128;
hash $request_uri;
hash_method crc32;
}
每個(gè)設(shè)備的狀態(tài)設(shè)置為:
- down 表示當(dāng)前的server不參與負(fù)載,用于ip_hash中
- weight 默認(rèn)為1.weight越大,負(fù)載的權(quán)重就越大。
- max_fails 允許請(qǐng)求失敗的次數(shù)默認(rèn)為1.設(shè)為0則表示關(guān)閉該項(xiàng)功能,當(dāng)超過(guò)最大次數(shù)時(shí),返回proxy_next_upstream 模塊定義的錯(cuò)誤
- fail_timeout 在max_fails定義的失敗次數(shù)后,暫停的時(shí)間。
- backup 可以將其理解為備機(jī),其它所有的非backup機(jī)器down或者忙的時(shí)候,才會(huì)將請(qǐng)求分配給backup機(jī)器。所以這臺(tái)機(jī)器壓力會(huì)最輕。
nginx支持同時(shí)設(shè)置多組的負(fù)載均衡,用來(lái)給不用的server來(lái)使用。
3. Nginx指令使用
1. upstream
聲明一組可以被proxy_pass和fastcgi_pass引用的服務(wù)器;這些服務(wù)器可以使用不同的端口,并且也可以使用Unix Socket;也可以為服務(wù)器指定不同的權(quán)重。如:
upstream web_pool {
server coolinuz.9966.org weight=5;
server 172.23.136.148:8080 max_fails=3 fail_timeout=30s;
server unix:/tmp/backend3;
}
2. server
語(yǔ)法:server name [parameters]
其中的name可以是FQDN,主機(jī)地址,端口或unix套接字;如果FQDN解析的結(jié)果為多個(gè)地址,則每個(gè)地址都會(huì)被用到。
3. proxy_pass
語(yǔ)法:proxy_pass URL;
該指令用于指定代理服務(wù)器的地址和URL將被映射為的URL或地址和端口。即用來(lái)指定后端服務(wù)器的地址或URL[端口]。
4. proxy_set_header
語(yǔ)法:proxy_set_header header value;
該指令允許重新定義和添加一些將被轉(zhuǎn)移到被代理服務(wù)器的請(qǐng)求頭部信息。
例如:
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
注意:$proxy_add_x_forwarded_for包含客戶端請(qǐng)求頭中的"X-Forwarded-For",與$remote_addr用逗號(hào)分開(kāi),如果沒(méi)有"X-Forwarded-For" 請(qǐng)求頭,則$proxy_add_x_forwarded_for等于$remote_addr
5. proxy_read_timeout
語(yǔ)法:proxy_read_timeout time;
這個(gè)指令設(shè)置Nginx與后端服務(wù)器建立連接后。等待后端服務(wù)器的響應(yīng)時(shí)間
6. proxy_send_timeout
語(yǔ)法:roxy_send_timeout time;
該指令指定請(qǐng)求轉(zhuǎn)移到后端服務(wù)器的超時(shí)時(shí)間。整個(gè)傳輸?shù)囊髸r(shí)間不超過(guò)超時(shí)時(shí)間,但只有兩次寫操作之間。如果在此時(shí)間之后的后端服務(wù)器將不采取新的數(shù)據(jù),然后nginx將關(guān)閉連接。
7. proxy_connect_timeout
語(yǔ)法:proxy_connect_timeout time;
該指令用來(lái)設(shè)置分配到后端服務(wù)器的連接超時(shí)時(shí)間。
8. proxy_buffers
語(yǔ)法: proxy_buffers the_number is_size;
該指令設(shè)置緩沖區(qū)的數(shù)目和大小,缺省情況下,一個(gè)緩沖區(qū)的大小和頁(yè)面大小相同。
9. proxy_buffer_size
語(yǔ)法:proxy_buffer_size buffer_size;
代理緩沖區(qū),該指令用于保存用用戶的頭部信息。
10. proxy_busy_buffers_size
語(yǔ)法:proxy_busy_buffers_size size;
用于當(dāng)系統(tǒng)負(fù)載較大,緩沖區(qū)不夠用時(shí),可以申請(qǐng)更大的proxy_buffers
11. proxy_temp_file_write_size
語(yǔ)法:proxy_temp_file_write_size size;
用于指定緩存臨時(shí)文件的大小
4. Nginx負(fù)載均衡配置參數(shù)
#設(shè)定http服務(wù)器,利用它的反向代理功能提供負(fù)載均衡支持
http {
#設(shè)定mime類型,類型由mime.type文件定義
include /etc/nginx/mime.types;
default_type application/octet-stream;
#設(shè)定日志格式
access_log /var/log/nginx/access.log;
#省略上文有的一些配置節(jié)點(diǎn)
#... ... ...
#設(shè)定負(fù)載均衡的服務(wù)器列表
upstream mysvr {
#weigth參數(shù)表示權(quán)值,權(quán)值越高被分配到的幾率越大
server 192.168.8.1x:3128 weight=5;
#本機(jī)上的Squid開(kāi)啟3128端口,不是必須要squid
server 192.168.8.2x:80 weight=1;
server 192.168.8.3x:80 weight=6;
}
upstream mysvr2 {
#weigth參數(shù)表示權(quán)值,權(quán)值越高被分配到的幾率越大
server 192.168.8.x:80 weight=1;
server 192.168.8.x:80 weight=6;
}
#第一個(gè)虛擬服務(wù)器
server {
#偵聽(tīng)192.168.8.x的80端口
listen 80;
server_name 192.168.8.x;
#對(duì)aspx后綴的進(jìn)行負(fù)載均衡請(qǐng)求
location ~ .*.aspx$ {
#定義服務(wù)器的默認(rèn)網(wǎng)站根目錄位置
root /root;
#定義首頁(yè)索引文件的名稱
index index.php index.html index.htm;
#請(qǐng)求轉(zhuǎn)向mysvr 定義的服務(wù)器列表
proxy_pass http://mysvr ;
#以下是一些反向代理的配置可刪除.
proxy_redirect off;
#后端的Web服務(wù)器可以通過(guò)X-Forwarded-For獲取用戶真實(shí)IP
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#允許客戶端請(qǐng)求的最大單文件字節(jié)數(shù)
client_max_body_size 10m;
#緩沖區(qū)代理緩沖用戶端請(qǐng)求的最大字節(jié)數(shù),
client_body_buffer_size 128k;
#nginx跟后端服務(wù)器連接超時(shí)時(shí)間(代理連接超時(shí))
proxy_connect_timeout 90;
#連接成功后,后端服務(wù)器響應(yīng)時(shí)間(代理接收超時(shí))
proxy_read_timeout 90;
#設(shè)置代理服務(wù)器(nginx)保存用戶頭信息的緩沖區(qū)大小
proxy_buffer_size 4k;
#proxy_buffers緩沖區(qū),網(wǎng)頁(yè)平均在32k以下的話,這樣設(shè)置
proxy_buffers 4 32k;
#高負(fù)荷下緩沖大小(proxy_buffers*2)
proxy_busy_buffers_size 64k;
#設(shè)定緩存文件夾大小,大于這個(gè)值,將從upstream服務(wù)器傳
proxy_temp_file_write_size 64k;
}
}
}
附1. Nginx的內(nèi)置變量
- $args, 請(qǐng)求中的參數(shù);
- $is_args, 如果已經(jīng)設(shè)置$args,則該變量的值為“?”,否則為“”。
- $content_length, HTTP請(qǐng)求信息頭里的"Content-Length";
- $content_type, 請(qǐng)求信息頭里的"Content-Type";
- $document_root, 針對(duì)當(dāng)前請(qǐng)求所屬的root指令設(shè)置的根目錄路徑;
- $document_uri, 與$uri相同;
- $host, 請(qǐng)求信息中的"Host",如果請(qǐng)求中沒(méi)有Host行,則等于設(shè)置的服務(wù)器名;
- $limit_rate, 對(duì)連接速率的限制;
- $request_method, 請(qǐng)求的方法,比如"GET"、"POST"等;
- $remote_addr, 客戶端地址;
- $remote_port, 客戶端端口號(hào);
- $remote_user, 客戶端用戶名,認(rèn)證用;
- $request_filename, 當(dāng)前請(qǐng)求的文件路徑名
- $request_body_file, 客戶端請(qǐng)求主體的臨時(shí)文件名。
- $request_uri, 請(qǐng)求的URI,帶參數(shù);
- $query_string, 與$args相同;
- $scheme, 所用的協(xié)議,比如http或者是https,比如rewrite ^(.+)$ $scheme://example.com$1 redirect;
- $server_protocol, 請(qǐng)求的協(xié)議版本,"HTTP/1.0"或"HTTP/1.1";
- $server_addr,服務(wù)器地址,如果沒(méi)有用listen指明服務(wù)器地址,使用這個(gè)變量將發(fā)起一次系統(tǒng)調(diào)用以取得地址(造成資源浪費(fèi));
- $server_name, 請(qǐng)求到達(dá)的服務(wù)器名;
- $server_port, 請(qǐng)求到達(dá)的服務(wù)器端口號(hào);
- $uri, 請(qǐng)求的URI,可能和最初的值有不同,比如經(jīng)過(guò)重定向之類的。
附2. 正則表達(dá)式匹配
- ~ 為區(qū)分大小寫匹配
- ~* 為不區(qū)分大小寫匹配
- !~和!~*分別為區(qū)分大小寫不匹配及不區(qū)分大小寫不匹配
附3. 文件及目錄匹配
- -f和!-f用來(lái)判斷是否存在文件
- -d和!-d用來(lái)判斷是否存在目錄
- -e和!-e用來(lái)判斷是否存在文件或目錄
- -x和!-x用來(lái)判斷文件是否可執(zhí)行
附4. flag標(biāo)記
- last 相當(dāng)于Apache里的[L]標(biāo)記,表示完成rewrite
- break 終止匹配, 不再匹配后面的規(guī)則
- redirect 返回302臨時(shí)重定向 地址欄會(huì)顯示跳轉(zhuǎn)后的地址
- permanent 返回301永久重定向 地址欄會(huì)顯示跳轉(zhuǎn)后的地址