haproxy负载均衡

haproxy详解

借助ai来实现,比如配置文件直接给出,然后讲解

1、概述

1.1、简介

  • HAProxy是一个使用C语言编写开源软件,提供高可用,负载均衡,以及基于TCP(四层)和HTTP(七层)的应用程序代理

  • HAProxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持或七层处理。HAProxy运行在当前的硬件上,完全可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单安全的整合进您当前的架构中, 同时可以保护你的web服务器不被暴露到网络上

  • haproxy能实现什么

什么是haproxy,能实现什么,动静分离,负载均衡

四层和七层

1.2、haproxy支持的算法

2、配置文件详解

2.1、安装haproxy和查看生成的配置文件

yum -y install haproxy

查看生成的配置文件

# 查看生成的主配置文件
[root@server ~]# rpm -qc haproxy
/etc/haproxy/haproxy.cfg  # 主配置文件,等会需要讲解里面的参数
/etc/logrotate.d/haproxy
/etc/sysconfig/haproxy

# 生成的所有文件
[root@server ~]# rpm -ql haproxy
/etc/haproxy
/etc/haproxy/conf.d
/etc/haproxy/haproxy.cfg
/etc/ima/digest_lists.tlv/0-metadata_list-compact_tlv-haproxy-2.6.6-18.oe2203sp3.x86_64
/etc/ima/digest_lists/0-metadata_list-compact-haproxy-2.6.6-18.oe2203sp3.x86_64
/etc/logrotate.d/haproxy
/etc/sysconfig/haproxy
/usr/bin/halog
/usr/bin/ip6range
/usr/bin/iprange
/usr/lib/systemd/system/haproxy.service
/usr/sbin/haproxy
/usr/share/haproxy
/usr/share/haproxy/400.http
/usr/share/haproxy/403.http
/usr/share/haproxy/408.http
/usr/share/haproxy/500.http
/usr/share/haproxy/502.http
/usr/share/haproxy/503.http
/usr/share/haproxy/504.http
/usr/share/haproxy/README
/usr/share/licenses/haproxy
/usr/share/licenses/haproxy/LICENSE
/var/lib/haproxy

2.2、主配置讲解(haproxy.cfg)

# 默认的主配置文件
[root@server haproxy]# cat haproxy.cfg 
#---------------------------------------------------------------------
# Example configuration for a possible web application.  See the
# full configuration options online.
#
#   https://www.haproxy.org/download/1.8/doc/configuration.txt
#
#---------------------------------------------------------------------

global   # 定义全局参数,属于进程级别的配置
    log         127.0.0.1 local2   # 配置日志转发,将haproxy日志发送到本地的127.0.0.1的local2设备上(syslog的本地设备),需要配合rsyslogs这个服务配置日志存储路径

    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid  # 指定pid文件
    user        haproxy   # 进程的用户
    group       haproxy   # 进程的用户组
    daemon                # 守护进程后台运行
    maxconn     4000      # 最大连接数为4000

defaults  # 用于配置默认参数,些参数可以被用到frontend,backend,Listen组件,影响后面的配置

    mode                    http    # haproxy工作模式http,会解析http请求头,支持http特有功能,cookie,重定向,健康检查
                                    # 四层模式tcp,不解析应用层

    log                     global  # 继承global块的日志配置
    option                  httplog  # 启用详细的http日志记录,请求头,客户端ip等
    option                  dontlognull  # 忽略空连接,即客户端建立请求但是没有发送任何请求就断开的情况,避免日志被无效信息刷屏

    retries                 3   # 设置后端服务器连接失败后的重试次数,3次仍然失败的话,就切换到下一个节点上

    timeout http-request    5s
    timeout queue           1m
    timeout connect         5s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 5s
    timeout check           5s  # 对后端节点健康检查的超时时间,5秒内没有健康检查的响应,视为节点不健康
    maxconn                 3000  # 默认配置下的最大并发连接数

