HAProxy学习笔记

Posted 刘元涛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HAProxy学习笔记相关的知识,希望对你有一定的参考价值。

安装参考:https://my.oschina.net/liuyuantao/blog/5119858

HAProxy组成

程序环境:

主程序:/usr/sbin/haproxy
配置文件:/etc/haproxy/haproxy.cfg
Unit file:/usr/lib/systemd/system/haproxy.service

配置段:

global:全局配置段,进程及安全配置相关的参数,性能调整相关参数
proxies:代理配置段
defaults:为frontend, backend, listen提供默认配置
frontend:前端,相当于nginx中的server {}
backend:后端,相当于nginx中的upstream {}
listen:同时拥有前端和后端配置

配置段

Haproxy配置-global

chroot  #锁定运行目录
deamon  #以守护进程运行
#stats socket /var/lib/haproxy/haproxy.sock  mode 600 level admin   #socket文件
user, group, uid, gid  #运行haproxy的用户身份
nbproc   #开启的haproxy进程数,与CPU保持一致
nbthread  #指定每个haproxy进程开启的线程数,默认为每个进程一个线程
cpu-map 1 0 #绑定haproxy进程至指定CPU
maxconn    #每个haproxy进程的最大并发连接数
maxsslconn  #SSL每个haproxy进程ssl最大连接数
maxconnrate  #每个进程每秒最大连接数
spread-checks #后端server状态check随机提前或延迟百分比时间,建议2-5(20%-50%)之间,成百上千个后端服务器可加此选项。
pidfile#指定pid文件路径
log 127.0.0.1 local3 info #定义全局的syslog服务器;最多可以定义两个

自定义haproxy的log日志

1、在rsyslog.conf配置配置文件中开启log日志功能

[root@centos_17haproxy]#vim /etc/rsyslog.conf
$ModLoad imudp   #开启udp模式存放日志
$UDPServerRun 514 #开启端口
local3.* /var/log/haproxy.log  #存放haproxy日志路径

修改完rsyslog配置文件之后重新启动:

systemctl restart rsyslog

2、在haproxyd的global全局配置文件中修改对应的local3

log 127.0.0.1 local3

配置完之后重新启动haproxy服务:

systemctl restart haproxy

3、验证结果,此时修改后的配置文件中已经生成单独的log日志文件

[root@centos_17haproxy]#tail /var/log/haproxy.log
Dec 22 00:03:19 localhost haproxy[15460]: Proxy stats started.
Dec 22 00:03:19 localhost haproxy[15460]: Proxy web_port started.

HAProxy Proxies配置

•defaults [<name>] #默认配置项,针对以下的frontend、backend和lsiten生效,可以多个name
•frontend <name> #前端servername,类似于Nginx的一个虚拟主机server。
•backend <name> #后端服务器组,等于nginx的upstream
•listen <name> #将frontend和backend合并在一起配置

 注:name字段只能使用”-”、”_”、”.”、和”:”,并且严格区分大小写,例如:Web和web是完全不同的两组服务器。

Proxies配置-defaults

defaults 配置参数:

•option redispatch   #当server Id对应的服务器挂掉后,强制定向到其他健康的服务器
•option abortonclose  #当服务器负载很高的时候,自动结束掉当前队列处理比较久的链接
•option http-keep-alive 60  #开启会话保持
•option forwardfor   #开启IP透传
•mode http   #默认工作类型
•timeout connect 60s  #转发客户端请求到后端server的最长连接时间(TCP之前)
•timeout server 600s  #转发客户端请求到后端服务端的超时超时时长(TCP之后)
•timeout client 600s  #与客户端的最长空闲时间
•timeout http-keep-alive 120s  #session 会话保持超时时间,范围内会转发到相同的后端服务器
•#timeout check 5s  #对后端服务器的检测超时时间

Proxies配置-frontend配置参数

•bind:指定HAProxy的监听地址,可以是IPV4或IPV6,可以同时监听多个IP或端口,可同时用于listen字段中
•bind [<address>]:<port_range> [, ...] [param*]
•mode http/tcp #指定负载协议类型
•use_backend backend_name #调用的后端服务器组名称

 bind指令仅能用于frontend和listen区段,用于定义一个或几个监听的套接字。

