haproxy基础部署方法和负载均衡的实习+调度算法

avatar
作者
筋斗云
阅读量:0

 一、基础部署方法+参数分析

实验思路+工作图:

环境设备:

四台主机: 

haproxy172.25.254.114haproxy服务
websever3172.25.254.10后端服务器
websever4172.25.254.20后端服务器
client172.25.254.200客户端
  1. 环境基础配置和安装软件
[root@haproxy ~]# vmset.sh eth0 172.25.254.114 haproxy.txy.org [root@haproxy ~]# nmcli connection reload [root@haproxy ~]# nmcli connection up eth0   #其他三台同理,利用脚本获取Ip地址,然后开启网卡   [root@websever3 ~]# vmset.sh eth0 172.25.254.10 websever3.txy.org  [root@websever4 ~]# vmset.sh eth0 172.25.254.20 websever4.txy.org  [root@client ~]# vmset.sh eth0 172.25.254.200 client.txy.org    #在主机haproxy上安装服务 [root@haproxy ~]# yum install haproxy -y   #在后端服务器web3和web4上装nginx [root@websever3 ~]# yum install nginx -y  [root@websever3 ~]# echo websever3 - 172.25.254.10 > /usr/share/nginx/html/index.html [root@websever3 ~]# cat  /usr/share/nginx/html/index.html websever3 - 172.25.254.10 [root@websever3 ~]# systemctl enable --now nginx.service   [root@websever4 ~]# yum install nginx -y  [root@websever4 ~]# echo websever4 - 172.25.254.10 > /usr/share/nginx/html/index.html [root@websever4 ~]# cat  /usr/share/nginx/html/index.html websever4 - 172.25.254.20  [root@websever4 ~]# systemctl enable --now nginx.service    
 基础部署方法:
  • HAProxy 的配置文件haproxy.cfg由两大部分组成,分别是:
  1. global:全局配置段

    • 进程及安全配置相关的参数.

    • 性能调整相关参数

    • ·Debug参数

  2. proxies:代理配置段

    • defaults: 为 frontend ,backend, listen提供默认配置

    • frontend:前端,相当于nginx中的server {)}

    • backend:后端,相当于nginx中的upstream G

    • listen:同时拥有前端和后端配置,配置简单,生产推荐使用

简单写一个,看效果
#编辑配置文件 [root@haproxy ~]# vim /etc/haproxy/haproxy.cfg 

[root@haproxy ~]# systemctl enable haproxy.service 

出现问题看日志排错 

 

 

在客户端测试: 

 

# 先停止nginx服务,到后端检测 ,此时的后端检测是默认的

# 启动nginx [root@websever3 ~]# systemctl restart nginx.service  # 合并backend方法 [root@haproxy ~]# vim /etc/haproxy/haproxy.cfg  listen webcluster      bind *:80    # *表示监听      mode http      balance  roundrobin      server  web3 172.25.254.10:80      server  web4 172.25.254.20:80  #启动 [root@haproxy ~]# systemctl restart  haproxy.service 

 再次测试

 

参数配置文件

1. 日志分离

查看日志定义名字:

[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg   [root@haproxy ~]# vim /etc/rsyslog.conf

 

 

2. gloabl全局布置命令(热处理)
   相关参数说明:
参数类型用途
chroot全局锁定运行目录
deamon全局守护进程运行
user、group、uid、gid全局运行haproxy的用户身份
stats  socket全局套接字文件
nbproc N全局开启的haproxy worker 进程数,默认进程数是一个
nbthread1(和nbproc互斥)全局指定每个haproxy进程开启的线程数,默认为每个进程一个线程
cpu-map 1 0全局绑定haproxy worker进程至指定CPU,将第1个work进程绑定至0号CPU
cpu-map 2 1全局绑定haproxyworker 进程至指定CPU,将第2个work进程绑定至1号CPU
maxconn N全局每个haproxy进程的最大并发连接数
maxsslconn N全局每个haproxy进程ssl最大连接数,用于haproxy配置了证书的场景下
maxconnrate N全局每个进程每秒创建的最大连接数量
spread-checks N全局后端server状态check随机提前或延迟百分比时间,建议2-5(20%-50%)之间,默认值0
pidfile全局指定oid文件路径
log 127.0.0.1 local2 info全局定义全局的syslog服务器:日志服务器需要开启UDP协议最多可以定义两个

部分参数操作演示
1.启用线程
# 启用多线程: [root@haproxy ~]# vim /etc/haproxy/haproxy.cfg

 

 2.线程数开了两个对应自己的内核数 ,解决cpu飘的问题
#解决cpu飘的问题 [root@haproxy ~]# vim /etc/haproxy/haproxy.cfg

 

 

 查看子进程

 子进程和多线程是互斥的
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg

 

 查日志

 注释后重新启动

定义全局syslo服务器  日志分离

 

3.proxies(代理配置)参数命令

 包含的参数有哪些
参数类型用途
defaultsproxies默认配置项,针对以下的frontend、backend和listen生效,可以多个name也可以没有name
frontendproxies前端servername,类似于Nginx的一个虚拟主机server和LVS服务集群。
backendproxies后端服务器组,等于nginx的upstream和LVS中的RS服务器
4proxies将frontend和backend合并在一起配置,相对于frontend和backend配置更简洁,生产常用
1.defaults

# default相关参数运用
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg

defaults
    mode              http      #采用7层 tcp 4层
    log                global      #日志延续gloabl  #采用全局定义的日志
    option             httplog     #日志 http日志格式
    option               dontlognull    #表示不记录空会话的链接日志信息
    option http-server-close     # 等待客户端完整的HTTP请求时间。此处等待时间10s
    option forwardfor       except 127.0.0.0/8      #传客户端真实IP至后端web服务器(在apache配置文件中加入 %{X-Forwarded-For}i 后在webserer中看日志即可看到地址透传信息)
    option          redispatch     # 重新派发流量给其他服务器,在sever id dowm后
    retries                 3       #3次连接失败就认为服务不可用,也可以通过后面设置
    timeout http-request    10s   #等待客户请求完全被接受和处理的最长时间
    timeout queue           1m  # 设置删除链接和客户端收到的503或者服务不可用等提示消息的等待时间
    timeout connect         10s #  客户端请求从haproxy到后端server最长连接等待时间(TCP连接之前)默认单位ms
    timeout client          1m   #客户端连接超时
    timeout server          1m   #服务器链接超时
    timeout http-keep-alive 10s  #session 会话保持超时时间,此时间段内会转发到相同的后端服务器
    timeout check           10s  # 对后端服务器的默认检测超时时间
    maxconn                 100000     #每个haproxy进程的最大并发连接数

 2. frontend

frontend webcluster

  bind *:80
  mode http
  use_backend webcluster-host

通过frontend关键字定义了一个名为"www"的前端虚拟节点
bind
此选项用于定义一个或者几个监听的套接字,只能在frontend和listen中定义
格式如下:
bind [<address>:[port_range]] [interface]

3. backend

 backend webcluster-host
 balance  roundrobin
 server  web3 172.25.254.10:80
 server  web4 172.25.254.20:80

4. listen

 5 .有关server配置
#server配置 1. check 指定健康检查,不写默认不开启  #默认对相应的后端服务器IP和端口,利用TCP连接进行周期性健康性检查,注意必须指定端口才能实现健康性检查  addr <IP> #可指定的健康状态监测IP,可以是专门的数据网段,减少业务网络的流量  port <num> #指定的健康状态监测端口  inter <num> #健康状态检查间隔时间,默认2000ms  fa11 <num> #后端服务器从线上转为线下的检查的连续失效次数,默认为3   rise <num> #后端服务器从下线恢复上线的检查的连续有效次数,默认为2  weight <weight> #默认为1,最大值为256,0(状态为蓝色)表示不参与负载均衡,但仍接受持久连  backup #将后端服务器标记为备份状态,只在所有非备份主机down机时提供服务,类似Sorry Server  disabled #将后端服务器标记为不可用状态,即维护状态,除了持久模式,将不再接受连接,状态为深黄色,优雅下线,不再接受新用户的请求  redirect prefix http://www.baidu.com/ #将请求临时(302)重定向至其它URL,只适用于http模式  redir http://www.baidu.com #将请求临时(302)重定向至其它URL,只适用于http模式  maxconn <maxconn> #当前后端server的最大并发连接数   [root@haproxy ~]# vim /etc/haproxy/haproxy.cfg listen webcluster      bind *:80      mode http      balance  roundrobin      server  web3 172.25.254.10:80  check inter 2 fall 3 rise 5 weight 2      server  web4 172.25.254.20:80  check inter 2 fall 3 rise 5 weight 1  #测试 [root@client ~]# for i in {1..10}; do curl 172.25.254.114; done websever3 - 172.25.254.10 websever4 - 172.25.254.20 websever3 - 172.25.254.10 websever4 - 172.25.254.20 websever3 - 172.25.254.10 websever4 - 172.25.254.20 websever3 - 172.25.254.10 websever4 - 172.25.254.20 websever3 - 172.25.254.10 websever4 - 172.25.254.20   #backup  ,标记后端服务为备份状态,会出现提示 [root@haproxy ~]# vim /etc/httpd/conf/httpd.conf [root@haproxy ~]# systemctl enable --now httpd Created symlink /etc/systemd/system/multi-user.target.wants/httpd.service → /usr/lib/systemd/system/httpd.service.  啦啦啦~下班

上面参数的相关实验操作相关截图:

 

 

 

 这里需要先把10和20的nginx服务关闭

标记后端为维护状态,不可使用状态。除开持久模式,其他不接受

 

  将请求临时重定向至其它URL

 

 前后端server的最大并发连接数

 

4. socat工具
  • 对服务器动态权重和其它状态可以利用 socat工具进行调整,Socat是 Linux 下的一个多功能的网络工具,名字来由是Socket CAT,相当于netCAT的增强版.
  • Socat 的主要特点就是在两个数据流之间建立双向通道,且支持众多协议和链接方式。如IP、TCP、UDP、IPv6、Socket文件等
  • 范例:利用工具socat 对服务器动态权重调整
#修改配置文件 [root@haproxy ~]# systemctl restart  haproxy.service [root@haproxy ~]# ll /var/l lib/   local/ lock/  log/ [root@haproxy ~]# ll /var/lib/haproxy/stats srw------- 1 root root 0  8月  9 13:54 /var/lib/haproxy/stats  # [root@haproxy ~]# systemctl restart  haproxy.service [root@haproxy ~]# ll /var/l lib/   local/ lock/  log/ [root@haproxy ~]# ll /var/lib/haproxy/stats srw------- 1 root root 0  8月  9 13:54 /var/lib/haproxy/stats    #[root@haproxy ~]# echo get weight webcluster/web3 | socat stdio /var/lib/haproxy/stats 2 (initial 2)   [root@haproxy ~]# echo " set weight webcluster/web3 1 "  | socat stdio /var/lib/haproxy/stats  [root@haproxy ~]# echo get weight webcluster/web3 | socat stdio /var/lib/haproxy/stats 1 (initial 2)  [root@haproxy ~]# echo " set weight webcluster/web3 2 "  | socat stdio /var/lib/haproxy/stats  [root@haproxy ~]# echo get weight webcluster/web3 | socat stdio /var/lib/haproxy/stats 2 (initial 2)  [root@haproxy ~]# echo 'show servers state' | socat stdio /var/lib/haproxy/stats 1 # be_id be_name srv_id srv_name srv_addr srv_op_state srv_admin_state srv_uweight srv_iweight srv_time_since_last_change srv_check_status srv_check_result srv_check_health srv_check_state srv_agent_state bk_f_forced_id srv_f_forced_id srv_fqdn srv_port srvrecord srv_use_ssl srv_check_port srv_check_addr srv_agent_addr srv_agent_port 2 webcluster 1 web3 172.25.254.10 2 0 2 2 352 6 3 7 6 0 0 0 - 80 - 0 0 - - 0 2 webcluster 2 web4 172.25.254.20 2 0 1 1 352 6 3 7 6 0 0 0 - 80 - 0 0 - - 0 4 static 1 static 127.0.0.1 0 0 1 1 1466 8 2 0 6 0 0 0 - 4331 - 0 0 - - 0 5 app 1 app1 127.0.0.1 0 0 1 1 1466 8 2 0 6 0 0 0 - 5001 - 0 0 - - 0 5 app 2 app2 127.0.0.1 0 0 1 1 1465 8 2 0 6 0 0 0 - 5002 - 0 0 - - 0 5 app 3 app3 127.0.0.1 0 0 1 1 1465 8 2 0 6 0 0 0 - 5003 - 0 0 - - 0 5 app 4 app4 127.0.0.1 0 0 1 1 1465 8 2 0 6 0 0 0 - 5004 - 0 0 - - 0 

 

二、调度算法

1.定义

haproxy通过固定参数 balance 指明对后端服务器的调度算法;balance参数可以配置在listen或backend选项中。

2. 分类
  • haproxy的调度算法分为静态和动态调度算法有些算法可以根据参数在静态和动态算法中相互转换。

静态算法:
  1. 定义:按照事先定义好的规则轮询公平调度,不关心后端服务器的当前负载、连接数和响应速度等,且无法实时修改权重(只能为0和1,不支持其它值),只能靠重启haproxy生效。

  2. 算法:

    • static-rr:基于权重的轮询调度I

      • 不支持运行时利用socat进行权重的动态调整(只支持0和1,不支持其它值)

      • 不支持端服务器慢启动 socatI

      • 其后端主机数量没有限制,相当于LVS中的 wrr

# 写配置文件 (关闭多进程显示) [root@haproxy ~]# vim /etc/haproxy/haproxy.cfg #重启

 

 此时不可以用socat访问的

 

     2. first

  • 根据服务器在列表中的位置,自上而下进行调度

  • 其只会当第一台服务器的连接数达到上限,新请求才会分配给下一台服务其会忽略服务器的权重设置

  • 不支持用socat进行动态修改权重,可以设置0和1,可以设置其它值但无效

动态算法:

定义:

  1. 基于后端服务器状态进行调度适当调整

  2. 新请求将优先调度至当前负载较低的服务器权重可以在

  3. haproxy运行时动态调整无需重启

    方法:

  • roundrobin

    • 基于权重的轮询动态调度算法

    • 支持权重的运行时调整,不同于Lvs中的rr轮训模式

    • HAProxy中的roundrobin支持慢启动(新加的服务器会逐渐增加转发数)

    • 其每个后端backend中最多支持4095个real server,

    • 支持对real server权重动态调整

    • roundrobin为默认调度算法,此算法使用广

基于找负载小的,支持socat

leastconn

  • 最小连接的最少连接的动态

  • 支持权重的运行时调整和慢启动,即:根据当前连接最少的后端服务器而非权重进行优先调度(新客户端连接)

  • 比较适合长连接的场景使用,比如:MySQL等场景。

 

其他算法
  1. source:

    • 源地址hash,基于用户源地址hash并将请求转发到后端服务器,后续同一个源地址请求将被转发至同-个后端web服务器。

    • 此方式当后端服务器数据量发生变化时,会导致很多用户的请求转发至新的后端服务器,默认为静态方式,但是可以通过hash-type支持的选项更改这个算法一般是在不插入Cookie的TCF模式下使用,也可给拒绝会话cookie的客户提供最好的会话粘性

    • 适用于session会话保持但不支持cookie和缓存的场景源地址有两种转发客户端请求到后端服务器的服务器选取计算方式,分别是取模法和一致性hash

 

  1. map-base取模法

  • map-based:取模法,对source地址进行hash计算,再基于服务器总权重的取模,最终结果决定将此请求转发至对应的后端服务器。

  • 此方法是静态的,即不支持在线调整权重,不支持慢启动,可实现对后端服务器均衡调度

  • 缺点是当服务器的总权重发生变化时,即有服务器上线或下线,都会因总权重发生变化而导致调度结果整体改变,hash-type 指定的默认值为此算法

  • 取模运算,就是计算两个数相除之后的余数,10%7=3,7%4=3

  • map-based算法 :基于权重取模,hash(source_ip)%所有后端服务器相加的总权重

  • 比如当源hash值时1111,1112,1113,三台服务器a b c的权重均为1,即a b c的调度标签分别会被设定为0 1 2 (1111%3=1,1112%3=2,1113%3=0)

  • 假设a为 0,1113主机会被调度到a上

  • 如果a下线后,权重数量发生变化

  • 1111%2=1,1112%2=0,1113%2=1

  • 1112和1113被调度到的主机都发生变化,这样会导致会话丢失

  1. 一致性hash

  • 一致性哈希,当服务器的总权重发生变化时,对调度结果影响是局部的,不会引起大的变动hash(o)mod n

  • 该hash算法是动态的,支持使用 socat等工具进行在线权重调整,支持启动

算法:

  • 后端服务器哈希环点keyA=hash(后端服务器虚拟ip)%(2^32)

  • 客户机哈希环点key1=hash(client_ip)%(2^32)

  • 得到的值在[0---4294967295]之间

  • 将keyA和key1都放在hash环上,将用户请求调度到离key1最近的keyA对应的后端服务器

 

 

  1. uri

  • 基于对用户请求的URI的左半部分或整个uri做hash,再将hash结果对总权重进行取模后

  • 根据最终结果将请求转发到后端指定服务器

  • 适用于后端是缓存服务器场景

  • 默认是静态算法,也可以通过hash-type指定map-based和consistent,来定义使用取模法还是一致性 hash

  • 注意:此算法基于应用层,所以只支持 mode http,不支持 mode tcp

 格式:

<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>

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

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

 

#开配置 # 测试页 [root@websever3 ~]# echo 172.25.254.10 - index1.html > /usr/share/nginx/html/index1.html [root@websever3 ~]# echo 172.25.254.10 - index2.html > /usr/share/nginx/html/index2.html [root@websever3 ~]# echo 172.25.254.10 - index3.html > /usr/share/nginx/html/index3.html  [root@websever4 ~]#  echo 172.25.254.20 - index1.html > /usr/share/nginx/html/index1.html [root@websever4 ~]#  echo 172.25.254.20 - index2.html > /usr/share/nginx/html/index2.html [root@websever4 ~]#  echo 172.25.254.20 - index3.html > /usr/share/nginx/html/index3.html   #测试 [root@client ~]# curl 172.25.254.114/index1.html   //第一次访问index1,返回10 172.25.254.10 - index1.html [root@client ~]# curl 172.25.254.114/index2.html  //第一次访问index2,返回20 172.25.254.20 - index2.html [root@client ~]# curl 172.25.254.114/index3.html    //第一次访问index3,返回10 172.25.254.10 - index3.html [root@client ~]# curl 172.25.254.114/index1.html  //第二次访问index1,返回10 uri不变,第一次返回=第二次返回 172.25.254.10 - index1.html [root@client ~]# curl 172.25.254.114/index2.html 172.25.254.20 - index2.html

 

url_param
  • url_param对用户请求的url中的 params 部分中的一个参数key对应的value值作hash计算,并由服务器总权重相除以后派发至某挑出的服务器,后端搜索同一个数据会被调度到同一个服务器,多用与电商

  • 通常用于追踪用户,以确保来自同一个用户的请求始终发往同一个realserver

  • 如果无没key,将按roundrobin算法

 

[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg   [root@haproxy ~]# systemctl restart haproxy.service    #测试 [root@client ~]# curl 172.25.254.114/index2.html?name=lee 172.25.254.10 - index2.html [root@client ~]# curl 172.25.254.114/index2.html?name=lee 172.25.254.10 - index2.html [root@client ~]# curl 172.25.254.114/index2.html?name=lee 172.25.254.10 - index2.html [root@client ~]# curl 172.25.254.114/index2.html?name=test 172.25.254.20 - index2.html [root@client ~]# curl 172.25.254.114/index2.html?name=test 172.25.254.20 - index2.html

 

hdr

  • 针对用户每个http头部(header)请求中的指定信息做hash

  • 此处由 name 指定的http首部将会被取出并做hash计算

  • 然后由服务器总权重取模以后派发至某挑出的服务器,如果无有效值,则会使用默认的轮询调度。

 [root@haproxy ~]# vim /etc/haproxy/haproxy.cfg   listen webcluster     bind *:80     mode http     #balance roundrobin     #balance leastconn     #balance static-rr     #balance first     #balance source     #balance uri     #balance url_param name,userid     balance hdr(User-Agent)         hash-type consistent     #redirect prefix http://www.baidu.com/     #cookie WEBCOOKIE insert nocache indirect     server webserver1 172.25.254.10:80 check inter 2 fall 3 rise 5 weight 1      server webserver2 172.25.254.20:80 check inter 2 fall 3 rise 5 weight 1     #server webserver_sorry 172.25.254.114:8080 backup  #测试  [root@client ~]# curl -vA "firefox" 172.25.254.114/index.html

    广告一刻

    为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!