frontend main  # 接收请求的前端虚拟节点,定义一些acl规则,请求定向到后端的backend
               # 客户端请求的入口,监听的端口,协议,请求转发规则,这个命名可以自定义

    bind *:80   # 设置haproxy监听地址和端口,*表示监听服务器的所有网卡,80是默认端口
    default_backend         http_back  # 默认的后端服务池,所有匹配此前端的请求,就是不匹配acl规则,就将请求转发到这个后端服务器组上

backend http_back   # 定义后端服务集群的配置,真实服务器,一个backend对应一个或者多个实体服务器
                    # 设置算法,健康检查,这个http_back需要与前端配置的名字一样
                    
    balance     roundrobin    # 设置负载均衡器的算法,轮询算法
    server  node1 127.0.0.1:5001 check  # 定义的后端节点,,node1 节点自定义名称(用于日志和监控识别)  ,check 启动健康检查
    server  node2 127.0.0.1:5002 check
    server  node3 127.0.0.1:5003 check
    server  node4 127.0.0.1:5004 check


# 还有一个listen字段, 常用于状态页面的监控,以及对后端的检查是前端和后端的组合

3、haproxy实验

3.1、自定义haproxy日志

  • 安装haproxy后,默认是没有这个日志文件的,需要配置

  • 还需要借助rsyslog服务

确认haproxy日志配置

global
    log         127.0.0.1 local2  # 发送日志到本地rsyslog的local2设备,使用syslog协议
defaults
    log         global            # 前端/后端继承global的日志配置
    option      httplog           # 启用详细的HTTP日志(包含请求方法、URL、状态码等)
    option      dontlognull       # 忽略空连接日志,减少无效信息

编辑rsyslog配置文件

vim /etc/rsyslog.conf

$ModLoad imudp    # 启用udp ,加载udp模块
$UDPServerRun 514  # 让rsyslog 监听514端口,syslog默认端口

# 配置haproxy 日志的存储规则,local2设备的所有日志级别(info,warn,err等所有级别都收集信息)

local2.*                        /var/log/haproxy.log 

重启日志服务和haproxy服务

systemctl restart rsyslog
systemctl restart haproxy

查看生成的日志

# 由于后端服务器没有配置,所以就是down状态
[root@server rsyslog.d]# tail -f /var/log/haproxy.log 
Oct 18 23:17:32 localhost haproxy[2872]: Server http_back/node1 is DOWN, reason: Layer4 connection problem, info: "Connection refused", check duration: 0ms. 3 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue.
Oct 18 23:17:32 localhost haproxy[2872]: Server http_back/node2 is DOWN, reason: Layer4 connection problem, info: "General socket error (Permission denied)", check duration: 0ms. 2 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue.
Oct 18 23:17:33 localhost haproxy[2872]: Server http_back/node3 is DOWN, reason: Layer4 connection problem, info: "Connection refused", check duration: 0ms. 1 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue.
Oct 18 23:17:33 localhost haproxy[2872]: Server http_back/node4 is DOWN, reason: Layer4 connection problem, info: "Connection refused", check duration: 0ms. 0 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue.
Oct 18 23:17:33 localhost haproxy[2872]: backend http_back has no server available!

还可以分割访问日志和错误日志

# 信息级别(info)及以上的访问日志写入access.log
local2.info                     /var/log/haproxy/haproxy_access.log
# 警告(warn)和错误(err)级别写入error.log
local2.warn;local2.err          /var/log/haproxy/haproxy_error.log

3.2、负载均衡实现

  • 四个节点
节点 ip 角色
server 192.68.50.20 haproxy服务器
node1 192.168.50.21 后端服务器
node2 192.168.50.22 后端服务器
client 192.168.50.1 客户端

3.2.1、配置haproxy配置文件

frontend main    # 配置前端acl规则
    bind *:80     # 所有80请求转发到http_back 这个服务器组
    default_backend         http_back


