Haproxy 配置文件


概述

haproxy的配置文件大概可以分两段:第一段配置是global配置段即全局配置段,主要是针对haproxy的进程和安全相关的配置;第二段是proxies代理配置段,主要是配置haproxy前端监听那个地址那个端口以及后端server的名称、地址、端口,以及server相关属性等配置;而proxies配置段里又分defaults配置段,这个部分主要是定义后续的backend,listen这两个段的默认配置;什么意思呢?也就是在后面的配置中如果我们没有写对应参数,它默认会继承defaults里的配置;如果说后面的配置中和前边的defaults中的配置重复了,那么就以后面的配置生效,也就是说后面的配置段优先级高于defaults里的配置;

proxies代理配置段中分三段配置,第一段是defaults配置段,这一段我们在上一篇博客中也说过,主要用于定义一些默认参数配置;第二段是frontend配置段,该段主要用来定义haporxy面向客户端怎样提供服务的;比如监听在那个地址的那个端口啊,调度那个后端服务器组呀等等;第三段就是后端服务器的配置段,通常frontend和backend是联合使用,也就是说frontend必须调用一个已经定义好的backend这样才能够完全的把用户的请求调度到对应服务器或者服务器组上;而对于listen来讲,它更像一个代理的角色,它既可以定义前端对于用户端监听地址信息,同时它也能定义后端server的属性;简单讲listen指令融合了frontend和backend的功能;了解了如何定义前端监听地址以及后端被代理的server的方式后,接下来我们一一来看下代理配置段中的配置;

HAProxy常用的负载均衡策略有:

  • 轮询(Round Robin):每个请求按顺序轮流分配给后端服务器,这是最常用的策略之一。

  • 最少连接(Least Connections):请求被分配给当前连接数最少的后端服务器。这种策略适用于后端服务器处理能力相近的情况。

  • 最少响应时间(Least Time):请求被分配给当前响应时间最短的后端服务器。这种策略适用于后端服务器处理能力不均衡的情况。

  • 哈希(Hash):请求被分配给通过对某个属性进行哈希计算得到的桶中的后端服务器。这种策略适用于后端服务器数量较多的情况。

haproxy配置分为五部分,分别如下:

  • global : 全局配置主要用于设定义全局参数,属于进程级的配置,通常和操作系统配置有关

  • default : (配置默认参数,这些参数可以被用到frontend,backend,Listen组件)
    在此部分中设置的参数值,默认会自动引用到下面的frontend、backend、listen部分中,因引,某些参数属于公用的配置,只需要在defaults部分添加一次即可。而如果frontend、backend、listen部分也配置了与defaults部分一样的参数,Defaults部分参数对应的值自动被覆盖。

  • frontend:( 接收请求的前端虚拟节点,Frontend可以更加规则直接指定具体使用后端的backend)
    frontend是在haproxy 1.3版本以后才引入的一个组件,同时引入的还有backend组件。通过引入这些组件,在很大程度上简化了haproxy配置文件的复杂性。forntend可以根据ACL规则直接指定要使用的后端backend。

  • backend : (后端服务集群的配置,真实服务器,一个Backend对应一个或者多个实体服务器)
    在HAProxy1.3版本之前,HAProxy的所有配置选项都在这个部分中设置。为了保持兼容性,haproxy新的版本依然保留了listen组件配置试。两种配置方式任选一中。

  • Listen : (Fronted和backend的组合体) 比如haproxy实例状态监控部分配置

原博客
haproxy官网
使用详解
其他使用案例
较全配置教程及解析博客
单个配置详细解释博客


global

例 :

在这里插入图片描述

以上是haproxy1.5.18yum安装里默认提供的global配置段;

其他示例 :

global
    log 127.0.0.1     local3            #定义haproxy日志输出设置
    log 127.0.0.1   local1 notice        
    #log    loghost    local0 info     #定义haproxy 日志级别
    ulimit-n    82000                  #设置每个进程的可用的最大文件描述符
    maxconn    20480                   #默认最大连接数
    chroot    /usr/local/haproxy       #chroot运行路径
    uid 99                          #运行haproxy 用户 UID
    gid 99                          #运行haproxy 用户组gid
    daemon                          #以后台形式运行harpoxy
    nbproc    1                        #设置进程数量
    pidfile    /usr/local/haproxy/run/haproxy.pid  #haproxy 进程PID文件
    #debug                          #haproxy调试级别,建议只在开启单进程的时候调试
    #quiet

log :其中log是用来指定日志的,haproxy的日志和nginx的日志不太一样;nginx的日志是我们用access_log 指令来指定日志文件和调用日志格式的名称,意思就是把日志以增量的方式往指定的日志文件中写;而haproxy的日志不是自己记录日志,而是通过把日志发送给rsyslog服务器上的一个facility上,然后通过rsyslog的配置把指定facility上的日志记录到某个文件中或者数据中;

以上配置段意思就是把haproxy的日志发送给本机的rsyslog上的local2 记录所有级别类型的日志;

其实我们不用配置rsyslog,默认会把日志记录到/var/log/messages这个文件中,这是因为rsyslog中明确定义了所有facility上的info级别以及info级别以上的日志都记录到/var/log/messages中;

有关rsyslog的配置说明

chroot:该指令主要作用同vsftpd里面的chroot类似,禁锢运行目录的;一般这个参数主要是防止haproxy被恶意程序攻击后对操作系统上的其他路径资源的破环;也就是说即便haproxy被恶意程序攻破,最多只能破环我们指定的chroot目录,而非整个系统目录结构;通常情况下haproxy不会出现这种情况,为了安全我们还是配置上这个参数;如果haproxy是我们手动编译安装的,通常我们会把这个参数的值设置成很haproxy的程序编译安装时指定的目录;yum安装的基本上都是/var/lib/haproxy;一般都不会去更改它;

pidfile:该指令是指定pid文件的,通常情况下需要和unit file里指定的pid文件是同一个文件;不是同一个文件的话可能会遇到无法reload的情况;

maxconn:该指令指定haproxy的单个进程最大并发连接数;

user/group:前者用来指定运行haproxy进程的用户(属主),后者是用来指定运行进程的用户属组

uid/gid:前者用来指定运行haproxy工作进程的用户id,后者是指定组id;以上两种方式都是来指定运行haproxy进程的用户身份;默认情况是用的id为99的用户(nobody用户)

deamon:此指令表示haproxy以守护进程运行;

stats socket:指定unix socket文件路径;主要用于本机交互的方式管理haproxy;

