Haproxy 反向代理

一、haproxy介绍

HAProxy是一个使用C语言编写的自由及开放源代码软件,其提供高可用性、负载均衡,以及基于TCP和HTTP的应用程序代理。

特点如下:
1、支持两种代理模式:TCP(四层)和HTTP(七层),支持虚拟主机;
2、能够补充Nginx的一些缺点比如Session的保持,Cookie的引导等工作
3、支持url检测后端的服务器出问题的检测会有很好的帮助。
4、更多的负载均衡策略比如:动态加权轮循(Dynamic Round Robin),加权源地址哈希(Weighted Source Hash),加权URL哈希和加权参数哈希(Weighted Parameter Hash)已经实现
5、单纯从效率上来讲HAProxy更会比Nginx有更出色的负载均衡速度。
6、HAProxy可以对Mysql进行负载均衡,对后端的DB节点进行检测和负载均衡。
9、支持负载均衡算法:Round-robin(轮循)、Weight-round-robin(带权轮循)、source(原地址保持)、RI(请求URL)、rdp-cookie(根据cookie)
10、不能做Web服务器即Cache。

二、haproxy安装

下载地址:http://www.haproxy.org/download/1.8/src/haproxy-1.8.20.tar.gz
如无法直接下载,可以在网盘中下载:

链接:https://pan.baidu.com/s/1o2CemcucfQ4zdGfb1yaaxA
提取码:7baf

# 1.编译安装haproxy
tar xf haproxy-1.8.20.tar.gz 
cd haproxy-1.8.20/
make TARGET=linux2628 PREFIX=/usr/local/haproxy-1.8.20
make install
cp /usr/local/sbin/haproxy /usr/sbin/
haproxy -v

# 在haproxy安装包内拷贝启动脚本
cp examples/haproxy.init /etc/init.d/haproxy
chmod 755 /etc/init.d/haproxy

# haproxy创建配置文件目录
useradd -r haproxy
mkdir /etc/haproxy /var/lib/haproxy /var/run/haproxy


# 2.可通过yum直接安装,版本较低1.5.18-8.el7,两种方法都可以。
yum install haproxy -y

三、haproxy配置文件

HAProxy配置文件的配置方法主要用两种:一种是由前端(frontend)和后端(backend)配置块组成,前端和后端都可以有多个。第二种方法是只有一个listen配置快块来同时实现前端和后端。我们这里主要介绍最常用的frontend和backend工作模式,这个也是推荐的配置方法。
同时前端(frontend)区域可以根据HTTP请求的header信息来定义一些规则,然后将符合某规则的请求转发到相应后端(backend)进行处理,这个我们后面会详细讲解。

3.1 haproxy.cfg配置文件

vim /etc/haproxy/haproxy.cfg
global                                        # 全局配置参数,进程级的,用来控制Haproxy启动前的一些进程及系统设置
    maxconn 10000                             # 定义每个haproxy进程的最大连接数,由于每个连接包括一个客户端和一个服务器端,所以单个进程的TCP会话最大数目将是该值的两倍
    chroot /var/lib/haproxy                   # 增加安全性,改变当前工作目录
    user haproxy                              # 启动用户为haproxy,也可以写成UID
    group haproxy                             # 启动用户组为haproxy,也可以写成PID
    daemon                                    # 以守护进程的方式运行
    nbproc 8                                  # 设置haproxy启动时的进程数,设置其CPU的核心数,可减少每个进程的任务队列,过多进程数也会导致进程崩溃
    pidfile /var/lib/haproxy/haproxy.pid      # 定义haproxy.pid的位置,注意目录要事先存在,如果没有需要提前创建。
    log 127.0.0.1 local3 info                 # 全局的日志配置,使用log关键字,指定使用127.0.0.1上的rsyslog服务中的local3日志设备,记录日志等级为info的日志,