① <address>:可选选项,其可以为主机名、IPv4地址、IPv6地址或*;省略此选项、将其指定为*或0.0.0.0时,将监听当前系统的所有IPv4地址;
② <port_range>:可以是一个特定的TCP端口,也可是一个端口范围(如5005-5010),代理服务器将通过指定的端口来接收客户端请求;需要注意的是,每组监听的套接字
③ <address:port>在同一个实例上只能使用一次,而且小于1024的端口需要有特定权限的用户才能使用,这可能需要通过uid参数来定义;
④ <interface>:指定物理接口的名称,仅能在Linux系统上使用;其不能使用接口别名,而仅能使用物理接口名称,而且只有管理有权限指定绑定的物理接口;

示例:

frontend WEB_PORT
    bind :80,:8080
    bind 192.168.7.102:10080,192.168.7.102:10043
    use_backend backend_name

Proxies配置-backend配置参数

•mode http/tcp #指定负载协议类型
•option #配置选项
•server #定义后端realserver

注意:option后面加httpchk,smtpchk, mysql-check, pgsql-check,ssl-hello-chk方法,可用于实现更多应用层检测功能。

示例:

backend backend_test
    mode http
    balance roundrobin
    server web1 192.168.153.102:80 check
    server web2 192.168.153.101:80 check
    server web3 192.168.153.103:80 check

后端服务器状态监测及相关配置

•check #对指定real进行健康状态检查,默认不开启
•addr IP  #可指定的健康状态监测IP
•port num  #指定的健康状态监测端口
•inter num  #健康状态检查间隔时间,默认2000 ms
•fall num  #后端服务器失效检查次数,默认为3
•rise num  #后端服务器从下线恢复检查次数,默认为2
•weight #默认为1,最大值为256,0表示不参与负载均衡
•backup #将后端服务器标记为备份状态
•disabled #将后端服务器标记为不可用状态
•redirect prefix http://www.magedu.com   #将请求临时重定向至其它URL,只适用于http模式
•maxconn <maxconn>:当前后端server的最大并发连接数
•backlog <backlog>:当server的连接数达到上限后的后援队列长度 

(mode http|tcp|health)设定实例的运行模式或协议。当实现内容交换时,前端和后端必须工作于同一种模式(一般说来都是HTTP模式),否则将无法启动实例。可以放在任何4段中 default frontent backent listen
① tcp:实例运行于纯TCP模式,在客户端和服务器端之间将建立一个全双工的连接,且不会对7层报文做任何类型的检查,通常用于SSL、SSH、SMTP等应用;
② http:实例运行于HTTP模式,7层,客户端请求在转发至后端服务器之前将被深度分析,所有不与RFC格式兼容的请求都会被拒绝;centos实际默认模式
③ health:实例工作于health模式,其对入站请求仅响应"OK"信息并关闭连接,且不会记录任何日志信息;此模式将用于响应外部组件的健康状态检查请求;目前来讲,此模式已经废弃,因为tcp或http模式中的monitor关键字可完成类似功能;可以用于测试
示例:

listen web
    mode http
    bind 192.168.37.17:80
    server web1 192.168.37.27:80 check weight 3  inter 3s fall 3 rise 5 #check后面命令是对haproxy进行状态检测
    server web2 192.168.37.37:80 check inter 3s fall 3 rise 5 backup
    redirect prefix http://www.magedu.com    临时重定向,只适用于http模式

frontend/ backend及Proxies配置-listen配置案例

使用listen替换frontend和backend的配置方式:

#官网业务访问入口======================================
frontend WEB_PORT_80
        bind 192.168.37.17:80
        mode tcp
        use_backend web_prot_http_nodes
backend web_prot_http_nodes
        mode http
        option forwardfor
        server 192.168.37.27:80 check inter 3000 fall 3 rise 5
        server 192.168.37.37:80 check inter 3000 fall 3 rise 5
 
frontend WEB_PORT_443
        bind 192.168.37.17:443
        mode tcp
        use_backend web_prot_http_nodes
backend web_prot_http_nodes
        mode http
        option forwardfor
        server  192.168.37.27:443 check inter 3000 fall 3 rise 5
        server  192.168.37.37:443 check inter 3000 fall 3 rise 5
 