以上是haproxy1.5.18配置文件中global段配置选项的说明;在haproxy1.8.0以后的版本中,haproxy支持多进程多线程的方式,而1.5不支持多线程,支持多进程,但是在1.5上启用多进程的方式是串行的,意思就是它不是一个主进程下生成多个子进程,而是一个进程下生成一个进程,然后子进程下在生成子进程的方式;所以如果要使用多进程的方式,建议还是使用1.8以后的版本;

配置多进程

nbproc:该指令是用于指定haproxy的进程数 ,通常情况下建议同cup核心数一样即可;
  
cpu-map:该指令用于绑定haproxy对应cup核心;有点类似nginx里的worker_cpu_affinity参数的意义;

例 :

nbproc 4
cpu-map 1 0
cpu-map 2 1
cpu-map 3 2
cpu-map 4 3

以上配置表示指定haproxy的进程数为4个,第一个进程绑定到0号核心上,第二个进程绑定到1号核心上,依次类推;如下

在这里插入图片描述
以上是haproxy1.8.20上配置使用多进程,启动进程情况,我们可以看到haproxy进程的父进程都是5945;

在1.5.18上使用多进程 :
在这里插入图片描述
以同样的配置在haproxy1.5.18上,启动的多进程就不一样,在1.5.18上多了一个haproxy-systemd这个进程,并且haproxy进程都是它的子进程,而我们用nbproc指定的进程数是指定haproxy-systemd下的haproxy的子进程数;而1.8.20nbproc指定的是haproxy的子进程数量,没有haproxy-systemd,又或者我们可以理解为1.8.20把1.5.18上的haproxy-systemd和haproxy进程合并成一个进程haproxy;通常情况下haproxy单进程也是足够用了,如果是在要开多进程,建议还是使用1.8以上的版本吧;

使用多线程

haproxy的多线程是在1.7以后的版本才支持的,所以1.5上面不支持多线程的方式,所以这里的演示就用haproxy1.8.20来演示

其它配置不变,新增 :

nbthread:指定每个haproxy进程开启的线程数;

maxsslconn:该指令指定每个haproxy进程ssl最大连接数,通常情况下证书都不放在haproxy上,nginx上放证书更加合适;

maxconnrate:该指令指定每个进程每秒最大连接数;

spread-checks:该指令指定后端server状态check随机提前或延迟百分比时间;通常情况下在后端主机较多的情况下使用;官方建议2-5(20%-50%)之间;如果在后端主机较多的情况下,不使用该指令来延迟对后端主机健康状态检查,那么很有可能降低haproxy的性能,因此该指令在后端主机较多的情况下(比如1000台甚至更多)能够避免同时并发对后端主机check时对haproxy的性能影响;

例 :

nbthread 4
nbproc 4
cpu-map 1 0
cpu-map 2 1
cpu-map 3 2
cpu-map 4 3

以上配置表示启动4个进程,每个进程里启动4个线程,默认每个进程一个线程

在这里插入图片描述

proxies代理配置中defaults

例 :

defaults
    log    global                      #引入global定义的日志格式
    mode    http                       #所处理的类别(7层代理http,4层代理tcp)
    maxconn 50000                      #最大连接数
    option  httplog                    #日志类别为http日志格式
    option  httpclose                  #每次请求完毕后主动关闭http通道
    option  dontlognull                #不记录健康检查日志信息
    option  forwardfor                 #如果后端服务器需要获得客户端的真实ip,需要配置的参数,可以从http header 中获取客户端的IP
    retries 3                          #3次连接失败就认为服务器不可用,也可以通过后面设置

    option redispatch                  #《---上述选项意思是指serverID 对应的服务器挂掉后,强制定向到其他健康的服务器,                     当使用了cookie时,haproxy将会将其请求的后端服务器的serverID插入到cookie中,以保证会话的SESSION持久性;而此时,如果后端的服务器宕掉了,但是客户端的cookie是不会刷新的,如果设置此参数,将会将客户的请求强制定向到另外一个后端server上,以保证服务的正常---》    
    stats                 refresh 30               #设置统计页面刷新时间间隔
    option               abortonclose            #当服务器负载很高的时候,自动结束掉当前队列处理比较久的连接
    balance             roundrobin                 #设置默认负载均衡方式,轮询方式
    #balance           source                    #设置默认负载均衡方式,类似于nginx的ip_hash      
    #contimeout      5000                    #设置连接超时时间
    #clitimeout        50000                   #设置客户端超时时间
    #srvtimeout       50000                   #设置服务器超时时间
    timeout     http-request          10s      #默认http请求超时时间
    timeout     queue                   1m       #默认队列超时时间
    timeout     connect                 10s      #默认连接超时时间
    timeout     client                     1m       #默认客户端超时时间
    timeout     server                   1m       #默认服务器超时时间
    timeout     http-keep-alive     10s      #默认持久连接超时时间
    timeout     check                   10s      #设置心跳检查超时时间

mode:该指令用于指定haporxy的工作类型的;

  • http表示haproxy基于http协议代理后端服务器,这也是默认haproxy的工作类型;如果我们在后端backend或listen中没有配置haporxy的工作类型,默认就会继承defaults里的配置。
  • tcp表示haproxy基于tcp协议代理后端服务器响应客户端请求,在此模式下,客户端和服务器端之前将建立一个全双工的连接,不会对七层报文做任何检查,默认为tcp模式,经常用于SSL、SSH、SMTP等应用。
  • health:已基本不用了。

option redispatch :当后
端server宕机后,强制把请求定向到其他健康的服务器上;正是因为这个参数,就确保了用户端请求不会被调度到一个宕机的服务器上;

option abortonclose:当服务器负载很高的时候,自动结束掉当前队列处理比较久的链接;

option http-keep-alive 60:开启会话保持,并设置时长为60s

option forwardfor [ except <network> ] [ header <name> ] [ if -none ]:开启IP透传;这个参数的意思是把客户端的源ip信息通过X-Forwarded-For首部传给后端server,后端server可通过扑捉haproxy发来的请求报文,把对应X-Forwarded-For首部的值记录下来;通常需要后端服务器更改日志格式,把对应首部的值加入到日志中显示;

可以定义在defaults、frontend、backend、listen4个区段

允许在发往服务器的请求首部中插入“X-Forwarded-For”首部。默认情况下,由于客户端的请求是经由haproxy发往后端server的,因此后端server日志中记录的client都是haproxy server的地址,有了option forwardfor 选项,可以让后端server日志记录真实的client地址,但server端日志格式需要修改。

< network>:可选参数,当指定时,源地址为匹配至此网络中的请求都禁用此功能。

< name>:可选参数,可使用一个自定义的首部,如“X-Client”来替代“X-Forwarded-For”。有些独特的web服务器的确需要用于一个独特的首部。

