先吐槽一下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/