#官网业务访问入口=====================================
listen WEB_PORT_80
        bind 192.168.37.17:80
        mode tcp
        option forwardfor
        server web1 192.168.37.17:80 check inter 3000 fall 3 rise 5
        server web2 192.168.37.27:80 check inter 3000 fall 3 rise 5
 
listen WEB_PORT_443
        bind 192.168.37.17:443
        mode tcp
        option forwardfor
        server web1 192.168.37.27:443 check inter 3000 fall 3 rise 5
        server web2 192.168.37.37:443 check inter 3000 fall 3 rise 5

HAProxy 调度算法 

balance:指明对后端服务器的调度算法,配置在listen或backend

静态算法:

按照事先定义好的规则轮询公平调度,不关心后端服务器的当前负载、链接数和相应速度等,且无法实时修改权重,只能重启后生效。

•static-rr:基于权重的轮询调度,不支持权重的运行时调整及后端服务器慢启动,其后端主机数量没有限制

•first:根据服务器在列表中的位置,自上而下进行调度,但是其只会当第一台服务器的连接数达到上限,新请求才会分配给下一台服务,因此会忽略服务器的权重设置。

#官网业务访问入口=====================================
listen WEB_PORT_80
        bind 192.168.37.17:80
        balance first
        mode tcp
        option forwardfor
        server web1 192.168.37.27:80 check inter 3000 fall 3 rise 5
        server web2 192.168.37.37:80 check inter 3000 fall 3 rise 5

动态算法:

基于后端服务器状态进行调度适当调整,比如优先调度至当前负载较低的服务器,且权重可以在haproxy运行时动态调整无需重启。

roundrobin:基于权重的轮询动态调度算法,支持权重的运行时调整,不等于lvs 的rr,支持慢启动即新加的服务器会逐渐增加转发数,每个后端backend中最多支持4095个server,此为默认调度算法,server 权重设置weight。

leastconn:加权的最少连接的动态,支持权重的运行时调整和慢启动,即当前后端服务器连接最少的优先调度,比较适合长连接的场景使用,比如mysql等场景,其并不太适用于较短会话的应用层协议。

roundrobin示例:

listen WEB_PORT_80
        bind 192.168.37.17:80
        #balance first
        balance roundrobin  默认是此算法
        mode tcp
        option forwardfor
        server web1 192.168.37.27:80 check inter 3000 fall 3 rise 5
        server web2 192.168.37.37:80 check inter 3000 fall 3 rise 5

hash 算法:

source:源地址hash,基于用户源地址hash并将请求转发到后端服务器,默认为静态即取模方式,但是可以通过hash-type支持的选项更改,后续同一个源地址请求将被转发至同一个后端web服务器,比较适用于session保持/缓存业务等场景,用法不多。
•map-based:取模法,基于服务器权重的hash数组取模,该hash是静态的即不支持在线调整权重,不支持慢启动,其对后端服务器调度均衡,缺点是当服务器的总权重发生变化时,即有服务器上线或下线,都会因权重发生变化而导致调度结果整体改变,hash(o)mod  n(其中n代表是有几个权重)。

1、source:源地址hash,基于用户源地址hash并将请求转发到后端服务器,默认为静态即取模方式,但是可以通过hash-type支持的选项更改,后续同一个源地址请求将被转发至同一个后端web服务器,比较适用于session保持/缓存业务等场景。
2、consistent:一致性哈希,该hash是动态的,支持在线调整权重,支持慢启动,优点在于当服务器的总权重发生变化时,对调度结果影响是局部的,不会引起大的变动。

listen web_prot_http_nodes
   bind 192.168.7.101:80
  mode http
  balance source
  hash-type consistent
  log global
  option forwardfor
  server 192.168.7.101 192.168.7.101:8080 check inter 3000 fall 3 rise 5
  server 192.168.7.102 192.168.7.102:8080 check inter 3000 fall 3 rise 5

3、uri:基于对用户请求的uri做hash并将请求转发到后端指定服务器,适用于后端缓存服务器

 对URI 的左半部分整个uri 做hash 计算,并除以服务器总权重取模

 左半部分:/<path>;<params>

 整个uri :/<path>;<params>?<query>#<frag>

map-based:取模法
consistent:一致性哈希
http://example.org/absolute/URI/with/absolute/path/to/resource.txt #URI/URL
ftp://example.org/resource.txt #URI/URL
/relative/URI/with/absolute/path/to/resource.txt #URI

