haproxy

基本介绍

haproxy特点

相比LVS和Nginx,LVS性能最好,但是搭建相对复杂,Nginx的upstream模块支持集群功能,但是对集群节点的健康检查功能不强,性能不如Haproxy。

概念(主要特性)

  • 可靠性和稳定性非常好,可以与硬件级的F5负载均衡设备相媲美

  • 最高可以同时维护40000-50000个并发连接,单位时间内处理的最大请求数为20000个,最大处理能力可达10Git/s

  • 支持多达八种负载均衡算法,也支持会话保持

  • 基于流量的健康评估机制,基于HTTP认证

  • 基于命令行的管理接口,有日志分析器,可以对日志进行分析

  • 有强大的ACL支持,用于访问控制(黑白名单)

  • 支持虚拟主机的功能,从而实现Web负载均衡更加灵活

LVS、Nginx、HAproxy区别

① LVS基于Linux操作系统内核实现软负载均衡,而HAproxy和Nginx是基于第三方应用实现的软负载均衡

② LVS是可实现4层的IP负载均衡技术,无法实现基于目录,URL的转发,而HAproxy和Nginx都可以实现4层和7层技术,HAproxy可以提供TCP和HTTP引用的负载均衡综合解决方案

③ LVS因为工作在ISO模型的第四层,其状态检测功能单一,而HAproxy在状态检测方面功能更丰富、强大、可支持端口、URL、脚本等多种状态检测方式

④ HAproxy功能强大,但整体性能低于4层模式的LVS负载均衡

⑤ Nginx主要用于Web服务器或者缓存服务器,Nginx的upstream模块虽然也支持集群功能,但对集群节点健康检查功能不强,性能没有HAproxy强

总体来说

反向代理、前端部署等http服务,都是用nginx

如果需要用到tcp转发,就需要用到haproxy(haproxy和frp从tcp转发角度来说,haproxy的性能更高,所以正式环境的tcp转发需要使用haproxy)

部署

.
├── config
│   └── haproxy.cfg
├── reload.sh
└── setup.sh

启动脚本

#!/bin/bash
docker stop haproxy
docker rm haproxy
docker run -d --network host --name haproxy \
--restart=always \
-v /etc/timezone:/etc/timezone:ro \
-v /etc/localtime:/etc/localtime:ro \
-v $(pwd)/config/:/usr/local/etc/haproxy/:ro \
haproxy:2.8.1-alpine

重载脚本

#!/bin/bash

if [ `docker run -i --rm --name haproxy-syntax-check -v $(pwd)/config/:/usr/local/etc/haproxy/:ro haproxy:2.8.1-alpine haproxy -c -f /usr/local/etc/haproxy/haproxy.cfg|grep -E -c "Configuration file is valid"` = 1 ];then
	docker kill -s HUP haproxy && echo "reload haproxy"
else
	echo "配置文件无效"
fi

haproxy 基本配置

global配置

全局配置部分。一般设置进程级别的配置 例如:

global
    log         127.0.0.1 local3  # 表示使用本地127.0.0.1上的rsyslog服务器中的local3设备记录
#    chroot      /var/lib/haproxy
#    pidfile     /var/run/haproxy.pid
    maxconn     100000     # 整个 HAProxy 实例的最大连接数限制为 100000。
#    user        haproxy
#    group       haproxy
    daemon    #  HAProxy 将在后台以守护进程的形式运行。

defaults配置

定义默认配置,所有的frontend、backend和listen都从该区段继承默认配置。如果在这些区段中重新声明指令配置项,则会覆盖defaults中的配置

示例:

defaults
    mode        tcp
    log         global
    option      tcplog
    # log-format {"client_ip":"%ci","client_port":"%cp","date_time":"%t","frontend_name_transport":"%ft","backend":"%b","server_name":"%s","time":"%Tq/%Tw/%Tc/%Tr/%Tt","bytes_read":"%B","connection":"%ac/%fc/%bc/%sc/%rc","queue":"%sq/%bq","backend_source_ip":"%bi","backend_source_port":"%bp","status_code":"%ST","http_request":%r,"request_headers":"%hrl","response_headers":"%hsl"}
    #option      forwardfor
    option      redispatch
    timeout connect 600s # 连接建立的超时时间为 600 秒
    timeout client 600s  # 客户端连接的超时时间为 600 秒
    timeout server 600s  # 服务器连接的超时时间为 600 秒
    maxconn     60000    # 默认的最大连接数限制为 60000
    retries     3		 # 尝试连接失败后的重试次数为 3 次