backend http_back
    balance     roundrobin   # 轮询算法
    server  node1 192.168.50.21:80 check  # 配置后端服务器
    server  node2 192.168.50.22:80 check


3.2.2、后端服务器配置

[root@node1 conf.d]# cat site1.conf 
server {
	listen 80;
	root /web/80;
}

[root@node2 conf.d]# cat site.conf 
server {
	listen 80;
	root /web/80;

}

# 网页目录定义,防火墙和selinux关闭

3.2.3、客户端访问和查看日志

[C:\~]$ curl 192.168.50.20 -s
node1:80

[C:\~]$ curl 192.168.50.20 -s
node2:80

haproxy日志

# 192.168.50.1 发起了请求
Oct 18 23:42:03 localhost haproxy[3165]: 192.168.50.1:4510 [18/Oct/2025:23:42:03.624] main http_back/node1 0/0/0/0/0 200 206 - - ---- 1/1/0/0/0 0/0 "GET / HTTP/1.1"
Oct 18 23:42:04 localhost haproxy[3165]: 192.168.50.1:4511 [18/Oct/2025:23:42:04.171] main http_back/node2 0/0/0/0/0 200 206 - - ---- 1/1/0/0/0 0/0 "GET / HTTP/1.1"

查看nginx日志

# 显示了haproxy服务器的ip地址,但是没有显示客户端的真实ip地址,后面可以添加一个选项来实现
192.168.50.20 - - [18/Oct/2025:23:45:36 +0800] "GET / HTTP/1.1" 200 9 "-" "curl/8.16.0" "-"

配置nginx日志显示客户端真实的ip地址,修改haproxy主配置文件

option                  forwardfor except 127.0.0.0/8

# forwardfo  在转发http请求时,会在请求头中添加客户端的真实ip地址,这个是传递ip地址的核心

# except  表示对127.0.0.0/8这个网段不会添加请求头,减少冗余


# 重启haproxy

systemctl restart haproxy

# 再次查看日志
192.168.50.20 - - [18/Oct/2025:23:53:02 +0800] "GET / HTTP/1.1" 200 9 "-" "curl/8.16.0" "192.168.50.1"

# 显示了客户端的真实ip地址

3.3、haproxy图形化页面

  • 图形化的监听非常的方便

修改主配置文件

listen stats  # 定义一个监听块
    bind :8000  # 监听的地址和端口,监听服务器的所有网卡的8000端口
    mode http  # http模式
    stats enable  # 开启
    stats uri /stats  # 统计页面的访问路径  :8000/stats才能访问到
    stats realm Haproxy\ Statistics
    stats auth admin:password   # 访问账号和密码,可以自定义

浏览器访问

http://192.168.50.20:8000/stats

img

3.4、acl实现动静分离

  • 就是静态的请求转发到node1,动态的请求转发到node2上

3.4.1、配置主配置文件

frontend main
    bind *:80
    default_backend         http_back
    # 定义acl规则
    acl html  path_end .html   # 匹配的后缀为html转发到html规则上
    acl php   path_end .php
    use_backend htmlweb if html  # 如果符合html规则,将其转发到htmlweb服务器组
    use_backend phpweb  if php

backend htmlweb   # 定义静态页面的服务器组
    balance roundrobin
    server  node1 192.168.50.21:80 check

backend phpweb  # 定义动态页面的服务器组
    balance roundrobin
    server ndoe2 192.168.50.22:80 check

3.4.2、配置动态服务器接收php请求

# 安装php,将php.conf文件拷贝过去
# 重启nginx即可
[root@node2 conf.d]# cat site.conf 
server {
	listen 80;
	root /web/80;
index index.php index.html index.htm;

location ~ \.(php|phar)(/.*)?$ {
    fastcgi_split_path_info ^(.+\.(?:php|phar))(/.*)$;

    fastcgi_intercept_errors on;
    fastcgi_index  index.php;
    include        fastcgi_params;
    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    fastcgi_param  PATH_INFO $fastcgi_path_info;
    fastcgi_pass   php-fpm;
}

}