if-none:仅在此首部不存在时才将其添加至请求报文问道中。

timeout connect 60s:转发客户端请求到后端server的最长连接时间;这个时间是定义代理连接后端服务器的超时时长;

timeout server 600s :转发客户端请求到后端服务端的超时超时时长;这个时间是服务端响应代理的超时时长;

timeout client 600s :与客户端的最长空闲时间;

timeout http-keep-alive 120s:session 会话保持超时时间,范围内会转发到相同的后端服务器;

timeout check 5s:对后端服务器的检测超时时间;

retries 3:定义重试次数;

maxconn 3000 :server的最大连接数(通常这个会配置在各server后面,用来指定该server的最大连接数)


frontend & backend

以上就是haproxy defaults配置段的常用配置说明和使用;接下来我们来说一下frontend 配置段和backend配置段

frontend myweb 
	bind *:80,:8080
	default_backend webservers
backend webservers
	server web1 172.17.0.2:80
	server web2 172.17.0.3:80
	server web3 172.17.0.4:80

frontend配置段里的指令配置

bind:该指令用于指定绑定IP和端口的,通常用于frontend配置段中或listen配置段中;用法是bind [IP]:,……

  • 上面例配置表示前端监听80端口和8080端口,这两个端口都可以把用户端请求代理到后端指定的服务器组上进行响应;

  • 除此以外,前端监听端口我们也可以不用bind参数指定 我们直接在frontend 或listen名字后面加要监听的地址和端口即可,如下所示

  frontend myweb *:80,:8080
	default_backend webservers

listen的配置(见下文)也是支持以上两种的形式去监听端口的;通常不写IP地址表示监听本机ip地址对应的端口;

balance:指定后端服务器组内的服务器调度算法;这个指令只能用于listen和backend或者defaults配置段中;

详细负载模式

示例:使用uri算法,并指定使用一致性hash算法

frontend myweb 
	bind *:80,:8080
	default_backend webservers
backend webservers
	balance uri
	hash-type consistent
	server web1 172.17.0.2:80
	server web2 172.17.0.3:80
	server web3 172.17.0.4:80
listen myweb *:80,:8080
	balance uri
	hash-type consistent
	server web1 172.17.0.2:80
	server web2 172.17.0.3:80
	server web3 172.17.0.4:80

这样配置后,用户访问80端口的某一个uri始终会发往同一台服务器上;不管是那个用户去访问都会被调度到同一台服务器上进行响应

use_backend <backend>:调用对应的backend,用于frontend中;

default_backend <backend>:设定默认的backend,用于frontend中;在没有匹配的"use_backend"规则时为实例指定使用的默认后端,因此,其不可应用于backend区段。在"frontend"和"backend"之间进行内容交换时,通常使用"use-backend"定义其匹配规则;而没有被规则匹配到的请求将由此参数指定的后端接收。

frontend myweb 
	bind *:80,:8080
	use_backend webservers
	default_backend webservers
backend webservers
	balance uri
	hash-type consistent
	server web1 172.17.0.2:80
	server web2 172.17.0.3:80
	server web3 172.17.0.4:80

以上配置表示用户访问80端口或8081端口,都会被调度到webservs这个后端服务器组上进行响应;

server <name> <address>[:[port]] [param*]:定义后端主机的各服务器及其选项;name表示服务器在haproxy上的内部名称;出现在日志及警告信息中;address表示服务器地址,支持使用主机名;port:端口映射;省略时,表示同bind中绑定的端口;param表示参数;常用的参数有如下几个:

  • maxconn < maxconn>:当前server的最大并发连接数;
  • backlog < backlog>:当前server的连接数达到上限后的后援队列长度;
  • backup:设定当前server为备用服务器;和nginx里的sorry server 是一样的;
  • cookie < value>:为当前server指定其cookie值,用于实现基于cookie的会话黏性;
  • disabled:标记为不可用;相当于nginx里的down;
  • redir < prefix>:将发往此server的所有GET和HEAD类的请求重定向至指定的URL;
  • weight < weight>:权重,默认为1,最大值为256,0表示不参与负载均衡;
  • on-error < mode>:后端服务故障时采取的行动策略;策略有如下几种:
    • fastinter:表示缩短健康状态检测间的时长;
    • fail-check:表示即健康状态检测失败,也要检测;这是默认策略;
    • sudden-death:模拟一个致命前的失败的健康检查,一个失败的检查将标记服务器关闭,强制fastinter
    • mark-down:立即标记服务器不可用,并强制fastinter;
  • check:对当前server做健康状态检测;
    • addr :检测时使用的IP地址;
    • port :针对此端口进行检测;
    • inter < delay>:连续两次检测之间的时间间隔,默认为2000ms;
    • rise < count>:连续多少次检测结果为“成功”才标记服务器为可用;默认为2;
    • fall < count>:连续多少次检测结果为“失败”才标记服务器为不可用;默认为3;

例 :

frontend myweb :80,:8081
	use_backend webservs
backend webservs
	balance roundrobin
	hash-type consistent
	server web1 172.17.0.2:80 check inter 3000 fall 2 rise 5 weight 2 maxconn 1000 on-error mark-down
	server web2 172.17.0.3:80 backup
	server web3 172.17.0.4:80 redir http://nginx.org

以上配置表示对web1进行健康状态检测 每隔3000毫秒检测一次,检测2次失败就立刻标记为不可用,并强制缩短检测间隔时长;权重为2,意思是该服务器被调度两次,其他服务器调度一次;最大连接为1000;
web2配置为backup角色,只有当web1和web3宕机后,web2才被调度;
访问web3的请求直接重定向到http://nginx.org上响应;接下来我们如果访问haproxy的80或8081端口,应该是可以访问到web1和web3;如果web1和web3宕机后,web2就会被调度;

我们把web1和web3给停了,用浏览器访问,它还是跳转了;这说明redir不关心所在server是否存活,它都会做跳转,只不过所在server存活的情况下,用户请求偶尔几次会不跳转,但一定会有跳转的情况;这样来说吧,只要有跳转所在server,且没有做健康状态检测,那么不管该组是否有存活server backup都是不能被激活的;要想backup被激活必须让haproxy知道对应后端服务器组里是否有活跃的服务器,如果有,它就不会激活backup,如果没有就会激活;但现在haproxy不知道,原因是web3压根没有做健康状态检测;所以要想激活backup,我们需要在web3上配置一个check即可

	server web3 172.17.0.4:80 redir http://nginx.org check 	

redir和check建议不要一起用,一起用的话,对应redir就会失效;


状态页相关

