欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

33.0 haproxy

程序员文章站 2024-03-21 09:33:28
...

[aaa@qq.com ~ ]#yum info haproxy
Loaded plugins: fastestmirror, langpacks
Loading mirror speeds from cached hostfile
Installed Packages
Name        : haproxy
Arch        : x86_64
Version     : 1.5.18               #base  repository
Release     : 7.el7
Size        : 2.6 M
Repo        : installed
From repo   : base
Summary     : TCP/HTTP proxy and load balancer for high availability environments
URL         : http://www.haproxy.org/
License     : GPLv2+
Description : HAProxy is a TCP/HTTP reverse proxy which is particularly suited for high
            : availability environments. Indeed, it can:
            :  - route HTTP requests depending on statically assigned cookies
            :  - spread load among several servers while assuring server persistence
            :    through the use of HTTP cookies
            :  - switch to backup servers in the event a main server fails
            :  - accept connections to special ports dedicated to service monitoring
            :  - stop accepting connections without breaking existing ones
            :  - add, modify, and delete HTTP headers in both directions
            :  - block requests matching particular patterns
            :  - report detailed status to authenticated users from a URI
            :    intercepted by the application

haproxy

默认http
  支持http反向代理
   支持动态程序的反向代理
  支持基于数据的反向代理(一般数据库不用haproxy,数据库有读写分离技术)
HAProxy是TCP / HTTP反向代理服务器,尤其适合于高可用性环境
   可以针对HTTP请求添加cookie,进行路由后端服务器
   可平衡负载至后端服务器,并支持持久连接
   支持基于cookie进行调度
   支持所有主服务器故障切换至备用服务器
   支持专用端口实现监控服务
   支持不影响现有连接情况下停止接受新连接请求
   可以在双向添加,修改或删除HTTP报文首部
   支持基于pattern实现连接请求的访问控制
   通过特定的URI为授权用户提供详细的状态信息
haproxy的调度算法(1.5版本)
balance参数

balance <algorithm> [ <arguments> ]
balance url_param <param> [check_post]
Define the load balancing algorithm to be used in a backend.

<algorithm> is the algorithm used to select a server when doing load
        balancing. This only applies when no persistence information
        is available, or when a connection is redispatched to another
        server. <algorithm> may be one of the following :

算法

balance

roundrobin 
static-rr
leastconn
first
source
uri 
url_param
hdr(<name>)hdr(user-agent)
rdp-cookie
rdp-cookie(<name>)

hash-type:哈希算法

hash-type <method> <function> <modifier>
    methodmap-based:除权取余法,哈希数据结构是静态数组  
      consistent:一致性哈希,哈希数据结构是一棵树  
    function : 哈希函数,取值:sdbm,djb2,wt6  
    modifier: 取值avalanche时,将修改哈希值,而非直接使用 
default_backend <backend>
无use_backend 匹配时,使用默认的backend,用于frontend中 
default-server [param*]
  为backend中的各server设定默认选项 

配置段

代理配置段:
   - defaults
   - frontend
   - backend
   - listen
Frontend段:指定接收客户端连接侦听套接字设置
ackend段:指定将连接请求转发至后端服务器的相关设置
Listen段:指定完整的前后端设置
proxy 名称:使用字母 数字 - _ . : 并区分字符大小写

性能调整

性能调整:
  maxconn :设置每个haproxy进程所能接受的最大并发连接数
  maxconnrate :设置每个进程每秒种所能建立的最大连接数量 #传输层
  maxsessrate :设置每个进程每秒种所能建立的最大会话数量 #会话层
  maxsslconn : 每进程支持SSL的最大连接数量
  spread-checks <0..50, in percent> 健康检测延迟时长百分比,建议2-5之间

日志

日志系统

log:
  log global
  log <address> [len <length>] <facility> [<level> [<minlevel>]]
    length 日志行的长度,默认1024 
  no log 
  注意:
     默认发往本机的日志服务器 
    (1) local2.*      /var/log/local2.log 
    (2) $ModLoad      imudp  
    $UDPServerRun 514
  log-format <string>:
  参考文档实现combined格式的记录 