3.4.3、客户端访问

img

img

4、acl规则详解

  • 这个就是haproxy的核心了

  • 可以根据这个acl将请求调度到不同的后端服务器组上

4.1、常见的acl规则(frontend块)

  • 定义在前端块里面

acl格式

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

  • aclname是必须字段,给这个acl规则自定义一个名字

  • criterion是必须字段,匹配标准,根据src(客户端ip),请求url(path),或者后缀名(path_end)

    • src 源ip

    • dst 目标ip

    • path_end 匹配文件后缀

  • flags 可选字段,用于修改匹配的行为

    • 忽略大小写(-i)

    • 正则匹配(-m)

    • 反转匹配(!)

  • operator 可选字段,匹配运算符,范围的匹配,等于(eq),大于(gt)等等

  • value 必须字段,匹配的目标值,ip,字符串,正则表达式

请求来源控制访问

# 请求来源控制访问:
		acl  allow  src 192.168.1.10
		acl  deny   src 192.168.1.0/24

请求方法控制

# 请求方法控制:
		acl  allow_get method  GET
		acl  allow_get method  POST

域名访问控制

# 域名访问控制:
		acl allow_domain hdr(host)   -i  example.com

url请求来源进行访问控制

	acl  php  url_reg  -i  \.php$  # 使用正则匹配特定url格式
	acl  php  path_end  .php  # 直接指定URL的地址为.php结尾的文件
	acl  dir   path  /api/v1/   #  匹配指定的路径

4.2、为acl规则引用(frontend块)

  • 也是配置在frontend块里面的

  • 写了acl规则,匹配即可,转发到后端服务器或者等等操作

4.2.1、use_backend 直接指定后端

use_backend backend_name if acl_name 

# 或者使用unless,就是取反,只要不是匹配acl_name的都成功,返回一个true

# if 匹配acl_name规则的,返回一个true

4.2.2、为acl指定跳转或者允许限制访问

redirection location https://example.com/ if acl_name

# 匹配acl规则,就跳转到指定网址

允许访问或者限制访问

# 需要开启mode为http,因为是七层的配置
http-request deny if acl_name # 拒绝一个acl访问

http-request allow if acl_name # 允许一个acl访问

tcp的拒绝和允许

# 客户端与服务器建立连接时进行判断
tcp-request connection {accept | reject} [{if | unless} acl_name

# 服务端发送响应后进行判断
tcp-response connection {accept | reject | close} [{if | unless} acl_name

4.3、acl的逻辑关系

  • 逻辑与

    • 默认是所有的acl之间都是逻辑与关系,2个条件同时满足即可

    • use_backend backend_name if aclname1 aclname2

  • 逻辑非

    • 多个条件中只要有一个满足即可

    • use_backend backend_name if aclname1 or aclname2

  • 逻辑或

    • 对acl进行取反

    • use_backend backend_name if !aclname

4.4、acl案例

4.4.1、允许指定的ip访问haproxy的状态页

listen stats #定义名称
        bind *:9099 #监听在9099端口
        acl sta src 192.168.29.1 #匹配名为sta且源IP地址为192.168.29.1的ACL规则
        http-request deny unless sta #拒绝除匹配sta规则以外的规则访问
        stats enable #启用stats页
        stats uri /myhaproxy?admin #自定义stats页面uri
        stats realm "Hello World" 
        stats auth admin:admin #设置状态页登录账号和密码

4.4.2、七层规则匹配

  • 一个后端服务器,80端口是一个statis 1,8080端口页面是 static 2

  • 另外一个后端服务器, 是不同的图片

  • 配置haproxy服务器

posted @ 2025-11-30 16:02  乔的港口  阅读(3)  评论(0)    收藏  举报