uri: uniform resource identifier,统一资源标识符,是一个用于标识某一互联网资源名称的字符串

示例:

listen WEB_PORT_80
        bind 192.168.37.17:80
        #balance first
        #balance source
        #hash-type consistent
        balance uri
        mode http
        option forwardfor
        server web1 192.168.37.27:80 check weight 3  inter 3000 fall 3 rise 5
        server web2 192.168.37.37:80 check inter 3000 fall 3 rise 5

 测试效果,访问指定的uri路径文件:

[root@centos_17~]#curl http://192.168.37.17/app/test1.html
192.168.37.37 RS1

4、url_param:
对用户请求的url中的<params>部分中的参数name作hash计算,并由服务器总权重相除以后派发至某挑出的服务器;通常用于追踪用户,以确保来自同一个用户的请求始终发往同一个Backend Server

假设url= http://www.magedu.com/foo/bar/index.php?k1=v1&k2=v2

则:
host = "www.magedu.com"
url_param= "k1=v1&k2=v2"

listen WEB_PORT_80
        bind 192.168.37.17:80  # haproxy调度器IP地址
        #balance first
        #balance source
        #hash-type consistent
        #balance uri
        balance url_param name  定义name值
        mode http  #不支持tcp模式,会切换至tcp的roundrobin负载模式
        option forwardfor
        server web1 192.168.37.27:80 check inter 3000 fall 3 rise 5  # 后端服务器IP地址
        server web2 192.168.37.37:80 check inter 3000 fall 3 rise 5

测试效果,定义的name=的值就会默认访问一个IP地址,不是name=有可能访问另外一个IP地址。

5、hdr(不常用)

hdr(<name>):针对用户每个http头部(header)请求中的指定信息做hash,此处由<name>指定的http首部将会被取出并做hash计算,然后由服务器总权重相除以后派发至某挑出的服务器,假如无有效的值,则会被轮询调度

•hdr( Cookie、User-Agent、host )

6、rdp-cookie对远程桌面的负载,使用cookie保持会话

•rdp-cookie(<name>)

算法总结:

•roundrobin------------->tcp/http   动态,用的比较多,做四层负载,做过session共享用的最多的调度算法,调度轮询,支持权重分配。
•leastconn-------------->tcp/http   动态,用的比较多,做四层负载均衡,用于后端服务器上MySQL/PHP/HTTPS
•static-rr-------------->tcp/http   静态轮询,等于roundrobin,但是不支持权重。
•first------------------>tcp/http   静态,很少使用
•source----------------->tcp/http   取决于hash_type是否consistent,后端服务器没有seesion共享,但是还要实现会话保持
•Uri-------------------->http       取决于hash_type是否consistent,缓存场景,CDN缓存服务器,七层。
•url_param-------------->http       取决于hash_type是否consistent,缓存场景,七层
•hdr-------------------->http       取决于hash_type是否consistent,基于请求头部指定的信息做调度,七层模式。
•rdp-cookie------------->tcp        取决于hash_type是否consistent,windows远程桌面,很少使用,四层。

什么时候用四层,什么时候用七层?

在haproxy对用户的请求报文,响应报文,不做响应处理,只做转发作用时,就用四层,通常情况,使用四层做负载。

在haproxy匹配头部信息,匹配某个字段,在做头部报文处理,需要用七层,七层做负载均衡,会对头部报文处理,会影响转发性能。

四层与七层的区别:

四层:

•在四层负载设备中,把client发送的报文目标地址(原来是负载均衡设备的IP地址),根据均衡设备设置的选择web服务器的规则选择对应的web服务器IP地址,这样client就可以直接跟此服务器建立TCP连接并发送数据。

 

七层:
•七层负载均衡服务器起了一个代理服务器的作用,服务器建立一次TCP连接要三次握手,而client要访问webserver要先与七层负载设备进行三次握手后建立TCP连接,把要访问的报文信息发送给七层负载均衡;然后七层负载均衡再根据设置的均衡规则选择特定的webserver,然后通过三次握手与此台webserver建立TCP连接,然后webserver把需要的数据发送给七层负载均衡设备,负载均衡设备再把数据发送给client;所以,七层负载均衡设备起到了代理服务器的作用。