stats enable:开启状态页;该指令可以配置在frontend或者listen或者backend,如果定义在backend中,那么我们必须要用前端去调用该banckend才能够看到状态页,所以通常我们都定义在listen中或者frontend中;具体示例如下

frontend stats_page
	bind *:80
	use_backend stats
	default_backend stats
backend stats
	server web1 172.17.0.2:80
	server web2 172.17.0.3:80
	server web3 172.17.0.4:80
	stats enable

定义在backend中必须要用frontend去调用该backend;

定义在 frontend :

frontend stats_page
	bind *:80
	stats enable
backend stats
	server web1 172.17.0.2:80

定义在listen中 :

listen stats_page *:80
	stats enable

以上三种方式都不影响访问状态页面,推荐配置在fonrtend或listen中;

配置好stats enable参数后,重启haproxy,我们就可以通过浏览器访问haproxy所在主机的对应端口,我这里监听在80端口上,所以访问http://IP:81/haporxy?stats就可以访问到状态页;

之所以访问/haproxy?stats这个uri才能够访问到状态页,是因为我们没有在配置文件中明确指定把状态页绑定到那个uri上,默认情况不指定就是这个/haproxy?stats,当然我们如果要指定需要用 stats uri < prefix> 来指定对应的rui即可

stats uri <prefix>:自定义stats page uri,默认值:/haproxy?stats

例 :

stats uri /admin?status

更改了uri后,默认的uri就不可以访问了,必须键入我们指定uri才可以被访问到,这在一定程度上降低了任何人访问状态页的风险;

stats auth ::配置状态页面认证的账号和密码,可使用多次;默认:no authentication,表示不验证

示例:配置状态页只允许admin用户访问并且密码为admin123.com

listen stats_page *:80
	stats enable 
	stats uri /admin?status
	stats auth admin::admin123.com

stats realm <realm>:设置认证时弹出输入用户名密码的提示信息;

例:

stats realm plz\ input\ username\ and\ passwd	

设定提示字符串需要把空白字符通过“\”转义,否则不会生效,加引号都不可以;

stats refresh <delay>:设置自动刷新时长;

stats admin { if | unless } <cond>:启用stats page中的管理功能

例 :

stats admin if TRUE

以上配置表示开启状态页管理功能,在条件为真的情况下,if TRUE表示一直为真,这意味着只要登录状态页,就有管理后端主机的权限。通常会通过后面的acl去控制,我这里为了演示方便,就用TRUE这个内置的ACL

stats hide-version:隐藏版本

状态页内容解释

默认健康状态检测是通过对后端server做tcp连接探测从而来判断后端server是否健康;如果对应后端server的IP地址或端口不通时,haproxy就认为该server不健康;其实这样判断不是不可以只是判断的力度不够精准;为了能够更加精准的检测后端server的健康状态,我们可以配置让其健康状态检测在应用层上做;比如对后端server上的某个url发起访问,如果能够正常响应,我们就认为后端server是健康的;

option httpchk :自定义健康检查url;可以配置defaults配置段中,可以配置在backend配置段中和listen配置段中,不可用配置在frontend配置段中;

通过GET方法对/index.html发起访问,如果能正常响应则后端server健康,反之亦然:

例 :

frontend stats_page
	bind *:80
	stats enable
backend stats
	server web1 172.17.0.2:80
	option httpchk GET /index.html

当后端server恢复正常时,在状态也上对应主机会从down状态慢慢转向up状态,知道几次检查都通过后,才完全把down状态的server转换为active up;这意味着必须要通过几次检查通过后该server才可上线提供服务;

stat socket < file> :将监控页面信息绑定到一个socket文件上;

haproxy的状态页的配置可通过鼠标点击去管理后端server;这样一来在对于我们想要监控haproxy本身以及后端server就是一个难题;haproxy的全局配置段中有一个stat socket 这样的配置。我们可以通过对该socket文件发送特定指令,实现操作haproxy的目的。我们接下来说说这个配置使用。

例 :

listen stats_page *:80
	stats enable 
	stats socket /var/lib/haproxy/stats

示例:通过socat向/var/lib/haproxy/stats传递help信息,让其打印帮助页面

[root@docker_node1 ~]# echo "help"|socat stdio /var/lib/haproxy/stats
Unknown command. Please enter one of the following commands only :
  clear counters : clear max statistics counters (add 'all' for all counters)
  clear table    : remove an entry from a table
  help           : this message
  prompt         : toggle interactive mode with prompt
  quit           : disconnect
  show info      : report information about the running process
  show pools     : report information about the memory pools usage
  show stat      : report counters for each proxy and server
  show errors    : report last request and response errors for each proxy
  show sess [id] : report the list of current sessions or dump this session
  show table [id]: report table usage stats or dump this table's contents
  get weight     : report a server's current weight
  set weight     : change a server's weight
  set server     : change a server's state or weight
  set table [id] : update or create a table entry's data
  set timeout    : change a timeout setting
  set maxconn    : change a maxconn setting
  set rate-limit : change a rate limiting value
  disable        : put a server or frontend in maintenance mode
  enable         : re-enable a server or frontend which is in maintenance mode
  shutdown       : kill a session or a frontend (eg:to release listening ports)
  show acl [id]  : report available acls or dump an acl's contents
  get acl        : reports the patterns matching a sample for an ACL
  add acl        : add acl entry
  del acl        : delete acl entry
  clear acl <id> : clear the content of this acl
  show map [id]  : report available maps or dump a map's contents
  get map        : reports the keys and values matching a sample for a map
  set map        : modify map entry
  add map        : add map entry
  del map        : delete map entry
  clear map <id> : clear the content of this map
  set ssl <stmt> : set statement for ssl
 
[root@docker_node1 ~]#

通过socket命令把web1标记为disable
在这里插入图片描述
执行把web1标记为disable,系统提示我们没有权限;接下来我们来配置权限即可

listen stats_page *:80
	stats enable 
	stats socket /var/lib/haproxy/stats mode 600 level admin

以上配置表示该socket文件具有admin权限,接下来在来把web1标记为disable(修改haproxy配置文件,需要重启haproxy )修改了权限以后,现在执行之前命令就没有报什么权限之类的错误了,接下来我们打开状态页,看看web1的状态是什么

示例:列出监控页面指标数据的信息

[root@docker_node1 ~]# echo "show info " |socat stdio /var/lib/haproxy/stats
Name: HAProxy
Version: 1.5.18
Release_date: 2016/05/10
Nbproc: 4
Process_num: 3
Pid: 6374
Uptime: 0d 0h05m04s
Uptime_sec: 304
Memmax_MB: 0
Ulimit-n: 8039
Maxsock: 8039
Maxconn: 4000
Hard_maxconn: 4000
........