日志管理

将特定信息记录在日志中
     capture cookie <name> len <length>  
捕获请求和响应报文中的 cookie并记录日志 
     capture request header <name> len <length>
      捕获请求报文中指定的首部并记录日志 
      示例:
      capture request header X-Forwarded-For len 15 
capture response header <name> len <length>
      捕获响应报文中指定的首部并记录日志 
      示例:
      capture response header Content-length len 9 
      capture response header Location len 15 
[aaa@qq.com ~ ]#vim /etc/haproxy/haproxy.cfg 
frontend web               #多对多
        bind *:80
        default_backend websrvs
backend websrvs
        balance roundrobin
        server srv1 192.168.31.17:80 check
        server srv2 192.168.31.27:80 check

或者用如下
listen http          
      bind 192.168.31.7:80      #一对一

frontend web
        bind *:80
        default_backend websrvs
backend websrvs
        default-server inter 1000 weight 10
        balance roundrobin
        server srv1 192.168.31.17:80 check weight 2
        server srv2 192.168.31.27:80 check maxconn 5000 backlog 100
        server backupsrv 192.168.31.7:8080 check   #sorry server
[aaa@qq.com ~ ]#for i in {1..100};do curl 192.168.31.7;sleep .5;done
<h1>rs2</h1>
<h1>rs2</h1>
<h1>rs2</h1>
<h1>rs2</h1>
<h1>rs2</h1>
<h1>rs1</h1>
<h1>rs2</h1>

把rs1和rs2服务都停了,则会显示自定义的道歉页面

  server srv1 192.168.31.17:80 check disabled  #可以用来灰度发布
  server srv1 192.168.31.17:80 check redir http://www.baidu.com
  curl -L 192.168.31.7
  如果调度到192.168.1.17,则会把http://www.baidu.com网址返回给客户端,让客户端去访问此网址
  check选项实现后台服务器(upstream)健康性检测
  backlog 后援队列,即等待连接的客户端数量

健康状态检测

 check:对当前server做健康状态检测,只用于四层检测
  注意:httpchk,“smtpchk”, “mysql-check”, “pgsql-check” and “ssl-hello-chk” 用于定义应用层检测方法
        addr :检测时使用的IP地址 
        port :针对此端口进行检测
        inter <delay>:检测之间的时间间隔,默认为2000ms  
        rise <count>:连续多少次检测结果为“成功”才标记为可用;默认为2  
        fall <count>:连续多少次检测结果为“失败”才标记为不可用;默认为3 
 disabled:标记为不可用
 redir <prefix>:将发往此server的所有GET和HEAD类的请求重定向至指定的URL 

cookie配置

实现session会话绑定

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配置示例

基于cookie的session sticky的实现
  backend websrvs
        cookie WEBSRV insert nocache
        server srv1 172.16.0.6:80 weight 2 check rise 1 fall 2 maxconn 3000 cookie srv1
        server srv2 172.16.0.7:80 weight 1 check rise 1 fall 2 maxconn 3000 cookie srv2 

curl -b WEBSRV cookie=srv1 192.168.31.17

统计接口启用相关的参数

stats enable
      启用统计页;基于默认的参数启用stats page 
stats hide-version 隐藏版本
stats refresh <delay>
      设定自动刷新时间间隔 
stats uri <prefix>
      自定义stats page uri,默认值:/haproxy?stats 
stats realm <realm>
      认证时的realm,示例:stats realm : HAProxy\ Statistics 
stats auth <user>:<passwd>
      认证时的账号和密码,可使用多次,默认:no authentication 
stats admin { if | unless } <cond>   #staus admin true
      启用stats page中的管理功能

配置示例

listen stats
      bind :9527 
      stats enable
      stats hide-version 
      stats uri /hastats
      stats realm HAPorxy\ Stats\ Page 
      stats auth admin1:password1 
      stats auth admin1:password2 
      stats refresh 3s 
      stats admin if TRUE 

示例

