首页
学习
活动
专区
圈层
工具
发布

第三章 负载均衡LB服务之Haproxy(三)

3.3 Haproxy的访问规则设置

3.3.1 Haproxy的规则设置

在上一节的案例中我们看到,通过acl可设定URI的访问规则,那么里面的hdr(host)是什么意思,又有哪些其他可以做设置的项呢?下面我们就来具体分析一下。

在haproxy的配置文件中,可以使用acl关键字来定义访问规则,然后使用use_backend ... if ... 来使用定义的acl规则,语法格式如下:

acl 规则名 类型 条件内容

use_backend 后端集群名 if acl名

从上面的语义来看就是,当有客户访问满足指定的acl名时,转交到指定的后端backend上。

acl可定义的条件类型有很多,总结来看,有几下几种:

地址类(四层):src源ip地址 src_port源端口 dst目的ip地址 dst_port目的端口;

域名路径类(七层):hdr请求的目的域名 path域名后子地址的路径 url统一资源定位,

其中每一个类型下又可分为多个子项,大体解释如下:

  • hdr(host):精确匹配全称域名,如:hdr(host) -i www.rzz.com
  • hdr_beg(host):精确匹配主机,匹配表示完整的全称域名,与hdr(host)类似
  • hdr_reg(host):正则匹配主机,即模糊匹配,表示以域名中可包含的字符,
  • path:匹配uri的path部分,用于精确的文件资源匹配。例如path -i /a.jsp
  • path_beg:匹配域名后的路径以什么开头
  • path_end:匹配域名后的路径以什么结尾
  • path_reg:使用正则表达式来匹配path
  • url:对整个url做匹配
  • url_reg:正则匹配路径
  • url_sub:请求的URL中包含什么字符串
  • url_dir:请求的URL中包含什么字符串作为部分路径

来看下面的几个案例(以下案例建议在haproxy配置文件中先注释之前手动输入的内容后再写入,否则容易由于先后顺序问题,造成实验效果不准确):

例1:设置ip为202.0.1.0/24地址段的客户端,转发给名为ttWeb的backend集群:

frontend ttWeb

bind 202.0.0.1:80

mode http

acl c1 src202.0.0.0/24

use_backend ttServersif c1

backend ttServers

balance roundrobin

server web1 192.168.10.102:80 check weight 30

注:本例中backend中仅设置了一个节点,其实可以设置多个。

例2:访问域名rzz.com下的所有请求,都转发给转发给名为ttWeb的backend集群。

frontend ttWeb

bind 202.0.0.1:80

mode http

acl c1 hdr_reg(host)-i rzz

use_backend ttServersif c1

default_backendWebServers

backend ttServers

balance roundrobin

server web1 192.168.10.100:80 check weight 30

注:其实这样写,rzz1.com、rzz2.com这样的相似域名,也符合该规则。那是不是该写成acl c1 hdr_reg(host) -i rzz.com就更精确一些了呢?

另外,如果我们把规则写成acl www hrd_reg(host) -i ^(www.rzz.com) 呢?大家可以复习之前学过的特殊字符,自行考虑、试验该结果。