defaults # 配置一些默认的参数,可以被frontend,backend,listen段继承使用 maxconn 10000 # 最大连接数 mode http # mode {http|tcp|health} http是七层模式,tcp是四层模式,health是健康检测,返回OK log global # 应用全局日志配置 option httplog # 启用日志记录HTTP请求,默认haproxy日志记录是不记录HTTP请求的 option http-keep-alive # 启用或禁用客户端和服务端到haproxy之间的长连接。haproxy将处理所有请求和响应报文,请求完后haproxy两端的连接都处于空闲状态。 option dontlognull # 启用该项,日志中将不会记录空连接。所谓空连接就是在上游的负载均衡器或者监控系统为了探测该服务是否存活可用时,需要定期的连接或者获取某一固定的
组件或页面,或者探测扫描端口是否在监听或开放等动作被称为空连接;官方文档中标注,如果该服务上游没有其他的负载均衡器的话,建议不要使用该参数,
因为互联网上的恶意扫描或其他动作就不会被记录下来 option http-server-close # 使用该参数,每处理完一个request时,haproxy都会去检查http头中的Connection的值,如果该值不是close,haproxy将会将其删除,如果该值为空将
会添加为:Connection: close。使每个客户端和服务器端在完成一次传输后都会主动关闭TCP连接。与该参数类似的另外一个参数是“option
forceclose”,该参数的作用是强制关闭对外的服务通道,因为有的服务器端收到Connection: close时,也不会自动关闭TCP连接,如果客户端也不关闭,
连接就会一直处于打开,直到超时。 option redispatch # 在session失败后,是否允许重新分配
option abortonclose # 当服务器负载很高的时候,自动结束掉当前队列处理比较久的链接 timeout connect 5000ms # 设置成功连接到一台服务器的最长等待时间,默认单位是毫秒 timeout client 50000ms # 设置连接客户端发送数据时的成功连接最长等待时间,默认单位是毫秒 timeout server 50000ms # 设置服务器端回应客户度数据发送的最长等待时间,默认单位是毫秒 listen stats # 定义一个名为stats的部分,理解为frontend和backend的组合体 mode http # 定义为http模式 bind
0.0.0.0:8888 # 定义监听套接字 stats enable # 开启WEB统计功能
stats refresh 30s # 页面自动刷新时间30s stats uri
/haproxy-status # web统计的URI为 /haproxy-status stats auth haproxy:haproxy # 访问web页面的用户名和密码 frontend frontend_web_server # 定义一个名为frontend_web_server的前端部分,用来匹配接收客户所请求的域名,uri等,并针对不同的匹配,做不同的请求处理 bind 192.168.7.80:80 # 定义前端访问的IP及端口 mode http # 定义为HTTP模式 option httplog # 启用记录HTTP请求、会话状态和计时器的功能 log global # 继承global中的log定义 default_backend backend_web_server # 如果前面acl都没有匹配到,默认的后端backend_web_server服务集群 backend backend_web_server # 定义后端服务器集群,以及对后端服务器的一些权重、队列、连接数等选项的设置,我将其理解为Nginx中的upstream块。 option forwardfor header X-REAL-IP # 启用X-Forwarded-For,在requests头部插入客户端IP发送给后端的server,使后端server获取到客户端的真实IP option httpchk HEAD / HTTP/1.0 # 开启对后端服务器的健康检测,通过GET / 来判断后端服务器的健康情况 balance source # 设置haproxy的调度算法为源地址hash server web-7.72 192.168.7.72:80 cookie 1 check inter 2000 rise 3 fall 3 weight 1 # 后端服务器名称为web-7.72,后端服务器的IP及端口,指定该服务器的SERVERID为1[cookie 1]
接受健康监测[check]、监测的间隔时长,单位毫秒[inter 2000],监测正常多少次后被认为后端
服务器是可用的[rise 3]监测失败多少次后被认为后端服务器是不可用的[fall 3]、分发的权重
[weight 1]
server web-7.73 192.168.7.73:80 cookie 2 check inter 2000 rise 3 fall 3 weight 2
server web-7.70 192.168.7.77:80 cookie 2 check inter 2000 rise 3 fall 3 backup # 上面全部down机后启动备机[backup]

 3.2 日志配置

 前面在haproxy中已经定义了日志级别为local3,需要rsyslog在514端口监听UDP协议,修改完成后重启rsyslog服务

vim /etc/rsyslog.conf

# 增加如下三行
$ModLoad imudp
$UDPServerRun 514
local3.*                                                /var/log/haproxy.log

systemctl restart rsyslog.service

3.3 web图面截图

 3.4 haproxy的8种调度算法