上线web1:

在这里插入图片描述

web1就已经正常上线了;通过这样的方式动态的去管理后端server,就可以实现很多功能,比如通过zabbix去监控haproxy里的状态指标;通过脚本动态的上线和下线server、动态的修改后端server的权重(这个需要根据算法来,如果调度算法是动态的就支持,静态的就不支持);


cookie

haproxy cookie

cookie是用来让服务端辨识客户端的一种机制;而对于haproxy来讲,基于cookie来做会话保持的原理就是通过对后端服务器响应报文中的cookie信息中添加(或覆盖的方式)一个键值对,在客户端下次访问时,检查对应cookie首部的信息,从而让haproxy能够判断把该请求调度在那个后端服务器上;通常我们会在server上设置一个cookie的值,在listen或backend中设置一个cookie的键,明确说明以怎样的方式设置cookie的键;通过listen或backend中设置的cookie的键结合server后面的cookie的值组成的cookie信息,从而实现不同的cookie信息调度到不同的server上去;

例子:

在这里插入图片描述

以上cookie COOKIE insert nocache表示在后端服务器响应报文首部中添加一个cookie的名称为COOKIE,而对应cookie的值就来源于后面server中的cookie的值;nocache表示该cookie不被共有缓存系统缓存;

重启haproxy,用浏览器访问看看响应首部有什么变化:

在这里插入图片描述

当客户端第一次访问时,响应首部set-Cookie中就会设置一个COOKIE=web1的值;这个值就是我们刚才在haproxy配置的,从这个值上看,我们本次访问被调度到web1上了,之后我们再次访问时,就不会被调度到其他服务器上,在cookie过期之前始终都会被调度到web1上响应;这是因为下次我们访问时,会自动把这个cookie信息携带上;如下

在这里插入图片描述

正是因为我们携带的cookie信息是COOKIE=web1和haproxy上的web1上的cookie的值相同,所以我们只要携带COOKIE=web1就会被调度到web1上;

用curl 模拟cookie信息访问不同后端服务器:

在这里插入图片描述
通过不同的cookie信息,就可以访问到不同后端server了;这样就实现了基于cookie信息来把相同cookie的请求发送给同一后端server的目的;实现了会话保持;

reqadd :在请求报文中添加一些特定的首部发送给后端服务器,这就好比两个人传话,对于后面的人,中间传话的人可以添油加醋,当然也可以一字不差的把原话传给后面的人;对于后端服务器的响应也是一样的道理,haproxy可以让客户端看到某些首部,也可以让客户端看不到某些首部;

添加请求首部via: haproxy

frontend myweb 
	bind *:80,:8080
	default_backend webservers
backend webservers
	server web1 172.17.0.2:80
	reqadd via:\ haproxy

reqdel : 删除请求报文中的首部
reqidel : 删除请求报文中的首部,不区分大小写

例 : 删除请求报文中的User-Agent首部

frontend myweb 
	bind *:80,:8080
	default_backend webservers
backend webservers
	server web1 172.17.0.2:80
	reqdel User-Agent.*

删除操作通常是基于一匹配模式来做的,意思就是被该模式匹配到的首部都会删除

rspadd添加响应报文

例 :在响应报文添加一首部,名称为x-via 值为haproxy-1.5.18

frontend myweb 
	bind *:80,:8080
	default_backend webservers
backend webservers
	server web1 172.17.0.2:80
	rspadd x-via:\ haproxy-1.5.18

返回报文 :
在这里插入图片描述

rspdel删除响应报文中首部,区分字符大小写的;
rspidel删除响应报文中首部,不区分字符大小写匹配到的响应首部

例 :删除响应报文中server首部

frontend myweb 
	bind *:80,:8080
	default_backend webservers
backend webservers
	server web1 172.17.0.2:80
	rspidel server.*

启用压缩功能

haproxy启用压缩功能同nginx的原理类似,在nginx里我们需要明确配置启动压缩功能,支持那些压缩算法,最小压缩大小以及压缩级别等等;在haproxy中要启用压缩功能我们只需要指定压缩算法,以及压缩资源类型即可;

示例:指定压缩算法是gzip,压缩资源类型为文本类型资源text/html text/plain

frontend myweb 
	bind *:80,:8080
	default_backend webservers
	compression algo gzip
	compression type text/html text/plain
backend webservers
	server web1 172.17.0.2:80
	rspidel server.*

结果示例

测试结果看,在响应报文中能够看到Content-Encoding: gzip首部,这意味着压缩功能已经启用;除了gzip压缩算法以外还有常用的压缩算法还有deflate;


错误页

haproxy同nginx是一样可自定义错误页面;在nginx里我们用error_page 指令来指定对应错误状态码加location,根据错误状态码指定的location来指定对应错误状态码的状态页面文件;haproxy自定义错误页面的思想类似,不同的是nginx作为web服务器可以自定义404错误页面,而haproxy通常作为代理服务器,对于404错误页面通常不会由haproxy自己指定,因为haproxy作为代理服务器对于后端server的资源是否能够找到,它不知道;即便我们在配置中指定了404错误对应的响应页面,在haproxy重启后是不会生效的;

haproxy指定错误页面的方式两种,第一种是指定本地文件系统文件作为对应错误状态码的错误页;第二种是指定对应错误状态码跳转的URL;

errorfile <code> <file>:指定对应错误状态码对应文件系统上的文件作为该状态码响应的页面

例 :自定义错误403的错误页面,页面地址/etc/haproxy/error403.html

frontend myweb 
	bind *:80,:8080
	default_backend webservers
backend webservers
	server web1 172.17.0.2:80
	errorfile 403 /etc/haproxy/error403.html

errorloc <code> <url>errorloc302 <code> <url>

< code>:指定对HTTP的哪些状态码返回指定的页面;这里可用的状态码有200、400、403、408、500、502、503和504;

< url>:Location首部中指定的页面位置的具体路径,可以是在当前服务器上的页面的相对路径,也可以使用绝对路径;需要注意的是,如果URI自身错误时产生某特定状态码信息的话,有可能会导致循环定向;

errorloc和errorloc302 两种方法效果一致,都是以临时重定向到指定的url上

例 : 对于403错误就跳转到指定http://nginx.org/aaa.html

frontend myweb 
	bind *:80,:8080
	default_backend webservers
backend webservers
	server web1 172.17.0.2:80
	errorloc 403 http://nginx.org/aaa.html

例 : 对于403错误就跳转到指定http://nginx.org/aaa.html,返回改为400

