Nginx實現反向代理負載均衡功能
Nginx:本身支持反向代理、負載均衡功能,屬於L7層負載均衡。Nginx反向代理簡單易用,受到大部分中小企業的青睞。
LVS:支持L4層負載均衡,
haproxy:支持L4、L7層負載均衡
L4、L7是指OSI模型中的第四層和第七層;L4:TCP負載均衡;L7:http負載均衡
nginx、lvs、haproxy區別參考資料
https://www.cnblogs.com/ahang/p/5799065.html
https://www.cnblogs.com/like-minded/p/5157659.html
實現Nginx負載均衡的兩個主要模塊
Nginx得負載均衡是基於反向代理之上實現的。
ngx_http_proxy_module: proxy代理模塊,把請求後拋給服務器節點或upstream服務器池
具體語法可以參考官方文檔:
http://nginx.org/en/docs/http/ngx_http_proxy_module.html
http://nginx.org/en/docs/http/ngx_http_upstream_module.html
Nginx反向代理軟件安裝
Nginx反向代理軟件安裝即安裝Nginx軟件。下面是安裝Nginx自動化腳本
#系統環境 cat /etc/redhat-release uname -r uname -m #設置目錄環境 mkdir /home/Ricky/tools -p mkdir /application mkdir /server/scripts -p #安裝所需的庫 yum -y install pcre pcre-devel openssl-devel rpm -qa pcre pcre-devel openssl-devel #添加Nginx運行用戶 useradd -u 501 -s /sbin/nologin -M www id www mkdir /application/nginx-1.12.2 -p #安裝Nginx cd /home/Ricky/tools wget -q http://nginx.org/download/nginx-1.12.2.tar.gz tar xf nginx-1.12.2.tar.gz cd nginx-1.12.2 ./configure --prefix=/application/nginx-1.12.2/ --user=www --group=www --with-http_ssl_module --with-http_stub_status_module echo $? make echo $? make install echo $? ln -s /application/nginx-1.12.2/ /application/nginx #開機啟動 echo "/application/nginx/sbin/nginx" >>/etc/rc.local tail -1 /etc/rc.local
Nginx反向代理部署
#生成配置文件nginx.conf cd /application/nginx/conf/ egrep -v "#|^$" nginx.conf.default >nginx.conf #配置反向代理和upstream資源池 vim nginx.conf upstream www_server_pools { server 10.0.0.7:80 weight=1; server 10.0.0.8:80 weight=1;#weight權重相等,實現負載均衡,輪詢處理請求 } server { listen 80; server_name www.ricky.com; location / { root html; index index.html index.htm; proxy_pass http://www_server_pools;#把請求拋向upstream資源池,讓資源池的設備進行處理 proxy_set_header Host $host;#自定義http包的header的host字段,讓代理服務器使用用戶的host去訪問web服務器(不改變http中host的信息);如果不自動以host字段,可能會導致返回400的報錯 } } /application/nginx/sbin/nginx –t /application/nginx/sbin/nginx -s reload lsof -i :80
反向代理負載均衡測試結果
我配置了1臺nginx反向代理服務器和兩臺web服務器(一臺apache,一臺nginx);實際生產中要統一使用apache或者nginx,我這裏是因為我自己在家裏的電腦搭建了一個集群架構研究集群,web服務器只搭建了一臺apache和一臺nginx,湊合著用。這裏nginx proxy屬於單點,可以增加一臺結合keepalived做高可用,後續文章講解。
for n in `seq 100`;do curl 10.0.0.6;sleep 1;done
apache www
nginx www
apache www
nginx www
如果web集群中的一臺服務器宕機了,代理就會把所有請求轉發到剩下的那臺web服務器提供服務,不會造成用戶因為單個節點壞了,而無法訪問公司網站
upstream模塊具備健康檢查功能,所以能夠及時發現集群中宕機的節點,從而輪詢給正常工作的機器來處理,使用的是輪詢原理。
400錯誤出現的可能
在實驗的時候,客戶端返回信息出現錯誤,只有一臺web能正常返回內容,另一臺返回400的報錯信息。因為是以前的筆記,忘了把錯誤信息保留下來。
1、http報文缺失host字段
用戶到反向代理服務器中的http報文header請求頭中是有host字段的,而反向代理服務器到web服務器的http報文header請求頭中是沒有host字段的,所以導致apache服務器無法正常解析nginx代理轉發的請求,所以返回400錯誤(400-499是客戶端的問題)
在http 1.1中不能缺失host字段,如果缺失, 服務器返回400 bad request,http1.1中不能缺失host字段,但host字段可以是空值。
在http 1.0中可以缺失host字段。
參考資料:https://blog.csdn.net/s1234567_89/article/details/51139864
proxy_set_header Host $host;
#自定義http包的header的host字段,讓代理服務器使用用戶的host去訪問web服務器(不改變http中host的信息)
位置:http,server,location
參考資料:
https://www.cnblogs.com/yanghj010/p/5980974.html
https://blog.csdn.net/a19860903/article/details/49914131
http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_set_header
反向代理原理
查看web服務器的訪問日誌
10.0.0.6 - - [13/Jun/2018:20:44:15 +0800] "GET / HTTP/1.0" 200 10 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.13.6.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
客戶端IP是10.0.0.61;
nginx反向代理服務器是10.0.0.6;
從這裏可以看出,用戶訪問web是通過反向代理服務器完成的(用戶訪問反向代理服務器,然後由代理服務器去請求web集群,獲取數據後,也是由代理服務器響應用戶)
web端如何記錄用戶ip?
web節點服務器訪問日誌第一個字段記錄的並不是客戶端IP(10.0.0.61),而是反向代理服務器本身的IP(10.0.0.6);而很多時候,運維可能需要通過訪問日誌的用戶IP來統計用戶的訪問情況,如何解決這個問題呢?
添加以下字段即可
proxy_set_header X-Forwarded-For $remote_addr;
位置:http,server,location
反向代理時,節點服務器獲取用戶真實IP的必要功能配置
在反向代理請求後端節點服務器的請求頭中增加獲取的客戶端IP的字段信息,然後節點後端可以通過程序或者相關的配置接收X-Forwared-For傳過來的用戶真實IP的信息。
web訪問日誌格式也得支持
配置nginx.conf配置文件中的log_format參數(http的Log模塊)
訪問日誌顯示X-Forward-For字段的用戶真實IP
web日誌格式配置如下
log_format main ‘$remote_addr - $remote_user [$time_local] "$request" ‘
‘$status $body_bytes_sent "$http_referer" ‘
‘"$http_user_agent" "$http_x_forwarded_for"‘;
access_log logs/access.log main;
#位置:http,server,location
參考資料:http://nginx.org/en/docs/http/ngx_http_log_module.html
測試效果10.0.0.6 - - [13/Jun/2018:21:47:59 +0800] "GET / HTTP/1.0" 200 10 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.13.6.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2" "10.0.0.61"
最後一個字段就是客戶端的IP
Nginx實現反向代理負載均衡功能