CDN调度器HAProxy、Nginx、Varnish

摘要:
智能DNS是办法之一,稳定可靠且有效。HAProxy实现:HAProxy不支持形如0.0.0.1-0.8.255.255cn的IP段表示方法,只支持1.1.4.0/22“CN”的IP段表示方法。1、我们需要先把IP段转化成它认识的方式;a˃下载iprang.c或者iprang.c本地镜像;b˃编译gcc-s-O3-oiprangeiprange.c;c˃整理IP段列表geo.txt形如:#headgeo.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"1234567891011#headgeo.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段列表:#cut-d,-f1,2,5geo.txt|./iprange|head1.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"123456789101112#cut-d,-f1,2,5geo.txt|./iprange|head1.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段归类到同一个文件中:#cut-d,-f1,2,5geo.txt|./iprange|sed's/"//g'|awk-F'''{print$1˃˃$2".subnets"}'#ls*.subnetsA1.subnetsAX.subnetsBW.subnetsCX.subnetsFJ.subnetsGR.subnetsIR.subnetsLA.subnetsML.subnetsNF.subnetsPR.subnetsSI.subnetsTK.subnetsVE.subnets#catAU.subnets1.0.0.0/241.0.4.0/221.1.1.0/241234567#cut-d,-f1,2,5geo.txt|./iprange|sed's/"//g'|awk-F'''{print$1˃˃$2".subnets"}'#ls*.subnetsA1.subnetsAX.subnetsBW.subnetsCX.subnetsFJ.subnetsGR.subnetsIR.subnetsLA.subnetsML.subnetsNF.subnetsPR.subnetsSI.subnetsTK.subnetsVE.subnets#catAU.subnets1.0.0.0/241.0.4.0/221.1.1.0/24f˃把这些文件放到同一个文件夹下,我们以/etc/haproxy/conf/为例。配置好后重启Haproxy即可。

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形如:

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段列表:

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段归类到同一个文件中:

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.subnetsAX.subnetsBW.subnetsCX.subnetsFJ.subnetsGR.subnetsIR.subnetsLA.subnetsML.subnetsNF.subnetsPR.subnetsSI.subnetsTK.subnetsVE.subnets
# cat AU.subnets
1.0.0.0/24
1.0.4.0/22
1.1.1.0/24

f> 把这些文件放到同一个文件夹下,我们以/etc/haproxy/conf/为例。

2、正确配置HAProxy以这些IP段为规则正确调度;
下面是一个haproxy.cfg的例子。配置好后重启Haproxy即可。

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
log127.0.0.1local2 debug
chroot/var/lib/haproxy
pidfile/var/run/haproxy.pid
maxconn8000
userhaproxy
group haproxy
daemon
stats socket/var/lib/haproxy/stats
defaults
modehttp
log global
optionhttplog
optiondontlognull
option http-server-close
option forwardfor except127.0.0.0/8
optionredispatch
retries3
timeout http-request10s
timeout queue1m
timeout connect10s
timeout client1m
timeout server1m
timeout http-keep-alive10s
timeout check10s
maxconn8000
frontendmain *: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^([^]*)/(.*)HTTP1/2&ipfrom=A1HTTP ifgeo_A1
reqrep^([^]*)/(.*)HTTP1/2&ipfrom=AXHTTP ifgeo_AX
reqrep^([^]*)/(.*)HTTP1/2&ipfrom=BWHTTP ifgeo_BW
reqrep^([^]*)/(.*)HTTP1/2&ipfrom=CXHTTP ifgeo_CX
reqrep^([^]*)/(.*)HTTP1/2&ipfrom=FJHTTP ifgeo_FJ
...
default_backend static
backend static
serverstatic127.0.0.1:6081check

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;
defaulta;
0.0.0.1-0.8.255.255a;
0.9.0.0-0.255.255.255a;
1.0.0.0-1.0.0.255a;
1.0.1.0-1.0.1.255b;
1.0.2.0-1.0.3.255b;
1.0.4.0-1.0.7.255a;
...
223.255.252.0-223.255.253.255c;
223.255.254.0-223.255.254.255a;
223.255.255.0-223.255.255.255a;
}
upstreambackend{
server127.0.0.1:81;
}
server{
listen80;
client_max_body_size10240m;
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;
expires5s;
}
}
...
}

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

免责声明:文章转载自《CDN调度器HAProxy、Nginx、Varnish》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇SmartSql漫谈EasyNVR无插件直播服务如何配合EasyBMS使用以及实现流媒体管理功能概述下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Ubuntu 搭建ELK

一、简介 官网地址:https://www.elastic.co/cn/ 官网权威指南:https://www.elastic.co/guide/cn/elasticsearch/guide/current/index.html 安装指南:https://www.elastic.co/guide/en/elasticsearch/reference/5.x...

nginx的平滑升级

一:解释nginx的平滑升级 随着nginx越来越流行,并且nginx的优势也越来越明显,nginx的版本迭代也来时加速模式,1.9.0版本的nginx更新了许多新功能,例如stream四层代理功能,伴随着nginx的广泛应用,版本升级必然越来越快,线上业务不能停,此时nginx的升级就是运维的工作了 Nginx方便地帮助我们实现了平滑升级。其原理简单概括...

编译安装squid3.1亲测

编译安装Squid2.6 1,设置“文件描述符”,并设置用户同时打开文件数量 # vi /usr/include/bits/typesizes.h # vi /usr/include/linux/posix_types.h 把里边的 #define __FD_SETSIZE 1024 改成 65536 2,设置当前环境 # ulimit -Hs 65536...

istio 学习之 手动注入sidecar

istio 创建pod的时候会给默认自动注入的命名空间 注入sidecar ,sidecar中包含envoy组件和pilot-agent组件 ,这两个共同组成sidecar。 这次的目的就是为了观察istio 注入的过程。 首先我们新创建一个test 命名空间 [root@istio-master test]# kubectl create namespa...

linux制作RPM包

制作rpm包 1.制作流程1.1 前期工作 1)创建打包用的目录rpmbuild/{BUILD,SPECS,RPMS, SOURCES,SRPMS} 建议使用普通用户,在用户家目录中创建 2)确定好制作的对象,是源码包编译打包还只是一些库文件打包 3)编写SPEC文件 4)开始制作 1.2 RPM制作过程 1)读取并解析 filename.spec 文件...

用Docker实现nginx多端口

一.安装docker 需要阿里的epel源,需要联网 [root@bogon ~]#yum -y install docker [root@bogon ~]#systemctl start docker [root@bogon ~]#systemctl enable docker 下载httpd镜像 Docker pull http:2.4.27-al...