frontend myweb 
	bind *:80,:8080
	default_backend webservers
backend webservers
	server web1 172.17.0.2:80
	errorloc400 403 http://nginx.org/aaa.html

这里还需要注意一点,这两种方式都是跳转前请求的方法是什么,跳转对应url也是同样的方法,都会返回302状态码,;这样一来对于其他非GET方法请求出现403错误码的时候,对应的错误页就无法正常处理(通常只允许GET方法去请求别的URL);比如跳转前用PUT方法,出现错误403后,按照上面的配置,对应指定的错误页的url也会用PUT方法去请求;为了解决这样的问题,我们这里需要用到errorloc303来指定;该指令的意思是返回303响应码;如果请求前非GET方法,而出现对应错误后,用GET方法去请求对应错误状态码指定的URL;

errorloc303 <code> <url>

frontend myweb 
	bind *:80,:8080
	default_backend webservers
backend webservers
	server web1 172.17.0.2:80
	errorloc303 403 http://nginx.org

以上配置就表示如果我们用非GET方法请求某资源,出现403错误后,返回303状态码;303表示请求重定向页面的方法要总是使用GET方法;

< code>:指定对HTTP的哪些状态码返回指定的页面;这里可用的状态码有400、403、408、500、502、503和504;

< url>:Location首部中指定的页面位置的具体路径,可以是在当前服务器上的页面的相对路径,也可以使用绝对路径;需要注意的是,如果URI自身错误时产生某特定状态码信息的话,有可能会导致循环定向


日志

haproxy日志配置可以在 defaults、frontend、listen、backend4个配置段中定义。也可以使用global全局配置。

log:启用事件和流量的每个实例日志记录。

no log:关闭日志记录;

log global:调用全局配置段中日志的定义;

log<address> [len <length>] <facility> [<level> [<minlevel>]]:定义一个用于接收haproxy日志的rsyslog服务器地址,facility;默认是发往本机的rsyslog服务器上的local2上;有关rsyslog的相关说明参考

log-format <string>:设定日志格式;日志格式的设定变量表请参照下表

+---+------+-----------------------------------------------+-------------+
| R | var  | field name (8.2.2 and 8.2.3 for description)  | type        |
+---+------+-----------------------------------------------+-------------+
|   | %o   | special variable, apply flags on all next var |             |
+---+------+-----------------------------------------------+-------------+
|   | %B   | bytes_read           (from server to client)  | numeric     |
| H | %CC  | captured_request_cookie                       | string      |
| H | %CS  | captured_response_cookie                      | string      |
|   | %H   | hostname                                      | string      |
|   | %ID  | unique-id                                     | string      |
|   | %ST  | status_code                                   | numeric     |
|   | %T   | gmt_date_time                                 | date        |
|   | %Tc  | Tc                                            | numeric     |
|   | %Tl  | local_date_time                               | date        |
| H | %Tq  | Tq                                            | numeric     |
| H | %Tr  | Tr                                            | numeric     |
|   | %Ts  | timestamp                                     | numeric     |
|   | %Tt  | Tt                                            | numeric     |
|   | %Tw  | Tw                                            | numeric     |
|   | %U   | bytes_uploaded       (from client to server)  | numeric     |
|   | %ac  | actconn                                       | numeric     |
|   | %b   | backend_name                                  | string      |
|   | %bc  | beconn      (backend concurrent connections)  | numeric     |
|   | %bi  | backend_source_ip       (connecting address)  | IP          |
|   | %bp  | backend_source_port     (connecting address)  | numeric     |
|   | %bq  | backend_queue                                 | numeric     |
|   | %ci  | client_ip                 (accepted address)  | IP          |
|   | %cp  | client_port               (accepted address)  | numeric     |
|   | %f   | frontend_name                                 | string      |
|   | %fc  | feconn     (frontend concurrent connections)  | numeric     |
|   | %fi  | frontend_ip              (accepting address)  | IP          |
|   | %fp  | frontend_port            (accepting address)  | numeric     |
|   | %ft  | frontend_name_transport ('~' suffix for SSL)  | string      |
|   | %hr  | captured_request_headers default style        | string      |
|   | %hrl | captured_request_headers CLF style            | string list |
|   | %hs  | captured_response_headers default style       | string      |
|   | %hsl | captured_response_headers CLF style           | string list |
|   | %ms  | accept date milliseconds (left-padded with 0) | numeric     |
|   | %pid | PID                                           | numeric     |
| H | %r   | http_request                                  | string      |
|   | %rc  | retries                                       | numeric     |
|   | %rt  | request_counter (HTTP req or TCP session)     | numeric     |
|   | %s   | server_name                                   | string      |
|   | %sc  | srv_conn     (server concurrent connections)  | numeric     |
|   | %si  | server_IP                   (target address)  | IP          |
|   | %sp  | server_port                 (target address)  | numeric     |
|   | %sq  | srv_queue                                     | numeric     |
| S | %sslc| ssl_ciphers (ex: AES-SHA)                     | string      |
| S | %sslv| ssl_version (ex: TLSv1)                       | string      |
|   | %t   | date_time      (with millisecond resolution)  | date        |
|   | %ts  | termination_state                             | string      |
| H | %tsc | termination_state with cookie status          | string      |
+---+------+-----------------------------------------------+-------------+

capture {request|response} header捕获并记录指定请求或响应首部最近一次出现时的第一个值,捕获的首部值使用花括号{}括起来后添加进日志中如果需要捕获多个首部值,他们将以指定的次序出现在日志文件中,并以竖线"|"作为分隔符,不存在的首部记录为空字符串,最常需要捕获的首部有如下几个:
1、虚拟主机环境中使用的Host字段 2、上传请求首部中的Content-length字段
3、快速区别真实用户和网络机器人的User-agent字段 4、代理环境中记录真实请求来源的X-Forward-Forward-F字段
capture语法:capture request header len
< name>:要捕获的名称,不区分大小写,注意:记录在日志中是首部对应的值,而非首部名称
< length>:指定记录首部值时所记录的精确长度,超出的部分将会被忽略

capture cookie <name> len <length>:捕获并记录请求报文和响应报文中的cookie信息

capture request header <name> len <length>:捕获并记录指定请求标头的最后一次出现

capture response header <name> len <length>:捕获并记录指定响应标头的最后一次出现

< name>:要捕获的首部的名称,此名称不区分字符大小写,但建议与它们出现在首部中的格式相同,比如大写首字母。记录在日志中的是首部对应的值,而非首部名称。
< length>:指定记录首部值时所记录的精确长度,超出的部分将会被忽略。