例3:访问以bbs开头的子路径(如:http://www.rzz.com/bbs/)的请求,都转发给名为ttWeb的backend集群。

frontend ttWeb

bind 202.0.0.1:80

mode http

acl c1 path_beg -i /bbs

use_backend ttServersif c1

default_backendWebServers

backend ttServers

balance roundrobin

server web2 192.168.10.101:80 check weight 30

例4:访问以.jpg .png结尾的子路径(如:http://www.rzz.com/bbs/a.jpg)的请求,都转发给名为ttWeb的backend集群。

frontend ttWeb

bind 202.0.0.1:80

mode http

acl c1 path_end -i .jgp .png

use_backend ttServersif c1

default_backendWebServers

backend ttServers

balance roundrobin

server web2 192.168.10.101:80 check weight 30

注:acl的定义中,是允许指定多个值项的,如本例中的acl c1 path_end -i .jgp .png,其他类型的acl(如hdr、url等)也是如此,可以设置多个值项。

例5:访问地址中包含login字符的请求,都转发给名为ttWeb的backend集群。

frontend ttWeb

bind 202.0.0.1:80

mode http

acl c1 url_sub -i login

use_backend ttServersif c1

default_backendWebServers

backend ttServers

balance roundrobin

server web2 192.168.10.101:80 check weight 30

好了,到此我们给acl的配置管理,通过案例做了几个较具代表性的实验,总结来看,对于acl的管理,常用的有三个类型的使用,就是hdr、path、url三项,每项下又支持多个分支,一般不加_后缀的是对原项的精确匹配,如:acl a1 hdr(Host) -i www.rzz1.com;加_beg是对地址的开始字符做匹配;加_end是对地址的结束字符做匹配;加_reg的是对地址做正则表达式匹配。所以大家在实际工作中可以借鉴这些规律,自行设计,以满足生产环境中的需求。有本文中未能涉及的较复杂需求,可以查找相关资料或官方文档,个人研究解决。

3.3.2 Haproxy的访问管理、重定向(跳转)

我们借助于acl,不仅可以完成针对性的分流,还可以对访问做允许/拒绝管理或重定向(又称跳转)操作。使用的关键字有redir、http-request redirect、redirect。

首先来分析一下对于访问端口的重定向管理该如何操作,可以使用redir做路径重定向,而redir设置,一般是写在server项中的,来看一下下面的案例:

例1:所有访问到haporxy服务器(即202.0.0.1)的81端口的请求,全部转到内部节点的80端口上

frontend ttWeb

bind 202.0.0.1:81

mode http

acl c1 dst_port 81

use_backend ttServers if c1

backend ttServers

balance roundrobin

server web1 202.0.0.1:81check weight 30 redir http://192.168.10.100:80

server web2 202.0.0.1:81 check weight 30 redirhttp://192.168.10.101:80

注:此例中,frontend监听的是81端口(bind行设置的是81),web1的地址也是本haproxy的地址,通过redir转发到了内部两个节点的80端口上。

再来介绍一下request请求重定向,一般会用到http-request redirect或redirect关键字。这两个关键字功能类似,语法也是一样的,只不过http-requestredirect更偏向于http模式的转发,支持日志格式变量(即可使用相关配置文件中预定义好的变量);而redirect只依赖于对静态字符串的审核,可以说http-request redirect是redirect的一种升级。

这两种重定向,无论哪一种,都有三种重定向方式

  • prefix:前置重定向,即可将url中原域名替换为新域名,但保留域名后的路径
  • location:位置重定向,将访问url重定向到新的url下
  • scheme:协议重定向,如:http重定向为https

我们同样分别举例说明。

例2:所有访问www.rzz.com及子路径的请求全部转到www.rzz1.com的对应子路径上。

frontend ttWeb

bind 202.0.0.1:80

mode http

acl c1 hdr(host) -iwww.rzz.com

redirect prefixhttp://www.rzz1.com if c1

default_backendWebServers

backend WebServers

balance roundrobin

server web1 192.168.10.100:80 check weight 30

server web2 192.168.10.101:80 check weight 30

注:该例中由于是要做域名地址的转换,所以使用了prefix方式。当客户端在浏览器中输入http://www.rzz.com/bbs后,会发现地址栏中自动变为http://www.rzz1.com/bbs了,说明做了域名替换。

例3:所有访问www.rzz.com及子路径的请求全部转到www.rzz1.com上,并不进子路径。

frontend ttWeb

bind 202.0.0.1:80

mode http

acl c1 hdr(host) -iwww.rzz.com

redirect locationhttp://www.rzz1.com if c1

default_backendWebServers

backend WebServers

balance roundrobin

server web1 192.168.10.100:80 check weight 30

server web2 192.168.10.101:80 check weight 30

注:该例中由于使用了location方式。当客户端在浏览器中输入http://www.rzz.com/bbs后,会发现地址栏中自动变为http://www.rzz1.com了,说明仅做地址重定向,不做域名替换。

综上两例,可看出在实际应用中还是prefix方式更实用些。

例4:将所有http协议的访问自动转为https协议

分析:在第3.2.2节最后部分,我们介绍了haproxy分流https访问的方式,里面设置的是mode tcp,当时解释是只可以用tcp模式,因为我们仅在内部web节点上做了ssl验证功能,而在haproxy上并未做ssl验证,所以只能采用tcp模式,这种方式被称为haproxy的ssl穿透(或称透明)模式,即由内部节点做ssl,haproxy服务器仅转发请求,不做ssl验证。

还有一种方式是使用haProxy服务器作为SSL验证终端,那么则需要在haprox上创建证书了,创建证书的过程我们在上一本书《Linux服务部署》的apache章节中已做了介绍,读者可以自行创建证书。在这里,为了方便,我们直接使用Linux系统自带的证书来完成验证,命令如下:

yum –y install openssl mod_ssl ---安装ssl相关软件包

安装完毕后,我们采用如下命令创建秘钥及证书

cd /etc/haproxy

openssl genrsa -out /etc/haproxy/haproxy.key 1024 ---生成秘钥

openssl req -new -key /etc/haproxy/haproxy.key -out/etc/haproxy/ haproxy.csr ---生成申请

openssl x509 -req -days 3655 -in haproxy.csr -signkey haproxy.key-out haproxy.crt ---生成证书

然后再来创建haproxy的验证文件

cat haproxy.crt haproxy.key > haproxy.pem

最后我们来编写haproxy配置文件

frontend ttWeb

bind 202.0.0.1:443 sslcrt /etc/haproxy/haproxy.pem ---指定使用验证文件做验证

mode http ---使用http模式

default_backendWebServers

backend WebServers

balance roundrobin

server web1 192.168.10.100:80 check weight 30

server web2 192.168.10.101:80 check weight 30

注:由于已经在haproxy服务器上做了ssl验证,所以在内部节点上就无需再做ssl验证了,因此可以直接转发到内部节点的80端口上。

然而,如果我们需要把所有的http访问,都转为https访问的话,则可以写为:

frontend ttWeb

bind 202.0.0.1:80

bind 202.0.0.1:443 sslcrt /etc/haproxy/haproxy.pem

mode http

redirect scheme https if !{ ssl_fc } #协议重定向,ssl_fc前后有空格

default_backendWebServers

其中监听了80端口,表示监控http访问;redirect使用了协议重定向,而if后面的!{ ssl_fc }的意思是判断如果不是ssl的访问请求(!表示取反),则可实现非https协议转为https的功能。后面的backend书写不变,此处略。

3.3.3 http-request访问过滤

使用http-request关键字,不仅可以在后面写入redirect做重定向,还可以写入其他配置,完成对访问的过滤功能,可用项如下:

allow:接受该http请求。

auth:提示输入用户认证信息,指定realm时将给出提示信息。

redirect:重定向功能。

deny:拒绝该http请求。

其中最常用的当然是allow、deny、redirect了。下面我们来看一下过滤案例:

例:仅接受目标端口80、443的访问通信

frontend ttWeb

bind 202.0.0.1:80

bind 202.0.0.1:443 sslcrt /etc/haproxy/haproxy2.pem

mode http

acl c1 dst_port 80

acl c2 dst_port 443

http-request allow ifc1

http-request allow ifc2

http-request deny ---拒绝其他通信访问

use_backendWebServers if c2

use_backendttServers if c1

default_backendWebServers

backend WebServers

balance roundrobin

server web2 192.168.10.101:80 check weight 30

backend ttServers

balance roundrobin

server web1 192.168.10.100:80 check weight30

通过案例我们可以看到,使用http-request过滤可是实现对客户端的限制,那么延伸一下,我们是不是就可以使用acl的src、url等规则实现客户白名单、黑名单的管理呢?当然是可以的,先定义白名单、黑名单的acl,在针对acl做allow、deny就能够实现了,读者可以自行设计一下。

3.4 动静分离机制

现今的企业网站,按其所具备的功能划分,可分为动态站点、静态站点两类。动态与静态的区别并不是指页面上是否有动画、flash等动图效果,它的正规解释是与客户有无数据交互功能,其实就是页面上是否有注册、登录、查询等与客户互通数据的功能。有,则被视为动态站点;无,则是静态站点。

从动静态网站的功能来看,静态页面下服务器只需要给客户发送页面内容即可,不需要进行数据处理,所以针对用户请求的服务进程无需做太多工作,所需内存、CPU资源少,运行速度快;而动态页面由于需要对用户数据进程处理,所以针对客户服务的进程需要更多的cpu、内存资源,运行速度可能会变慢。总结来说,就是动态页面与静态页面相比,消耗系统资源较多,运行速度相对略慢,支持的并发少。

因此,在大规模互联网企业中,为了提高整体服务集群的工作效率,会对客户请求访问的目标页面做分类处理,比如:让客户访问静态页面时分流到一组集群中,如nginx集群;而访问动态页面时,则分流到另一组集群上,如apache、tomcat集群。由此我们将之称为动静分离。

关于动态页面,页面后台的代码一般都是由固定语言编写的,通常页面代码有php语言或jsp语言(即java语言)两种语言。php页面的后缀一般为.php,java页面的后缀一般为.jsp,所以可认定.php、.jsp的页面一般都为动态页面;而静态页面主要是一些文字、图片、动画、动图等资源,所以后缀一般是 .jpg .gif .png.css .js的。

基于Haproxy的http模式原理,就可以对客户所访问的不同目标资源做动静态的分别处理。下面我们来写一下具体的代码:

frontend ttWeb

bind 202.0.0.1:80

mode http

acl c1 path_end -i .js .php .jsp ---定义动态页面后缀

use_backend ttServers if c1

default_backend WebServers

backend WebServers

balance roundrobin

server web2 192.168.10.101:80 check weight 30

backend ttServers

balance roundrobin

server web1 192.168.10.100:80 check weight 30

好了,到这里,一个简单的动静分离设置就实现了。

3.5 haproxy监控

有同学可能会问了,有了分流的设置,我们该如何查看每个集群、节点的访问量、并发数等信息呢?其实很简单,我们只需要在haproxy的配置文件中开启一个端口,使用stats关键字设定监控即可,下面来看一下具体配置:

listen status_page

bind 202.0.0.1:8888 ---设定监控页面的地址及端口

stats enable ---启用状态监测功能

stats uri /haproxy-status ---指定页面在服务器上的url

stats realm "Welcome to the haproxy page" ---启用验证,并设置显示文字,需要配合stats auth使用

stats auth admin:123456 ---登录页面时验证使用的账号、密码

stats hide-version ---启用统计报告,但隐藏HAProxy的版本

stats admin if TRUE ---满足指定条件时,启用监控页面的管理功能,允许通过web页面启用或禁用后端服务器

stats refresh 5s ---监控页面刷新时间

好了,写完这些我们就可以重启haproxy服务。通过客户端的浏览器,输入http://202.0.0.1:8888/haproxy-status,访问监控页面,会有弹窗要求输入账号密码如下图所示:

输入账号admin、密码123456后即可打开监控页面了。如下图所示:

里面的frontend、backend是可以点击的,这样我们就能直观的看到每个frontend、backend、节点的工作状态了。

3.6 小结

到此,我们的haproxy的主要内容就讲解完了,大家可以多多练习。在实际工作中根据项目需求,设计对应的分流规则。当然,haproxy的功能还有很多,我们只讲解了其中的主要部分,其他配置,如果在工作中有所需要,大家可以查询一些相关资料,自行学习完成。

下一篇
举报
领券