CDN功能以下:
一、將全網IP分爲若干個IP段組,分組的依據一般是運營商或者地域,目的是讓相同網絡環境中的用戶彙集到相同的組內;
二、依據CDN服務器們的網絡和容量,肯定哪些CDN服務器適合服務哪些IP段組;
三、根據以上兩步獲得的結論,讓用戶去最適合他的服務器獲得服務。nginx
說白了,就是根據用戶不一樣的來源IP把用戶請求重定向到不一樣的CDN服務器上去。
那麼,如何實現呢?git
智能DNS是辦法之一,穩定可靠且有效。
但至少在兩個環境下它不能徹底知足咱們:
一、須要特別精細的調度時。因爲大多數DNS Server不支持DNS擴展協議,因此拿不到用戶的真實IP,只能根據Local DNS來調度。
二、訪問特別頻繁時。因爲每次調度都將觸發一次DNS,若是請求變得密集,DNS請求自己帶來的開銷也會相應變大;
三、須要根據服務器的帶寬容量、鏈接數、負載狀況、當機與否來調度時。因爲DNS Server沒有CDN節點服務器的信息,這種調度會變得困難。github
這時候咱們能夠:
一、將用戶先行引導到某一臺或幾臺統一的服務器上去;
二、讓它拿到用戶的真實IP,計算出服務他的服務器;
三、經過HTTP302或其它方式把用戶定位到最終服務器上。redis
部署在用戶先訪問到的那幾臺服務器上,負責定位IP而後重定向用戶請求的那個軟件,咱們叫它「調度器」。服務器
HAProxy實現:
HAProxy不支持形如0.0.0.1-0.8.255.255 cn的IP段表示方法,只支持1.1.4.0/22 「CN」的IP段表示方法。
一、咱們須要先把IP段轉化成它認識的方式;
a> 下載iprang.c或者iprang.c本地鏡像;
b> 編譯gcc -s -O3 -o iprange iprange.c;
c> 整理IP段列表geo.txt形如:網絡
1
2
3
4
5
6
7
8
9
10
11
|
# head geo.txt
"1.0.0.0","1.0.0.255","AU"
"1.0.1.0","1.0.3.255","CN"
"1.0.4.0","1.0.7.255","AU"
"1.0.8.0","1.0.15.255","CN"
"1.0.16.0","1.0.31.255","JP"
"1.0.32.0","1.0.63.255","CN"
"1.0.64.0","1.0.127.255","JP"
"1.0.128.0","1.0.255.255","TH"
"1.1.0.0","1.1.0.255","CN"
"1.1.1.0","1.1.1.255","AU"
|
d> 輸出HAProxy認識的IP段列表:frontend
1
2
3
4
5
6
7
8
9
10
11
12
|
# cut -d, -f1,2,5 geo.txt | ./iprange | head
1.0.0.0/24 "AU"
1.0.1.0/24 "CN"
1.0.2.0/23 "CN"
1.0.4.0/22 "AU"
1.0.8.0/21 "CN"
1.0.16.0/20 "JP"
1.0.32.0/19 "CN"
1.0.64.0/18 "JP"
1.0.128.0/17 "TH"
1.1.0.0/24 "CN"
1.1.1.0/24 "AU"
|
e> 便於管理的目的,將整合後的IP段歸類到同一個文件中:socket
1
2
3
4
5
6
7
|
# cut -d, -f1,2,5 geo.txt | ./iprange | sed 's/"//g' | awk -F' ' '{ print $1 >> $2".subnets" }'
# ls *.subnets
A1.subnets AX.subnets BW.subnets CX.subnets FJ.subnets GR.subnets IR.subnets LA.subnets ML.subnets NF.subnets PR.subnets SI.subnets TK.subnets VE.subnets
# cat AU.subnets
1.0.0.0/24
1.0.4.0/22
1.1.1.0/24
|
f> 把這些文件放到同一個文件夾下,咱們以/etc/haproxy/conf/爲例。性能
二、正確配置HAProxy以這些IP段爲規則正確調度;
下面是一個haproxy.cfg的例子。配置好後重啓Haproxy便可。url
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
global
log 127.0.0.1 local2 debug
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 8000
user haproxy
group haproxy
daemon
stats socket /var/lib/haproxy/stats
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 8000
frontend main *:5000
acl geo_A1 src -f /etc/haproxy/conf/A1.subnets
acl geo_AX src -f /etc/haproxy/conf/AX.subnets
acl geo_BW src -f /etc/haproxy/conf/BW.subnets
acl geo_CX src -f /etc/haproxy/conf/CX.subnets
acl geo_FJ src -f /etc/haproxy/conf/FJ.subnets
...
reqrep ^([^\ ]*)\ /(.*)\ HTTP \1\ /\2&ipfrom=A1\ HTTP if geo_A1
reqrep ^([^\ ]*)\ /(.*)\ HTTP \1\ /\2&ipfrom=AX\ HTTP if geo_AX
reqrep ^([^\ ]*)\ /(.*)\ HTTP \1\ /\2&ipfrom=BW\ HTTP if geo_BW
reqrep ^([^\ ]*)\ /(.*)\ HTTP \1\ /\2&ipfrom=CX\ HTTP if geo_CX
reqrep ^([^\ ]*)\ /(.*)\ HTTP \1\ /\2&ipfrom=FJ\ HTTP if geo_FJ
...
default_backend static
backend static
server static 127.0.0.1:6081 check
|
Nginx實現:
Nginx能夠在覈心模塊HttpGeoModule(http://wiki.nginx.org/HttpGeoModule)的配合下實現調度:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
http{
...
geo $useriprang {
ranges;
default a;
0.0.0.1-0.8.255.255 a;
0.9.0.0-0.255.255.255 a;
1.0.0.0-1.0.0.255 a;
1.0.1.0-1.0.1.255 b;
1.0.2.0-1.0.3.255 b;
1.0.4.0-1.0.7.255 a;
...
223.255.252.0-223.255.253.255 c;
223.255.254.0-223.255.254.255 a;
223.255.255.0-223.255.255.255 a;
}
upstream backend {
server 127.0.0.1:81;
}
server {
listen 80;
client_max_body_size 10240m;
location / {
proxy_redirect off;
proxy_pass http://backend$request_uri&useriprang=$useriprang;
proxy_next_upstream http_502 http_504 error timeout invalid_header;
proxy_cache cache_one;
proxy_cache_key $host:$server_port$uri$is_args$args;
expires 5s;
}
}
...
}
|
Varnish實現:
Varnish則有兩個插件能夠實現調度:
https://github.com/cosimo/varnish-geoip (Last updated: 28/05/2013)
https://github.com/meetup/varnish-geoip-plugin (Last updated: 2010)
性能問題
如上所述,使用Haproxy、Nginx、Varnish都能快速實現這個功能。
其中Nginx和Varnish使用了二分法在IP表中定位用戶IP,而Haproxy是逐條過濾。
因此在IP分得較細,IP段組較多(歸類後超過1000組)時,Haproxy會出現明顯的性能衰減,其他二者沒有這個問題。
其它 本文使用的軟件版本以下: HAProxy1.4.22,Nginx1.2.9,Varnish3.0.4。 HAProxy和Varnish都是目前的最新版本。 本文有參考http://blog.exceliance.fr/2012/07/02/use-geoip-database-within-haproxy/ 轉自:http://blog.yikuyiku.com/?p=3851