CDN 調度器HAProxy、Nginx、Varnish

Nginx DNS GCC 軟件 運營商 java高級架構師a 2019-06-11

CDN 功能如下:

1、將全網 IP 分為若干個 IP 段組,分組的依據通常是運營商或者地域,目的是讓相同網絡環境中的用戶聚集到相同的組內;

2、依據 CDN 服務器們的網絡和容量,確定哪些 CDN 服務器適合服務哪些 IP 段組;

3、根據以上兩步得到的結論,讓用戶去最適合他的服務器得到服務。

說白了,就是根據用戶不同的來源 IP 把用戶請求重定向到不同的 CDN 服務器上去。

那麼,如何實現呢?智能 DNS 是辦法之一,穩定可靠且有效。但至少在兩個環境下它不能完全滿足我們:

1、需要特別精細的調度時。由於大多數 DNS Server 不支持 DNS 擴展協議,所以拿不到用戶的真實 IP,只能根據Local DNS 來調度。

2、訪問特別頻繁時。由於每次調度都將觸發一次 DNS,如果請求變得密集,DNS 請求本身帶來的開銷也會相應變大;

3、需要根據服務器的帶寬容量、連接數、負載情況、當機與否來調度時。由於 DNS Server 沒有 CDN 節點服務器的信息,這種調度會變得困難。這時候我們可以:

1、將用戶先行引導到某一臺或幾臺統一的服務器上去;

2、讓它拿到用戶的真實 IP,計算出服務他的服務器;

3、通過 HTTP302 或其它方式把用戶定位到最終服務器上。

部署在用戶先訪問到的那幾臺服務器上,負責定位 IP 然後重定向用戶請求的那個軟件,我們叫它“調度器”。

HAProxy 實現:

HAProxy 不支持形如 0.0.0.1-0.8.255.255 cn 的 IP 段表示方法,只支持 1.1.4.0/22 “CN”的 IP 段表示方法。

1、我們需要先把 IP 段轉化成它認識的方式;

a> 下載 iprang.c 或者 iprang.c 本地鏡像;

b> 編譯 gcc -s -O3 -o iprange iprange.c;

c> 整理 IP 段列表 geo.txt 形如:

CDN 調度器HAProxy、Nginx、Varnish

d> 輸出 HAProxy 認識的 IP 段列表:

CDN 調度器HAProxy、Nginx、Varnish

e> 便於管理的目的,將整合後的 IP 段歸類到同一個文件中:

CDN 調度器HAProxy、Nginx、Varnish

f> 把這些文件放到同一個文件夾下,我們以/etc/haproxy/conf/為例。

2、正確配置 HAProxy 以這些 IP 段為規則正確調度;

下面是一個 haproxy.cfg 的例子。配置好後重啟 Haproxy 即可。

1 global
2 log 127.0.0.1 local2 debug
3
4 chroot /var/lib/haproxy
5 pidfile /var/run/haproxy.pid
6 maxconn 8000
7 user haproxy
8 group haproxy
9 daemon
10
11 stats socket /var/lib/haproxy/stats
12
13 defaults
14 mode http
15 log global
16 option httplog
17 option dontlognull
18 option http-server-close
19 option forwardfor except 127.0.0.0/8
20 option redispatch
21 retries 3
22 timeout http-request 10s
23 timeout queue 1m
24 timeout connect 10s
25 timeout client 1m
26 timeout server 1m
27 timeout http-keep-alive 10s
28 timeout check 10s
29 maxconn 8000
30
31 frontend main *:5000
32 acl geo_A1 src -f /etc/haproxy/conf/A1.subnets
33 acl geo_AX src -f /etc/haproxy/conf/AX.subnets
34 acl geo_BW src -f /etc/haproxy/conf/BW.subnets
35 acl geo_CX src -f /etc/haproxy/conf/CX.subnets
36 acl geo_FJ src -f /etc/haproxy/conf/FJ.subnets
37
38 ...
39
40 reqrep ^([^\ ]*)\ /(.*)\ HTTP \1\ /\2&ipfrom=A1\ HTTP if geo_A1
41 reqrep ^([^\ ]*)\ /(.*)\ HTTP \1\ /\2&ipfrom=AX\ HTTP if geo_AX
42 reqrep ^([^\ ]*)\ /(.*)\ HTTP \1\ /\2&ipfrom=BW\ HTTP if geo_BW
43 reqrep ^([^\ ]*)\ /(.*)\ HTTP \1\ /\2&ipfrom=CX\ HTTP if geo_CX
44 reqrep ^([^\ ]*)\ /(.*)\ HTTP \1\ /\2&ipfrom=FJ\ HTTP if geo_FJ
45
46 ...
47
48 default_backend static
49
50 backend static
51 server static 127.0.0.1:6081 check

Nginx 實現:

Nginx 可以在核心模塊 HttpGeoModule(http://wiki.nginx.org/HttpGeoModule)的配合下實現調度:

1 http{
2
3 ...
4
5 geo $useriprang {
6 ranges;
7 default a;
8 0.0.0.1-0.8.255.255 a;
9 0.9.0.0-0.255.255.255 a;
10 1.0.0.0-1.0.0.255 a;
11 1.0.1.0-1.0.1.255 b;
12 1.0.2.0-1.0.3.255 b;
13 1.0.4.0-1.0.7.255 a;
14 ...
15 223.255.252.0-223.255.253.255 c;
16 223.255.254.0-223.255.254.255 a;
17 223.255.255.0-223.255.255.255 a;
18 }
19
20 upstream backend {
21 server 127.0.0.1:81;
22 }
23
24 server {
25 listen 80;
26 client_max_body_size 10240m;
27
28 location / {
29 proxy_redirect off;
30 proxy_pass http://backend$request_uri&useriprang=$useriprang;
31 proxy_next_upstream http_502 http_504 error timeout invalid_header;
32 proxy_cache cache_one;
33 proxy_cache_key $host:$server_port$uri$is_args$args;
34 expires 5s;
35 }
36
37 }
38
39 ...
40
41 }

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 是逐條過濾。

相關推薦

推薦中...