vim /etc/haproxy/haproxy.cfg
listen haproxy
        bind 192.168.31.7:9527   #我做实验用的是80端口
        stats enable
        stats hide-version
        stats refresh 30
        stats uri /dhy-ha
        stats realm : HAproxy\Statistics
        stats auth dhy:dhy1
        stats admin if TRUE  
frontend web
        bind 192.168.31.7:80
        default_backend websrvs

backend  websrvs
        cookie WEBSRV insert nocache
        server srv1 192.168.31.17:80 check cookie dhy17 maxconn 5000
        server srv2 192.168.31.27:80 check cookie dhy27 maxconn 5000


33.0 haproxy
33.0 haproxy

工作模式

maxconn :为指定的frontend定义其最大并发连接数;默认为3000
mode { tcp|http|health }
  定义haproxy的工作模式
  tcp:基于layer4实现代理;可代理mysql, pgsql, ssh, ssl等协议,https时使用此模式,默认模式
  http:仅当代理协议为http时使用,CentOS中haproxy实际的默认模式
  health:工作为健康状态检查的响应模式,当连接请求到达时回应“OK”后即断开连接,较少使用

tcp是伪代理,真正的代理是tcp转发,此处是应用层模拟的传输层;后端服务器日志你看到的是代理服务器在访问后端服务器

TCP模式示例

示例:
      listen ssh
      bind :22022 
      balance leastconn 
      mode tcp
      server sshsrv1 192.168.31.17:22 check 
      server sshsrv2 192.168.31.27 check 

健康状态检测

对后端服务器做http协议健康状态检测:通常用于backend
      option httpchk 默认向后端服务器发请求:OPTIONS / HTTP/1.0 
      option httpchk <uri>
      option httpchk <method> <uri>
      option httpchk <method> <uri> <version>               #开始行
            定义基于http协议的7层健康状态检测机制 
      http-check expect [!] <match> <pattern>
            http协议健康状态检测响应内容或指定响应码 
————————————————————
https://cbonte.github.io/haproxy-dconv/1.5/configuration.html#4-option%20httpchk
backend websrvs
#option httpchk GET / HTTP/1.1\r\nhost:   #实验未能成功,添加官网如下成功
option httpchk OPTIONS * HTTP/1.1\r\nhost:
http-check expect status 200
server srv1 192.168.31.17:80 check

curl 192.168.31.17 503 服务不可用
curl 192.168.31.17  正常访问

forwardfor配置

option forwardfor [ except <network> ] [ header <name> ] [ if-none ]
      在由haproxy发往后端主机的请求报文中添加“X-Forwarded-For”首部,其值为前端客户端的地址;用于向后端主发送真实的客户端IP     #在日志中添加X-Forwarded-For
            [ except <network> ]:请求报请来自此处指定的网络时不予添加此首部, 如haproxy自身所在网络
            [ header <name> ]:使用自定义的首部名称,而非“X-Forwarded-For ”  
            [ if-none ] 如果没有首部才添加首部,如果有使用默认值 

为指定的MIME类型启用压缩传输功能
      compression algo <algorithm> ...:启用http协议的压缩机制,指明压缩 算法gzip, deflate
      compression type <mime type> ...:指明压缩的MIMI类型 

示例

[root@cos7 ~ ]#vim /etc/haproxy/haproxy.cfg 
option forwardfor       except 127.0.0.0/8  #默认头部是X-Forwarded-For
[root@cos17 ~ ]#vim /etc/httpd/conf/httpd.conf 
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" \"%{X-Forwarded-For}i\"" combined

#自定义头部
option forwardfor       except 127.0.0.0/8 header dhytest
[root@cos17 ~ ]#vim /etc/httpd/conf/httpd.conf 
\"%{dhytest}i\"
[root@cos17 ~ ]#tail -f /var/log/httpd/accss_log

错误页配置

