Nginx的geo子產品不僅可以有限速白名單的作用,還可以做全局負載均衡,可以要根據用戶端ip通路到不同的server。比如,可以将電信的使用者通路定向到電信伺服器,網通的使用者重 定向到網通伺服器”,進而實作智能DNS的作用。前面介紹過nginx域名通路的白名單配置梳理,下面對nginx的geo子產品使用做一梳理(參考Geo子產品-Nginx中文文檔)
geo指令是通過ngx_http_geo_module子產品提供的。預設情況下,nginx安裝時是會自動加載這個子產品,除非安裝時人為的手動添加--without-http_geo_module。
ngx_http_geo_module子產品可以用來建立變量,其值依賴于用戶端IP位址。
geo指令
文法: geo [$address] $variable { ... }
預設值: —
配置段: http
定義從指定的變量擷取用戶端的IP位址。預設情況下,nginx從$remote_addr變量取得用戶端IP位址,但也可以從其他變量獲得。
例如:
geo $remote_addr $geo {
default 0;
127.0.0.1 1;
}
geo $arg_ttlsa_com $geo {
default 0;
127.0.0.1 1;
}
如果該變量的值不能代表一個合法的IP位址,那麼nginx将使用位址"255.255.255.255"。
nginx通過CIDR或者位址段來描述位址,支援下面幾個參數:
1)delete:删除指定的網絡
2)default:如果用戶端位址不能比對任意一個定義的位址,nginx将使用此值。 如果使用CIDR,可以用"0.0.0.0/0"代替default。
3)include: 包含一個定義位址和值的檔案,可以包含多個。
4)proxy:定義可信位址。 如果請求來自可信位址,nginx将使用其“X-Forwarded-For”頭來獲得位址。 相對于普通位址,可信位址是順序檢測的。
5)proxy_recursive:開啟遞歸查找位址。 如果關閉遞歸查找,在用戶端位址與某個可信位址比對時,nginx将使用"X-Forwarded-For"中的最後一個位址來代替原始用戶端位址。如果開啟遞歸查找,在用戶端位址與某個可信位址比對時,nginx将使用"X-Forwarded-For"中最後一個與所有可信位址都不比對的位址來代替原始用戶端位址。
6)ranges:使用以位址段的形式定義位址,這個參數必須放在首位。為了加速裝載位址庫,位址應按升序定義。
geo $country {
default ZZ;
include conf/geo.conf;
delete 127.0.0.0/16;
proxy 192.168.100.0/24;
proxy 2001:0db8::/32;
127.0.0.0/24 US;
127.0.0.1/32 RU;
10.1.0.0/16 RU;
192.168.1.0/24 UK;
}
# vim conf/geo.conf //編輯conf/geo.cong檔案
10.2.0.0/16 RU;
192.168.2.0/24 RU;
位址段例子:
geo $country {
ranges;
default ZZ;
127.0.0.0-127.0.0.0 US;
127.0.0.1-127.0.0.1 RU;
127.0.0.1-127.0.0.255 US;
10.1.0.0-10.1.255.255 RU;
192.168.1.0-192.168.1.255 UK;
}
geo指令主要是根據IP來對變量進行指派的。是以geo塊下隻能定義IP或網絡段,否則會報錯。
====================nginx利用geo子產品做限速白名單操作======================
nginx的限速白名單需要結合geo和map指令來實作,map指令使用ngx_http_map_module子產品提供的。預設情況下,nginx安裝時是會自動加載這個子產品,除非安裝時人為手動添加--without-http_map_module。
ngx_http_map_module子產品可以建立變量,這些變量的值與另外的變量值相關聯。允許分類或者同時映射多個值到多個不同值并儲存到一個變量中,map指令用來建立變量,但是僅在變量被接受的時候執行視
圖映射操作,對于處理沒有引用變量的請求時,這個子產品并沒有性能上的缺失。
配置如下:
http {
geo $whiteiplist {
default 1;
127.0.0.1 0;
192.0.0.0/8 0;
103.20.102.0/24 0;
}
map $whiteiplist $limit {
1 $binary_remote_addr;
0 "";
}
limit_conn_zone $limit zone=limit:10m;
server {
listen 80;
server_name test.huanqiu.com;
location ^~ /download/ {
limit_conn limit 4;
limit_rate 200k;
alias /data/www.huanqiu.com/data/download/;
}
}
}
------------------------如下是一個nginx中geo限速白名單的配置執行個體--------------------------
[root@localhost ~]# cat /usr/local/nginx/conf/vhosts/wangshibo.conf
geo $whiteiplist {
default 1;
127.0.0.1 0;
192.168.0.0/16 0;
58.68.230.0/24 0;
}
map $whiteiplist $limit {
1 $binary_remote_addr;
0 "";
}
limit_conn_zone $limit zone=limit:10m;
server {
listen 80;
server_name dev.wangshibo.com wangshibo.com *.wangshibo.com;
access_log /usr/local/nginx/logs/8080-access.log main;
error_log /usr/local/nginx/logs/8080-error.log;
location ~ / {
root /var/www/html/8080;
index index.html index.php index.htm;
}
location ^~ /download/ {
limit_conn limit 4; //最大的并發連接配接數
limit_rate 200k; //每個連接配接的帶寬
alias /data/wangshibo/download/;
}
}
配置要點解釋:
1)geo指令定義一個白名單$whiteiplist, 預設值為1, 所有都受限制。 如果用戶端IP與白名單列出的IP相比對,則$whiteiplist值為0也就是不受限制。
2)map指令是将$whiteiplist值為1的,也就是受限制的IP,映射為用戶端IP。将$whiteiplist值為0的,也就是白名單IP,映射為空的字元串。
3)limit_conn_zone和limit_req_zone指令對于鍵為空值的将會被忽略,進而實作對于列出來的IP不做限制。
測試方法
[root@localhost vhosts]# ab -c 100 -n 300 http://dev.wangshibo.com/download/docs/pdf/kevingarce.pdf
==============Nginx利用geo子產品做負載均衡的操作記錄===============
本次測試的機器ip資訊如下:
server1: 113.110.86.28
server2: 113.110.86.25
server3: 188.84.155.239
用戶端1:113.110.86.23
用戶端2:113.110.86.51
用戶端3:113.110.86.19
三台server機器上都部署了nginx環境,為了測試效果,特意配置了server1和server2的9090端口的首頁,如下:
[root@localhost ~]# curl http://113.110.86.28:9090
this is server1:113.110.86.28
[root@localhost ~]# curl http://113.110.86.25:9090
this is server2:113.110.86.25
配置server3,在server3上實作利用geo子產品做負載均衡的目的,server3的nginx配置如下:
[root@localhost vhosts]# cat test.conf
geo $geo {
default default;
113.110.86.19/32 uk;
113.110.86.51/32 us;
}
#這裡我是單網測試,是以掩碼是32位;如果是vlan,可以是24位掩碼,比如:
# 113.110.86.0/24 tw;
upstream uk.server {
server 113.110.86.28:9090;
}
upstream us.server {
server 113.110.86.25:9090;
}
upstream default.server {
server 188.84.155.239:9090;
}
server {
listen 80;
server_name 188.84.155.239;
index index.html index.htm;
root /var/www/html/80;
location / {
proxy_redirect off;
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_pass http://$geo.server$request_uri;
}
}
server {
listen 9090;
server_name 188.84.155.239;
location / {
root /var/www/html/9090;
index index.html index.htm;
}
}
通路server3的9090端口
[root@localhost vhosts]# curl http://188.84.155.239:9090
this is server3:188.84.155.239
------------------------接下來就開始測試-------------------------
1)在用戶端1上通路http://188.84.155.239,如下:
[root@localhost ~]# curl http://188.84.155.239
this is server3:188.84.155.239
因為用戶端1的IP位址為113.110.86.23,按照上面server3中nginx的配置,它通路的很明顯是server3的9090端口!
2)在用戶端2上通路http://188.84.155.239,如下:
[root@localhost ~]# curl http://188.84.155.239
this is server2:113.110.86.25
按照server3的nginx配置,用戶端2通路server3的80端口就會被負載到server2的9090端口上!
3)在用戶端3上通路http://188.84.155.239,如下:
[root@jenkins-server ~]# curl http://188.84.155.239
this is server1:113.110.86.28
按照server3的nginx配置,用戶端3通路server3的80端口就會被負載到server1的9090端口上!
------------------------------------------------------------
通過上面的測試,很明顯能看到geo子產品起到了負載均衡的作用。這樣就可以把三台伺服器分别放到不同的IDC機房。然後在資料同步就可以了。
這樣做的好處就是省去了在DNS上做手腳,因為智能DNS有時候按照來訪IP解析的時候會解析對方的DNS位址,把它比對到一台伺服器,如果對方是
網通使用者,它用的電信DNS,會直接把它比對到電信的伺服器。而nginx的geo子產品就是根據來通路IP來比對伺服器的,這樣隻要我們把各地區的IP段收集起來就可以了~~
*************** 當你發現自己的才華撐不起野心時,就請安靜下來學習吧!***************