可以捕获的请求首部的个数没有限制,但每个捕获最多只能记录64个字符。为了保证同一个frontend中日志格式的统一性,首部捕获仅能在frontend中定义。

配置示例:

frontend web
    bind *:80
    mode http
    capture request header Cache-Control  len 40   # 捕捉请求的域名
    capture request header Host           len 40   # 捕捉请求的域名
    capture request header User-Agent     len 16   # 捕捉请求的设备
    capture response header Server        len 40   # 捕捉响应的Server是什么
    
    use_backend webservers
backend webservers
    balance roundrobin
    server web1 172.16.1.7:80 check
    server web2 172.16.1.8:80 check

验证日志

#日志结果,关注{}中内容,第一个{}是request,第二个{}是response
haproxy: 10.0.0.100:48132 main webcluster/web2 {proxy.qingchen.com|curl/7.29.0}
haproxy: 10.0.0.100:48132 main webcluster/web2 {proxy.qingchen.com|curl/7.29.0} {nginx/1.18.0}

在haproxy配置中加入capture request header Host len 15的配置,如下:

frontend websrv *:80
     capture request header Host len 15
     default_backend    webservers
backend webservers
    cookie node insert nocache
    balance  roundrobin
    server node1  172.16.42.131:80 check cookie node1
    server node2  172.16.42.135:80 check cookie node2

对比前后日志格式:

Apr  6 18:15:54 localhost haproxy[2271]: 172.16.42.165:57495 [06 /Apr/2017 :18:15:54.605] websrv webservers /node1  177 /0/1/2/180  304 149 - - --VN 1 /1/0/0/0  0 /0  "GET /test3.html HTTP/1.1"
Apr  6 18:21:19 localhost haproxy[2351]: 172.16.42.165:57947 [06 /Apr/2017 :18:21:19.498] websrv webservers /node1  0 /0/0/1/1  304 149 - - --VN 1 /1/0/1/0  0 /0  {172.16.42.128}  "GET /test3.html HTTP/1.1"

多了 HOST {172.16.42.128}

haproxy最多只能使用2个日志配置,如果global中配置了两个日志服务器,那么在使用了全局配置后,如果还有其他自定义的日志配置,则不会生效

ACL

ACL(access control list)翻译过来就是访问控制列表;Linux里的权限里有ACL,httpd、nginx、varnish里都有ACL的概念;访问控制列表(ACL)的使用提供了一个灵活的解决方案来执行内容切换,并通常根据从请求、响应或任何环境状态提取的内容做出决策。

haproxy中访问控制实现和httpd、nginx、varnish中的访问控制类似,都是先扑捉用户的请求报文或响应报文,或者其他环境状态的信息来把客户端分类;然后把该ACL作为条件判断,把不同类别或者说符合我们定义ACL的客户端做其他操作;比如我们可以去扑捉用户的请求报文中的referer首部的信息,来判断本次请求的客户端是不是合法的客户端,合法就允许访问,不合法就拒绝访问或重定向到别的url上;至于是不是合法的客户端,这个需要我们明确的去定义acl实现;

Haproxy Acl官网

haproxy中ACL的定义语法:

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

acl是关键字,aclname是区别不同acl的标识;不同的acl是通过名称来区分的,相同名称的acl表示同一个acl,区分字符大小写,且其只能包含大小写字母、数字、-(连接线)、_(下划线)、.(点号)和:(冒号);haproxy中,acl可以重名,这可以把多个测试条件定义为一个共同的acl;

criterion表示判断基准的方法,以criterion指定的信息来分类不同客户端;flages表示标记,常用的标记有 -i表示不区分字符大小写;-m表示使用特定模式匹配方法;-n表示禁用DNS解析;-u表示强制ACL的唯一id;-f:从指定的文件中加载模式;

flags : 匹配模式

operator表示操作符,常用的操作符有;对于整数值的操作符有 eq(等于)、ge(大于等于)、gt(大于)、le(小于等于)、lt(小于);对于字符串的操作符有,精准匹配 -m str;子串匹配 -m sub;前缀匹配 -m beg;后缀匹配 -m end; 路径匹配 -m dir ;域名匹配 -m dom;

value表示操作对象类型,值得类型有布尔型,整数型,IP ,string,正则表达式,十六进制数;

criterion 常用的方法:

  • dst:表示目标ip
  • src:表示源ip
  • dst_port:表示目标端口
  • src_port:表示源端口
  • path:表示提取请求的URL路径,该路径从第一个斜杠开始,在问号之前结束(不包括主机部分)。
  • url:表示提取请求的整个URL路径;
  • req.hdr:表示提取用户请求报文中特定首部;
  • status:表示提取响应的状态码;

criterion其他匹配:

  • hdr_beg():用于测试请求报文的指定首部的开头部分是否符合指定的模式
    例子:
    acl host_static hdr_beg(host) -i img. video. download. ftp.
    测试请求是否为提供静态内容的主机img、video、download或ftp。

  • hdr_end():用于测试请求报文的指定首部的结尾部分是否符合指定的模式
    例子:
    acl host_static hdr_beg(host) -i .aa.com .bb.com

  • hdr_reg():正则匹配
    例子:
    acl bbs hdr_reg(host) -i ^(bbs.test.com|shequ.test.com|forum)

  • url_sub:表示请求url中包含什么字符串

  • url_dir:表示请求url中存在哪些字符串作为部分地址路径

  • path_beg: 用于测试请求的URL是否以指定的模式开头
    例子:
    acl url_static path_beg -i /static /iilannis /javascript /stylesheets
    用于测试URL是否以/static、/iilannis、/javascript或/stylesheets开头。

  • path_end:用于测试请求的URL是否以指定的模式结尾
    例子:
    acl url_static path_end -i .jpg .gif .png .css .js
    测试URL是否以.jpg、.gif、.png、.css或.js结尾。

acl作为条件时的逻辑关系:

AND 表示与关系;表示满足第一个acl的同时要满足第二acl 此条件才为真;通常用空白字符分隔两个ACL

OR表示与关系;表示满足acl1或acl2中的任意一个此条件就为真;通常用“||”分隔两个ACL

!表示非关系;表示对该ACL取相反的操作,意思就是非该acl此条件为真;

示例:拒绝源ip为192.168.0.21的请求访问

frontend websrv *:80
     default_backend    webservers
backend webservers
    balance  roundrobin
    server node1  172.16.42.131:80 check 
    server node2  172.16.42.135:80 check 
    acl block_ip src 192.168.0.21
    block if block_ip 