后端服务器宕机,代理服务器错误页面
[proxy-4.1版](https://cbonte.github.io/haproxy-dconv/1.5/configuration.html#4-errorfile)
errorfile <code> <file> 自定义错误页
      <code>:HTTP status code.
            支持200, 400, 403, 408, 500, 502, 503, 504. 
      <file>:错误页文件路径
示例:
      errorfile 400 /etc/haproxy/errorfiles/400badreq.http 
      errorfile 408 /dev/null # workaround Chrome pre-connect bug 
      errorfile 403 /etc/haproxy/errorfiles/403forbid.http 
      errorfile 503 /etc/haproxy/errorfiles/503sorry.http
errorloc <code> <url>
      相当于errorloc302 <code> <url>,利用302重定向至指URL
      示例:errorloc 503 http://www.dhy.com/error_pages/503.html   #加到backend后端

修改报文首部

在请求报文尾部添加指定首部
      reqadd <string> [{if | unless} <cond>] 
在响应报文尾部添加指定首部
      rspadd <string> [{if | unless} <cond>] 
      示例:rspadd X-Via:\ HAPorxy
从请求报文中删除匹配正则表达式的首部 
      reqdel <search> [{if | unless} <cond>]  
      reqidel <search> [{if | unless} <cond>] 不分大小写 
从响应报文中删除匹配正则表达式的首部
      rspdel <search> [{if | unless} <cond>] 
      rspidel <search> [{if | unless} <cond>] 不分大小写 ignore
      示例: rspidel server.* 

示例

[root@cos7 ~ ]#vim /etc/haproxy/haproxy.cfg
listen ssh
        bind :22222
        balance leastconn
        mode tcp
        server sshsrv1 192.168.31.17:22 check
        server sshsrv2 192.168.31.27:22 check

listen haproxy
        bind 192.168.31.7:9527
        stats enable
        stats hide-version
        stats refresh 30
        stats uri /dhy-ha
        stats realm : haproxy:dhy
        stats auth dhy:dhy1
        stats admin if TRUE

frontend web
        bind 192.168.31.7:80
        default_backend websrvs
        rspidel server.*
        rspadd server:\ dhy-nginx
        reqadd dhyheader:\ requestheader-dhy
        errorfile 503 /etc/haproxy/errorfiles/503.html
backend  websrvs
        cookie WEBSRV insert nocache
        server srv1 192.168.31.17:80 check cookie dhy17 maxconn 5000
        server srv2 192.168.31.27:80 check cookie dhy27 maxconn 5000
[root@cos7 ~ ]#systemctl reload haproxy

[root@cos17 ~ ]#vim /etc/httpd/conf/httpd.conf
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\"  \"%{dhyheader}i\"" combined

[root@cos6 ~ ]#curl -I 192.168.31.7
HTTP/1.1 200 OK
Date: Fri, 14 Sep 2018 09:14:29 GMT
Last-Modified: Fri, 14 Sep 2018 07:44:58 GMT
ETag: "10-575d0000e1342"
Accept-Ranges: bytes
Content-Length: 16
Content-Type: text/html; charset=UTF-8
server: dhy-nginx                         #"国产"nginx
Set-Cookie: WEBSRV=dhy17; path=/
Cache-control: private

[aaa@qq.com ~ ]#for i in {1..100};do curl 192.168.31.7;sleep 0.5;done
<h1>rs2-27</h1>
<h1>rs1-17</h1>
<h1>rs2-27</h1>
<h1>rs1-17</h1>

[aaa@qq.com ~ ]#tail -f /var/log/httpd/access_log
192.168.31.7 - - [14/Sep/2018:17:30:43 +0800] "GET / HTTP/1.1" 200 16 "-"  "requestheader-dhy"
192.168.31.7 - - [14/Sep/2018:17:30:44 +0800] "GET / HTTP/1.1" 200 16 "-"  "requestheader-dhy"

图3
33.0 haproxy

[root@cos7 ~ ]#mkdri -p /etc/haproxy/errorfiles/
[root@cos7 ~ ]#echo "503 error" > /etc/haproxy/errorfiles/503.html
[root@cos17 ~ ]#systemctl stop httpd
[root@cos27 ~ ]#systemctl stop httpd
[root@cos6 ~ ]#for i in {1..100};do curl 192.168.31.7;sleep 0.5;done
503 error
503 error
503 error

acl:access control list

ACL

acl:访问控制列表(ACL)的使用提供了一个灵活的解决方案来执行内容交换,并且通常基于从请求中提取的内容、响应或任何环境状态进行决策          #类似dns的智能dns
acl <aclname> <criterion> [flags] [operator] [<value>] ...
      <aclname>:ACL名称,可使用字母 数字 : . - _ ,区分字符大小写 
      <criterion>: 比较的标准和条件 

     <value>的类型:
      - boolean
      - integer or integer range 
      - IP address / network
      - string (exact, substring, suffix, prefix, subdir, domain) 
      - regular expression
      - hex block 

     <flags>
      -i 不区分大小写
      -m 使用指定的pattern匹配方法 
      -n 不做DNS解析
      -u 强制每个ACL必须唯一ID,否则多个同名ACL或关系 
      -- 强制flag结束. 当字符串和某个flag相似时使用 
    [operator]
      匹配整数值:eq、ge、gt、le、lt 
      匹配字符串:
        - exact match (-m str) :字符串必须完全匹配模式
        - substring match (-m sub) :在提取的字符串中查找模式,如果其中任何一个被发现,ACL将匹配
        - prefix match (-m beg) :在提取的字符串首部中查找模式,如果其中任何一个被发现,ACL将匹配
        - suffix match (-m end) :将模式与提取字符串的尾部进行比较,如果其中任何一个匹配,则ACL进行匹配
        - subdir match (-m dir) :查看提取出来的用斜线分隔(“/”)的字符串,如果其中任何一个匹配,则ACL进行匹配
        - domain match (-m dom) :查找提取的用点(“.”)分隔字符串,如果其中任何一个匹配,则ACL进行匹配 

ACL 逻辑

acl作为条件时的逻辑关系:  
- 与:隐式(默认)使用
- 或:使用“or ” 或 “||”表示 
- 否定:使用“!“ 表示
示例:if invalid_src invalid_port 与关系  
      if invalid_src || invalid_port 或  
      if ! invalid_src 非 
<criterion> :各种条件
      dst       目标IP 
      dst_port  目标PORT 
      src       源IP 
      src_port  源PORT
      示例:acl invalid_src src 192.168.31.1
[root@cos7 ~ ]#vim /etc/haproxy/haproxy.cfg 
listen haproxy
        bind 192.168.31.7:9527
        acl valid_src src 192.168.31.1
        stats enable
        stats hide-version
        stats refresh 30
        stats uri /dhy-ha
        stats realm : haproxy:dhy
        stats auth dhy:dhy1
        stats admin if ! valid_src

图4
33.0 haproxy

[root@cos7 ~ ]#vim /etc/haproxy/haproxy.cfg 
frontedn web
      bind 192.168.31.7:80
      block if METH_HEAD

      acl image_acl path_end .jpg .png    #图片服务器
      default_backedn websrvs
      use_backend appsrvs if image_acl    #图片服务器
backend websrvs
      srvser srv1 192.168.31.17:80 check
backend appsrvs
      srvser srv2 192.168.31.27:80 check   #图片服务器

支持https协议

配置HAProxy支持https协议:  
支持ssl会话;
      bind *:443 ssl crt /PATH/TO/SOME_PEM_FILE 
      crt 后证书文件为PEM格式,且同时包含证书和所有私钥  
            cat demo.crt demo.key > demo.pem
把80端口的请求重向定443
      bind *:80
      redirect scheme https if !{ ssl_fc }   
向后端传递用户请求的协议和端口(frontend或backend)
      http-request set-header X-Forwarded-Port %[dst_port] 
      http-request add-header X-Forwared-Proto https if { ssl_fc } 

frontend web
      bind 172.18.0.7:80
      bind 172.18.0.7:443 ssl crt /etc/haproxy/a.pem
mod tcp
-----------------------
cd /etc/pki/tls/certs/
make a.pem
cat a.pem #包含了证书和私钥,如果是自己手动创建的则,cat a.crt a.key > a.pem
Privacy Enhanced Mail 私有,加强,邮件
相关标签: haproxy