在經(jīng)典的框架和組件里,nginx無疑占有一席之地残制。作為高性能輕量級的反向代理web服務(wù)器立砸,其單機(jī)并發(fā)量可達(dá)3萬QPS
使用nginx的初衷,為了解決內(nèi)部網(wǎng)需要訪問外網(wǎng)初茶,但防火墻限制導(dǎo)致只能訪問指定ip颗祝,但外網(wǎng)比如頭條等為了安全使用域名+動態(tài)ip的方式,無法開放所有ip的訪問權(quán)限恼布。所以需要在外網(wǎng)部署服務(wù)對內(nèi)網(wǎng)的請求進(jìn)行轉(zhuǎn)發(fā)螺戳。
有2種方式:一、部署web服務(wù)進(jìn)行接收并訪問外網(wǎng)服務(wù)折汞;二倔幼、部署nginx應(yīng)用進(jìn)行代理轉(zhuǎn)發(fā),使用nginx的反向代理功能爽待。無疑使用nginx是最佳的嘗試损同。
本文介紹自己使用過程的接觸到的概念和配置,以及對Nginx真實部署時需要考慮問題的探究鸟款。
基本概念
應(yīng)用場景
靜態(tài)文件服務(wù)器
實現(xiàn)動靜分離
反向代理服務(wù)器
面向內(nèi)部服務(wù)器的代理膏燃,對外接收請求,轉(zhuǎn)到內(nèi)部服務(wù)器
負(fù)載均衡
內(nèi)置策略:
- 輪詢Round-Ribon/RR
- 加權(quán)輪詢 各節(jié)點(diǎn)硬件性能不一樣何什,可設(shè)置對應(yīng)的權(quán)重
- ip hash 基于ip hash算法组哩,對客戶端請求的ip進(jìn)行hash計算,然后根據(jù)hash結(jié)果將同一個客戶端ip的請求分發(fā)給同一臺服務(wù)器進(jìn)行處理;
- 能夠一定保持用戶的session禁炒,但免不了節(jié)點(diǎn)切換時的session失效【節(jié)點(diǎn)失效/超時重試機(jī)制】
- 但前提是nginx作為內(nèi)部服務(wù)器的直接轉(zhuǎn)發(fā)者
- hash算法的影響因素:機(jī)器權(quán)重而咆、是否存活、負(fù)載上限幕袱。對象:目標(biāo)散列調(diào)度(利用目標(biāo)IP)和源地址散列調(diào)度(利用源IP)
n = ServerNode[hashkey(dest_ip)];
if ( (n is dead) OR (W(n) == 0) OR (C(n) > 2*W(n))) then
return NULL;
return n; // 如果一切OK
注:S(n)是ServerNode列表中第n個服務(wù)器暴备,c(n)是負(fù)載上限;w(n)是該服務(wù)器的權(quán)重们豌;hashkey()為散列函數(shù)涯捻。在實現(xiàn)時,一般采用素數(shù)乘法Hash函數(shù)望迎,通過乘以素數(shù)使得散列鍵值盡可能地達(dá)到較均勻的分布障癌。
web緩存
對不同的文件作不同的緩存處理
正向代理服務(wù)器
適用resolver關(guān)鍵字代理客戶端的請求,但不能代理https的
nginx.conf配置文件
文件結(jié)構(gòu):
- 全局塊 允許生成worker processes數(shù)目等
- events塊 配置與用戶的網(wǎng)絡(luò)連接
- http塊 嵌套多個server
- upstream塊
- server塊
- location塊 配置請求的路由辩尊,及各頁面的處理情況
#worker_processes auto; #工作進(jìn)程數(shù):如果有SSL涛浙、gzip這些比較消耗CPU的工作可以設(shè)為和CPU的數(shù)量一樣;要處理很多很多的小文件,充分利用IO帶寬
#worker_cpu_affinity auto;
#worker_rlimit_nofile 200000; #更改worker進(jìn)程的最大打開文件數(shù)限制,不受ulimit-a的限制
error_log logs/error.log;
error_log logs/error.log notice;
error_log logs/error.log info;
events {
worker_connections 1024; #單個工作進(jìn)程可以允許同時建立外部連接的數(shù)量
use epoll; #設(shè)置用于復(fù)用客戶端線程的輪詢方法
multi_accept on; #告訴nginx收到一個新連接通知后接受盡可能多的連接
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'
'$request_time - $upstream_cache_status' ;
access_log logs/access.log main;
sendfile on; 可以在磁盤和TCP socket之間互相拷貝數(shù)據(jù)(或任意兩個文件描述符)
tcp_nopush on; 告訴nginx在一個數(shù)據(jù)包里發(fā)送所有頭文件摄欲,而不一個接一個的發(fā)送
tcp_nodelay on; 告訴nginx不要緩存數(shù)據(jù)轿亮,而是一段一段的發(fā)送--當(dāng)需要及時發(fā)送數(shù)據(jù)時,就應(yīng)該給應(yīng)用設(shè)置這個屬性
keepalive_timeout 30;
keepalive_requests 100;
reset_timedout_connection on;
client_body_timeout 40;
send_timeout 2;
#負(fù)載均衡列表及算法配置
upstream mysvr {
#ip_hash; #可以解決session不能跨服務(wù)器的問題
server xx.xxx.xxx.xx:8002 weight=100;
server xx.xxx.xxx.xx:8003 weight=10 max_fails=3 fail_timeout=30s;
server xx.xxx.xxx.xx:8004 down; #down表示當(dāng)前的server暫時不參與負(fù)載
server xx.xxx.xxx.xx:8005 backup; #backup其它所有的非backup機(jī)器down或者忙的時候胸墙,請求backup機(jī)器
#server 172.17.0.2:8124 ;
}
server {
keepalive_requests 120; #單連接請求上限次數(shù)我注。
listen 8767; #監(jiān)聽端口
server_name 127.0.0.1; #監(jiān)聽地址
location ~*^.+$ { #請求的url過濾,正則匹配迟隅,~為區(qū)分大小寫但骨,~*為不區(qū)分大小寫。
#root path; #根目錄
#index vv.txt; #設(shè)置默認(rèn)頁
#proxy_pass http://mysvr; #請求轉(zhuǎn)向mysvr 定義的服務(wù)器列表
# deny 127.0.0.1; #拒絕的ip
#allow 172.18.5.54; #允許的ip
}
location ~ ^~ /zhjrsl {
# proxy_pass http://xx.xxx.xxx.xx:8002; #代理智袭,訪問http://xx.xxx.xxx.xx:8764/zhjrsl/時會轉(zhuǎn)向http://xx.xxx.xxx.xx:8002/zhjrsl/
proxy_pass http://mysvr;
}
location /zipkin/ { #有沒有/都一樣
proxy_pass http://xx.xxx.xxx.xx:9411;
}
location /kibana {
#proxy_pass http://xx.xxx.xxx.xx:9202/app/kibana/; #有/時奔缠,則將kibana后面的路徑放到代理路徑后面
proxy_pass http://xx.xxx.xxx.xx:9202/app; #無/時,則將kibana后面的路徑+kibana放到代理路徑后面
}
location ~ ^\/zhjrsl\/* {
return 301 http://xx.xxx.xxx.xx:8002/zhjrsl/; #重定向
}
#兜底的
location / {
}
location /monitor{
check_status;
access_log off;
allow 10.189.110.30;
deny all;
}
}
include /etc/nginx/conf.d/*.conf;
}
ngnix中l(wèi)ocation與proxy_pass配置規(guī)則:
代理轉(zhuǎn)發(fā)主要用到的配置
- location配置用于匹配請求的URL补履,即ngnix中的$request_uri變量
- proxy_pass配置用于轉(zhuǎn)發(fā)URL
(location =) > (location 完整路徑) > (location ^~ 路徑) > (location ,* 正則順序) > (location 部分起始路徑) > (/)
location = /uri =開頭表示精確匹配添坊,只有完全匹配上才能生效。
location ^~ /uri ^~ 開頭對URL路徑進(jìn)行前綴匹配箫锤,并且在正則之前贬蛙。
location ~ pattern ~開頭表示區(qū)分大小寫的正則匹配。
location ~* pattern ~*開頭表示不區(qū)分大小寫的正則匹配谚攒。
location /uri 不帶任何修飾符阳准,也表示前綴匹配,但是在正則匹配之后馏臭,如果沒有正則命中野蝇,命中最長的規(guī)則讼稚。
location / 通用匹配,任何未匹配到其它location的請求都會匹配到绕沈,相當(dāng)于switch中的default
實際部署
Nginx的高可用性
高可用借助于主備節(jié)點(diǎn)和監(jiān)控切換
主流方案是Keepalived+Nginx實現(xiàn)雙機(jī)熱備
Keepalived是一個基于VRRP協(xié)議來實現(xiàn)的服務(wù)高可用方案锐想,可以利用其來避免IP單點(diǎn)故障,類似的工具還有heartbeat乍狐、corosync赠摇、pacemaker。但是它一般不會單獨(dú)出現(xiàn)浅蚪,而是與其它負(fù)載均衡技術(shù)(如lvs藕帜、haproxy、nginx)一起工作來達(dá)到集群的高可用惜傲。
部署分布式集群
每臺nginx都有公網(wǎng)地址洽故,利用DNS的負(fù)載均衡【在域名處設(shè)置同個域名多個指向,只能是最簡單輪詢算法】盗誊。但故障切換會慢时甚,且增加網(wǎng)絡(luò)開銷。
一臺公網(wǎng)nginx通過upstream功能哈踱,輪詢撞秋、ip、url多方式分發(fā)到內(nèi)網(wǎng)多臺nginx嚣鄙。但公網(wǎng)的nginx如果down機(jī)的話,內(nèi)網(wǎng)全斷
兩個公網(wǎng)nginx服務(wù)+三個公網(wǎng)ip【2個nginx的實際ip和1個虛擬ip/VIP】串结,通過keepalive+lvs實現(xiàn)高可用哑子,再upstream到內(nèi)網(wǎng)
如果并發(fā)量真的巨大的話,一般就要借助硬件F5等設(shè)備做負(fù)載均衡肌割,跟DNS卧蜓、CDN等服務(wù)商合作做域名解析轉(zhuǎn)發(fā)、緩存配置把敞,這也是目前大多數(shù)大廠的架構(gòu)配置
DNS做負(fù)載均衡
DNS(Domain Name System)是因特網(wǎng)的一項服務(wù)弥奸,它作為域名和IP地址相互映射的一個分布式數(shù)據(jù)庫,能夠使人更方便的訪問互聯(lián)網(wǎng)
同時許多DNS還支持基于地理位置的域名解析奋早,即會將域名解析成距離用戶地理最近的一個服務(wù)器地址盛霎,這樣就可以加速用戶訪問,改善性能
域名解析請求都會根據(jù)對應(yīng)的負(fù)載均衡算法計算出一個不同的IP地址并返回耽装,這樣A記錄中配置多個服務(wù)器就可以構(gòu)成一個集群愤炸,并可以實現(xiàn)負(fù)載均衡
www.apusapp.com IN A 114.100.20.201;
www.apusapp.com IN A 114.100.20.202;
www.apusapp.com IN A 114.100.20.203;
缺點(diǎn):
- DNS是多級解析,且每級緩存A記錄掉奄。當(dāng)A調(diào)整時规个,DNS未感知刷新完成,導(dǎo)致訪問A的請求失效
- DNS采用最簡單的RR負(fù)載均衡算法,不能滿足內(nèi)部服務(wù)動態(tài)調(diào)整
- 造成額外的網(wǎng)絡(luò)交互诞仓,為了在A調(diào)整時及時刷新各級DNS的緩存缤苫,設(shè)置DNS刷新時間小
大型網(wǎng)站總是部分使用DNS域名解析,利用域名解析作為第一級負(fù)載均衡手段墅拭,找到同樣提供負(fù)載均衡服務(wù)器的內(nèi)部服務(wù)器活玲,這組內(nèi)部負(fù)載均衡服務(wù)器再進(jìn)行負(fù)載均衡,請請求發(fā)到真實的服務(wù)器上帜矾,最終完成請求
虛擬IP
VIP翼虫,是一種不與特定計算機(jī)或者特定計算機(jī)網(wǎng)卡相對應(yīng)的IP地址。所有發(fā)往這個IP地址的數(shù)據(jù)包最后都會經(jīng)過真實的網(wǎng)卡到達(dá)目的主機(jī)的目的進(jìn)程
用來網(wǎng)絡(luò)地址轉(zhuǎn)換屡萤,提升網(wǎng)絡(luò)容錯和可移動性
虛擬IP常用于系統(tǒng)高可用性的場景珍剑,能夠自由漂浮
原理:當(dāng)虛擬IP漂浮后,刷新所有其他主機(jī)的arp緩存
CDN服務(wù)
...