acl block_ip src 192.168.0.21表示定义一个acl,名称为block_ip ,提取客户端的源ip作为分类基准,其源ip的值为192.168.0.21;这意味着只要是源IP为192.168.0.21就会被该acl匹配,或者说源IP为192.168.0.21的请求满足block_ip这个ACL;block if block_ip表示拒绝满足block_ip这条ACL规则的请求;

block { if | unless } <condition>:表示7层拒绝,满足或不满足指定条件就拒绝;

frontend websrv *:80
     default_backend    webservers
backend webservers
    balance  roundrobin
    server node1  172.16.42.131:80 check 
    server node2  172.16.42.135:80 check 
    acl block_ip src 192.168.0.21
    block if block_ip 
    acl block_curl hdr(User-Agent) -m sub -i curl 
    block if block_curl 

以上表示定义一个acl其名称为block_curl 提取用户请求报文中的User-Agent首部的值做字串匹配,匹配不区分字符大小写,如果用户请求报文中包含curl子串,就表示满足我们定义的ACL,如果满足我们定义的block_curl规则,就拒绝;

再用curl去访问是被拒绝的,但是用wget去访问就完全正常,说明我们定义的acl用curl去访问是满足该acl,所以被拒绝了;

拒绝源地址为192.168.0.21并且User-Agent首部中包含curl字串的客户端访问:

    acl block_curl hdr(User-Agent) -m sub -i curl 
    acl block_ip src 192.168.0.21
    block if block_curl block_ip 

block_ip 和block_curl这两条ACL是逻辑与的关系,表示两个ACL都要被满足才能拒绝;满足其中一个就不能被拒绝的;

示例:拒绝源地址为192.168.0.21的访问或者请求报文User-Agent首部的值包含curl的访问

    acl block_curl hdr(User-Agent) -m sub -i curl 
    acl block_ip src 192.168.0.21
    block if block_curl || block_ip 

配置表示拒绝referer首部不包含test的域名字串的访问;其中hdr_dom(referer)同hdr(referer) -m dom是一样的;

    acl valid_referer hdr_dom(referer)  -i test
    block if block_curl || block_ip 

使用 curl --referer “www.test.com” http://192.168.0.22 就可以访问

在不加referer信息的访问时会被拒绝,这是因为请求报文中referer首部的值为空,不满足vaild_referer这条ACL,所以!valid_referer就为真,所以会被拒绝;加上referer访问就会被valid_referer匹配,!valid_referer就为假,所以访问就不会被拒绝;

利用ACL实现动静分离

frontend websrv *:80
	 acl url_static path_beg -i /static /images /javascript /stylesheets
	 acl url_static path_end -i .jpg .gif .png .css .js .htm1 .txt .htm
	 use_backend static_servs if url_static
     default_backend webservers
backend webservers
    server web1  172.16.42.130:80 check 
backend static_servs 
    balance  roundrobin
    server static1  172.16.42.131:80 check 
    server static2  172.16.42.132:80 check 

以上配置表示不区分字符大小写匹配用户请求的URI路径中以 /static /images /javascript /stylesheets 开头或者以 .jpg .gif .png .css .js .html .txt .htm 结尾的请求都归类于url_static这个ACL中。以上是两条同名的ACL,它俩会被haproxy识别成一条ACL,即两条ACL之间是或关系,表示满足其中一条即可

如果用户请求的URI路径满足定义的ACL,就把请求调度到static_servs这个后端组响应;不满足就默认调度到webservers这个后端组上进行响应;

HTTPS

在haproxy的配置文件中,我们要明确的声明监听某个端口,该端口需要ssl协议来访问,类似nginx里的listen 443 ssl配置;除此之外我们还需要用crt来指定证书;不同于nginx里的配置是haproxy的证书内容包含私钥信息;所以在我们申请好证书后,还需要把证书文件内容同私钥文件做合并;

frontend web_ssl 
	bind :443 ssl crt /etc/haproxy/ssl/haproxy.pem
    default_backend webservers
frontend web *:80
    default_backend webservers
backend webservers
    server static1  172.16.42.131:80 check 
    server static2  172.16.42.132:80 check 

bind :443 ssl crt /etc/haproxy/ssl/haproxy.pem 表示监听443端口,并明确指定使用ssl协议访问;证书文件是/etc/haproxy/ssl/haproxy.pem

把80端口的请求重向定443 :

frontend web *:80
    default_backend webservers
    redirect scheme https if !{ ssl_fc }

上面配置后我们访问用http去访问,在响应报文中会用location告诉浏览器去访问https://XXXX;这样一来就实现了全站https;

添加以下可向后端传递用户请求的协议和端口(frontend或backend)

http_request set-header X-Forwarded-Port %[dst_port]
http_request add-header X-Forwared-Protohttps if { ssl_fc }

以上内容表示向后端请求报文中设置X-Forwarded-port首部的值为dst_port变量的值;添加X-Forwared-Proto首部,其值为https,在请求协议是https的请求时;通常这两个设置是后端应用server要求使用https访问时需要把前端https请求通过X-Forwared-Proto传递给后端;

在后端server上配置日志格式,分别将这两个首部记录到日志,然后通过访问,查看日志中记录这两个首部的值是否是我们访问的443端口和https协议?

定义httpd的日志格式,分别记录{X-Forwarded-Port和X-Forwared-Proto首部的值:
在这里插入图片描述
用浏览器访问测试,看看日志中记录的信息:
在这里插入图片描述
可以看到日志中把对应访问端口和协议都传给了后端server;

四层负载

用tcp协议来代理后端server :

frontend mydb
	bind :3306 
	mode tcp
	blance source
    server db1  172.16.42.131:3306 check 
    server db2  172.16.42.132:3306 check 

此时用别的主机上的mysql客户端是可以正常访问haproxy监听的3306端口

tcp-request connection <command> 表示根据第4层条件对传入连接执行操作;

command : 允许访问用accept来标识,拒绝用reject;同http-request 类似,不同的是http-request允许是用allow标识,拒绝用deny标识;

例 : 以下配置表示拒绝源地址为192.168.100.11的连接

frontend mydb
	bind :3306 
	mode tcp
	blance source
    server db1  172.16.42.131:3306 check 
    server db2  172.16.42.132:3306 check 
    acl invaild_client src 192.168.100.11
    tcp-request connection reject if invaild_client 

仅开放源地址为192.168.100.11的主机访问,拒绝其他主机的访问:

frontend mydb
	bind :3306 
	mode tcp
	blance source
    server db1  172.16.42.131:3306 check 
    server db2  172.16.42.132:3306 check 
    acl invaild_client src 192.168.100.11
    tcp-request connection accept if invaild_client 
    tcp-request connection reject 

配置示例

  • 22
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值