Quantcast
Channel: polygun2000的博客
Viewing all articles
Browse latest Browse all 55

haproxy中使用map处理大量主机头

$
0
0
先吐槽一下haproxy的官方文档,这个文档真是个神奇的东西,所有需要的东西都在里边,但是如果你想象力不够丰富,就是不知道怎么使用。以下文档,是我简单翻译的aloha blog中的文档而来,加了一点自己的理解。
原文地址见参考文档部分。

我有一个做售后服务的朋友,遇到过一家客户,他们只有一个公网IP,但是要承担几十个不同域名的网站。当时他们使用的是F5 BIGIP,是通过irule取不同主机头,分配到后端不同的pool中去。

haproxy面对同样的问题,也采取了类似的方法,通过ACL来匹配请求中的主机头,然后分配给不同的backend。例子如下:

frontend ft_allapps
 [...]
 use_backend bk_app1 if { hdr(Host) -i app1.domain1.com app1.domain2.com }
 use_backend bk_app2 if { hdr(Host) -i app2.domain1.com app2.domain2.com }
 default_backend bk_default

这个方法对于少量主机头当然OK,但是要把情况极端化一点,例如上百个主机头的情况呢?
那估计配置文件会让人发疯的。

但在haproxy 1.5版以后,haproxy引入了converter这个功能,其中有一种map类型的converter。
这个map converter的功能就是将input和output数据1:1做预先对应。
实际使用中,只要调用map converter,输入map中预先定义好的input值,就会得到对应的output值。

map实际存在于一个包含格式的文本文件中,这个文件在haproxy启动时被加载进来。该文件有两列,左边是input串,右边是output串 。

那么对应前述例子,我们可以预先定义一个map文件,假设文件为/etc/hapee-1.5/domain2backend.map,其内容如下:
#domainname  backendname
app1.domain1.com bk_app1
app1.domain2.com bk_app1
app2.domain1.com bk_app2
app2.domain2.com bk_app2

第一列是主机头,第二列是对应分配的backend名称。

然后在haproxy的配置文件中,做如下配置:
frontend ft_allapps
 [...]
 use_backend %[req.hdr(host),lower,map(/etc/hapee-1.5/domain2backend.map,bk_default)]

haproxy会按照如下步骤操作:

1.req.hdr(host) ==> 从HTTP请求中取得主机头
2.lower ==> 转换所有字符为小写
3.map(/etc/hapee-1.5/domain2backend.map,bk_default) ==>在这个map文件中查找小写的主机头,如果找到对应项,则返回对应的backend名称,如果没找到返回bk_default这个backend名称。
4.将请求流量发送给map返回的backend服务器。

这样即使面对成百上千的主机头,也只是需要在map文件中操作,然后reload即可。
即不需要写正则表达式,也不需要在haproxy配置文件中写入大量的ACL判断。

另外,map数据是以"树"的数据结构存储,所以其查找速度比起查ACL来说要快多了。

简单就是美!!

2016.01.22增补

如果是https网站,则需要从sni中获取hostname
use_backend %[ssl_fc_sni,lower,map(/etc/hapee-1.5/domain2backend.map,bk_default)]

参考文档:
http://blog.haproxy.com/2015/01/26/web-application-name-to-backend-mapping-in-haproxy/

 

Viewing all articles
Browse latest Browse all 55

Trending Articles