nginx使用用戶真實IP做hash(解決經過CND後ip_hash失效問題)

在nginx中常用的有以下四種負載均衡的算法,分別是:round-robin、ip-hash、least-connected和weighted。當然在實際生產中或許使用最多的就是ip-hash了,一般會這樣使用:

upstream h5 {
   ip_hash;
   server 192.168.100.104:9080;
   server 192.168.100.105:9080;
 }

如果用戶是直連的話那還好,nginx可以根據用戶的IP均勻地向多個服務器節點分配負載請求。但是如果我們的域名使用了CDN加速的話,那麼用戶在請求js、CSS、圖片等靜態資源時並沒有直接請求到我們的服務器,而是請求的少量的CDN加速節點服務器,從而造成有少量IP(PS:CDN節點服務器IP)頻繁大量訪問nginx。同時又因爲ip_hash策略的原因,導致出現部分服務器的負載非常大,其他服務器卻沒有多少請求的現象

因此,爲了解決這個問題,我們可以通過在nginx中獲取用戶請求時的真實IP,然後根據這些真實IP做hash策略,也就是自定義nginx的hash策略。實現步驟如下:

(1)修改nginx配置文件nginx.conf:

[root@tkde-iphone ~]# vim /usr/local/nginx/conf/nginx.conf

http {
include mime.types; #設定mime類型,類型由mime.type文件定義
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”‘;
access_log logs/access.log main;

#獲取用戶真實IP,並賦值給變量$clientRealIP
map $http_x_forwarded_for $clientRealIp {
    "" $remote_addr;
    ~^(?P<firstAddr>[0-9\.]+),?.*$ $firstAddr;
}

……..

include gzip.conf; #壓縮配置文件
include proxy.conf; #proxy_cache參數配置文件
include vhost/*.conf; #nginx虛擬主機包含文件目錄
include mysvrhost.conf; #後端WEB服務器列表文件
}

(2)修改nginx的配置文件mysvrhost.conf:

[root@tkde-iphone ~]# vim /usr/local/nginx/conf/mysvrhost.conf

upstream h5 {
hash $clientRealIp;
server 192.168.100.104:9080;
server 192.168.100.105:9080;
}

注:這種方式也並不是萬無一失了,因爲請求的Header中的HTTP_X_FORWARDED_FOR參數可以在請求時被修改的,因此就存在一定的安全隱患。不過現在的CDN一般都有加速防黑的功能,所有實際上問題也不是很大。如果實在不放心的話不是還可以使用SSL證書整站加密嘛


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章