七层IP透传:

(1)分析:后端收到服务的请求是haproxy的,所以日志记录的请求ip也是haproxy的;如我们想要记录真实client 的ip,需加forwardfor 选项;

 在由haproxy 发往后端主机的请求报文中添加"X-Forwarded-For" 首部,其值为前端客户端的地址;用于向后端主发送真实的客户端IP。

(2)格式

option forwardfor [ except <network> ] [ header <name> ] [ if-none ]

[ except <network> ] :请求报请来自此处指定的网络时不予添加此首部,如haproxy 自身所在网络

[ header <name> ] :使用自定义的首部名称,而非默认的"X-Forwarded-For"

[ if-none ] 如果没有首部才添加首部,如果有使用默认值

七层负载:

listen web_prot_http_nodes
  bind 192.168.7.102:80  # haproxy主机的IP地址
  mode http
  option forwardfor  #IP地址透传
  server web1 blogs.studylinux.net:80 check inter 3000 fall 3 rise 5 # 调度到后端服务器上

查看nginx的访问日志就可以收集到client的IP地址: tail -f  /var/log/nginx/access.log

 四层负载:

listen web_prot_http_nodes
   bind 192.168.7.102:80 # haproxy调度器IP地址
   mode tcp
   server web2 blogs.studylinux.net:80 send-proxy check inter 3000 fall 3 rise 5

Nginx配置:需要在nginx配置文件中加入以下两部分内容,并将nginx的日志格式改为json格式。

listen 80 proxy_protocol; # 加入proxy_protocol选项
"tcp_xff":"$proxy_protocol_addr"; #TCP获取客户端真实IP日志格式,需要添加两个配置选项。

查看nginx的访问日志就可以收集到client的IP地址: tail -f  /var/log/nginx/access.log

Cookie 配置(生产中可以基于haproxy均衡调度到后端服务器) 

cookie <value>:为指定server设定cookie值,此处指定的值将在请求入站时被检查,第一次为此值挑选的server将在后续的请求中被选中,其目的在于实现持久连接的功能; 

cookie <value>:为当前server指定cookie值,实现基于cookie的会话黏性

cookie <name> [ rewrite | insert | prefix ] [ indirect ] [ nocache ] [ postonly ] [ preserve ] [ httponly ] [ secure ] [ domain <domain> ]* [ maxidle <idle> ] [ maxlife <life> ]

<name>:cookie名称,用于实现持久连接,可以解决一直同时调度到同一台主机的问题。

rewrite:重写
insert:插入
prefix:前缀
nocache:当client和hapoxy之间有缓存时,不缓存cookie

基于cookie实现的session 保持:

实现原理:首先以轮询的方式第一次给访问用户分配服务器,并给用户发放cookie值,然后用户再次访问时,就会携带cookie值,调度器会区分cookie值,将用户调度到后端服务器,实现cookie的会话黏性。

listen WEB_PORT_80
        bind 192.168.37.17:80
     balance roundrobin  # 以轮询的方式先对用户发放cookie值。
        mode http
        cookie SERVER-COOKIE  insert  indirect  nocache  #先定义,下边才能使用,insert报文首部,nocache 不缓存cookie,其中SERVER-COKIE名称可以自定义。
        server web1 192.168.37.27:80 cookie web-27 check inter 3000 fall 3 rise 5
        server web2 192.168.37.37:80 cookie web-37 check inter 3000 fall 3 rise 5

用curl命令验证cookie会话保持状态:

[root@mysql2 ~]# curl --cookie "SERVER-COOKIE=web1-27" http://192.168.37.27/index.html
192.168.7.103
[root@mysql2 ~]# curl --cookie "SERVER-COOKIE=web1-37" http://192.168.37.37/index.html

 

以上是关于HAProxy学习笔记的主要内容,如果未能解决你的问题,请参考以下文章

Haproxy 学习笔记上

学习笔记:python3,代码片段(2017)

关于Linux下HAProxy自动化部署的一些笔记整理

关于Linux下HAProxy自动化部署的一些笔记整理

sh Unbounce脚本片段,用于在零停机时间内重新启动HAProxy

[原创]java WEB学习笔记61:Struts2学习之路--通用标签 property,uri,param,set,push,if-else,itertor,sort,date,a标签等(代码片段