listen配置

该区段定义了一个完整的代理,属于frontend和backend的结合体,在新版中该区段不是必须的。但在老版本中所有的配置都在这一部分完成,为保证配置的兼容性,这一部分被保留 示例:

listen admin_stats					# 监听器名字
    stats   enable                      # 启用统计信息收集,允许通过 HTTP 访问 HAProxy 的统计信息
    bind    *:65000                     # 该监听器监听所有网络接口上的 65000 端口
    mode    http                        # 处理的是 HTTP 请求
    option  httplog                     # 启用了 HTTP 日志记录,将记录有关 HTTP 请求和响应的详细信息
    log     global                      # 日志记录的位置和级别,将使用 global 部分定义的设置
    maxconn 10                          # 限制了该监听器的最大连接数为 10 个
    stats   refresh 30s                 # 统计信息页面的刷新频率为 30 秒
    stats   uri /admin                  # 访问统计信息页面的 URI 为 /admin
    stats   realm haproxy               # 统计信息页面的域名称为 haproxy
    stats   auth admin:admin            # 访问统计信息页面所需的用户名和密码为 admin:admin
    stats   hide-version                # 隐藏统计信息页面中的 HAProxy 版本信息
    stats   admin if TRUE               # 根据条件是否启用统计信息页面,这里设置为始终启用

prometheus监控收集

frontend stats
   bind *:8404
   http-request use-service prometheus-exporter if { path /metrics }
   stats enable
   stats uri /stats
   stats refresh 10s

转发tcp

listen grafana
    bind 0.0.0.0:13000
    mode tcp                            # 监听器配置为 TCP 模式,即处理的是 TCP 连接
    option tcplog                       # 启用了 TCP 日志记录,将记录有关 TCP 连接的详细信息
    timeout connect 60000s
    timeout client 60000s
    timeout server 60000s
    balance roundrobin                  # 使用 Round Robin 负载均衡算法来分配请求给后端服务器
    option tcpka                        # 启用了 TCP 保持活动功能,以在客户端和服务器之间保持长连接
    server s1 172.168.1.58:3000         # 指定了一个后端服务器,其中 s1 是服务器的名称

send-proxy模式

在 HAProxy 中,send-proxy 模式是一种功能,用于在代理之间传递客户端的原始连接信息。它允许在代理之间传递客户端的原始 IP 地址和端口信息,而不是只传递已经建立的连接。

通常情况下,在 TCP 代理中,当客户端连接到代理时,代理会建立一个新的连接到后端服务器,而此时代理服务器和后端服务器之间的连接是新建立的,与客户端的连接不同。这就导致后端服务器无法获取客户端的真实 IP 地址。

但是,通过使用 send-proxy 模式,代理服务器可以在与后端服务器建立连接时,发送客户端的原始连接信息,包括客户端的 IP 地址和端口等。后端服务器收到这些信息后,就可以知道客户端的真实 IP 地址,并可以根据需要进行相应的处理,比如记录日志、做访问控制等。

server backend1 192.168.1.10:80 send-proxy

这会告诉 HAProxy 在与后端服务器建立连接时,发送客户端的原始连接信息。在后端服务器的配置中,你也需要相应地配置以接收这些信息。

总的来说,send-proxy 模式可以帮助你解决代理服务器无法获取客户端真实 IP 地址的问题,提高了代理服务的灵活性和功能性。

当你启用 send-proxy 模式后,在与后端服务器建立连接时,HAProxy 会在 TCP 数据包的头部添加一些特殊的代理协议头。这些头部信息包含了客户端的 IP 地址和端口,以及一些其他的元数据。