1. roundrobin     # 根据服务器权重轮询的算法,可以自定义权重,它支持慢启动,并能在运行时修改权重,所以是一种动态算法。最多支持4095台后端主机。
2. static-rr      # 与roundrobin类似,static-rr也是一种轮询算法,但它是静态的,对后端主机数量无限制。
3. leastconn      # 最小连接数算法,一种可以根据后端主机连接数情况进行调度的动态算法,支持慢启动和运行时调整,可将新的请求调度至连接数较少的后端主机。与LVS中lc算法类似。
4. first          # 根据服务器标识顺序选择服务器,当服务器承载的连接数达到maxconn的值后便将新情求调度至下一台服务器。此算法只在一些特殊场景下使用。
5. source         # 对请求的源IP地址进行hash处理,根据hash运算处理结果调度至后端服务器。可使固定IP的请求始终调度至统一服务器。
6. uri            # 根据请求的uri进行hash处理并调度之后端主机。
7. url_param      # 将URL的参数进行判断并进行hash计算,参数可以自定义,任何的URL参数都可以。
8. hdr(name)      # 根据请求中的HTTP报文首部的值进行hash计算并调度。name可以是GET、USERAGENT等首部名。

四、ACL的用法

4.1 ACL的语法

acl <aclname> <criterion> [flags] [operator] [<value>] ...

<aclname>:ACL名称,区分字符大小写,且其只能包含大小写字母、数字、-(连接线)、_(下划线)、.(点号)和:(冒号);haproxy中,acl可以重名,这可以把多个测试条件定义为一个共同的acl;

<criterion>:测试标准,即对什么信息发起测试;测试方式可以由[flags]指定的标志进行调整;而有些测试标准也可以需要为其在<value>之前指定一个操作符[operator];

[flags]:目前haproxy的acl支持的标志位有3个:

-i:不区分<value>中模式字符的大小写;

-f:从指定的文件中加载模式;

--:标志符的强制结束标记,在模式中的字符串像标记符时使用;

<value>:acl测试条件支持的值有以下四类:

整数或整数范围:如1024:65535表示从1024至65535;仅支持使用正整数(如果出现类似小数的标识,其为通常为版本测试),且支持使用的操作符有5个,分别为eq、ge、gt、le和lt;

字符串:支持使用“-i”以忽略字符大小写,支持使用“”进行转义;如果在模式首部出现了-i,可以在其之前使用“--”标志位;

正则表达式:其机制类同字符串匹配;

IP地址及网络地址

同一个acl中可以指定多个测试条件,这些测试条件需要由逻辑操作符指定其关系。条件间的组合测试关系有三种:“与”(默认即为与操作)、“或”(使用“||”操作符)以及“非”(使用“!”操作符)。

4.2 用例

# 定义允许访问的IP地址段和拒绝的IP地址段
acl accept_clients src 192.168.7.0/24
acl reject_clients src 192.168.5.0/24
tcp-request content accept if accept_clients
tcp-request content reject if reject_clients
tcp-request content reject             # 此项表明不匹配前两项的默认都拒绝

# 将源IP为192.168.5.10的用户禁止、将403的错误重定向到其他服务器;
frontend  webservers
bind *:80
default_backend webservs
acl badguy src 192.168.5.10
block if badguy
errorloc 403 http://www.baidu.com

# 定义一个名叫php_web的acl,当请求的url末尾是以.php结尾的,将会被匹配到,以下两种写法任选其一
acl php_web url_reg /*.php$
acl php_web path_end .php

# 定义一个名叫static_web的acl,当请求的url末尾是以.css、.jpg、.png、.jpeg、.js、.gif结尾的,将会被匹配到,以下两种写法任选其一
acl static_web url_reg /*.(css|jpg|png|jpeg|js|gif)$
acl static_web path_end .gif .png .jpg .css .js .jpeg

# 如果满足策略php_web时,就将请求交予backend php_server
use_backend php_server if php_web

# 如果满足策略static_web时,就将请求交予backend static_server
use_backend static_server if static_web

# 匹配XX开始的
acl static_d path_beg /static /small /big 

# 匹配首页
acl index_page path_reg ^/$ 

# 匹配User-Agent类型
acl ua hdr_reg(User-Agent) -i iphone android

# 匹配访问的域名
acl club hdr_reg(host) -i club.jesse.com 

# 匹配相关的ACL策略就进行跳转
redirect prefix https://www.baidu.com if ua static_d club

# 读写分离:
acl read method GET
acl read method HEAD
acl write method PUT
acl write method POST
use_backend imgservers if read
use_backend uploadservers if write
原文地址:https://www.cnblogs.com/cyleon/p/10980147.html