Apache 负载均衡 #

负载均衡概述 #

什么是负载均衡? #

text
┌─────────────────────────────────────────────────────────────┐
│                    负载均衡概念                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  负载均衡:将请求分发到多个后端服务器                        │
│                                                             │
│  作用:                                                     │
│  ├── 提高可用性 - 单点故障不影响整体                        │
│  ├── 提升性能 - 分担请求压力                               │
│  ├── 弹性扩展 - 动态增减服务器                             │
│  └── 灵活运维 - 可进行灰度发布                             │
│                                                             │
│  架构示例:                                                 │
│                                                             │
│           ┌─────────────────┐                              │
│           │   Apache LB     │                              │
│           │  负载均衡器     │                              │
│           └────────┬────────┘                              │
│                    │                                        │
│     ┌──────────────┼──────────────┐                        │
│     │              │              │                        │
│     ▼              ▼              ▼                        │
│ ┌────────┐    ┌────────┐    ┌────────┐                    │
│ │Server 1│    │Server 2│    │Server 3│                    │
│ │ :3000  │    │ :3000  │    │ :3000  │                    │
│ └────────┘    └────────┘    └────────┘                    │
│                                                             │
└─────────────────────────────────────────────────────────────┘

负载均衡算法 #

text
┌─────────────────────────────────────────────────────────────┐
│                    负载均衡算法                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  轮询(Round Robin)                                        │
│  按顺序依次分发请求到各服务器                               │
│  适用于服务器性能相近的场景                                 │
│                                                             │
│  加权轮询(Weighted Round Robin)                           │
│  根据权重分配请求,权重高的服务器处理更多请求               │
│  适用于服务器性能差异的场景                                 │
│                                                             │
│  最少连接(Least Connections)                              │
│  将请求分发给当前连接数最少的服务器                         │
│  适用于长连接场景                                           │
│                                                             │
│  IP 哈希(IP Hash)                                         │
│  根据客户端 IP 计算哈希值分配服务器                         │
│  适用于需要会话保持的场景                                   │
│                                                             │
└─────────────────────────────────────────────────────────────┘

启用代理模块 #

加载必要模块 #

bash
# Ubuntu/Debian
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_balancer
sudo a2enmod lbmethod_byrequests
sudo a2enmod lbmethod_bytraffic
sudo a2enmod lbmethod_bybusyness
sudo a2enmod lbmethod_heartbeat
sudo a2enmod headers
sudo systemctl restart apache2

基础负载均衡配置 #

简单轮询配置 #

apache
# ============================================
# 简单轮询负载均衡
# ============================================

<Proxy "balancer://mycluster">
    BalancerMember "http://server1:3000"
    BalancerMember "http://server2:3000"
    BalancerMember "http://server3:3000"
</Proxy>

<VirtualHost *:80>
    ServerName example.com
    
    ProxyPass / balancer://mycluster/
    ProxyPassReverse / balancer://mycluster/
    
    ProxyPreserveHost On
</VirtualHost>

加权轮询配置 #

apache
# ============================================
# 加权轮询负载均衡
# ============================================

<Proxy "balancer://weighted">
    # loadfactor 范围 1-100
    BalancerMember "http://server1:3000" loadfactor=3
    BalancerMember "http://server2:3000" loadfactor=2
    BalancerMember "http://server3:3000" loadfactor=1
</Proxy>

<VirtualHost *:80>
    ServerName example.com
    
    ProxyPass / balancer://weighted/
    ProxyPassReverse / balancer://weighted/
</VirtualHost>

最少连接配置 #

apache
# ============================================
# 最少连接负载均衡
# ============================================

<Proxy "balancer://leastconn" lbmethod=bybusyness>
    BalancerMember "http://server1:3000"
    BalancerMember "http://server2:3000"
    BalancerMember "http://server3:3000"
</Proxy>

<VirtualHost *:80>
    ServerName example.com
    
    ProxyPass / balancer://leastconn/
    ProxyPassReverse / balancer://leastconn/
</VirtualHost>

流量均衡配置 #

apache
# ============================================
# 流量均衡负载均衡
# ============================================

<Proxy "balancer://traffic" lbmethod=bytraffic>
    BalancerMember "http://server1:3000"
    BalancerMember "http://server2:3000"
    BalancerMember "http://server3:3000"
</Proxy>

<VirtualHost *:80>
    ServerName example.com
    
    ProxyPass / balancer://traffic/
    ProxyPassReverse / balancer://traffic/
</VirtualHost>

会话保持 #

apache
# ============================================
# Cookie 会话保持
# ============================================

<Proxy "balancer://sticky">
    BalancerMember "http://server1:3000" route=server1
    BalancerMember "http://server2:3000" route=server2
    BalancerMember "http://server3:3000" route=server3
    
    ProxySet stickysession=SERVERID
</Proxy>

<VirtualHost *:80>
    ServerName example.com
    
    ProxyPass / balancer://sticky/
    ProxyPassReverse / balancer://sticky/
</VirtualHost>

# 后端应用需要设置 Cookie: SERVERID=server1

基于 IP 的会话保持 #

apache
# ============================================
# IP 哈希会话保持
# ============================================

# 使用 mod_rewrite 实现
RewriteEngine On

RewriteMap lb "rnd:/path/to/server.map"
RewriteRule ^/(.*)$ http://${lb:servers}/$1 [P,L]

# server.map 文件内容
# servers server1|server2|server3

健康检查 #

基础健康检查 #

apache
# ============================================
# 健康检查配置
# ============================================

<Proxy "balancer://healthcheck">
    BalancerMember "http://server1:3000" retry=5 timeout=60
    BalancerMember "http://server2:3000" retry=5 timeout=60
    BalancerMember "http://server3:3000" retry=5 timeout=60
    
    ProxySet timeout=60
</Proxy>

<VirtualHost *:80>
    ServerName example.com
    
    ProxyPass / balancer://healthcheck/
    ProxyPassReverse / balancer://healthcheck/
    
    # 故障转移页面
    ErrorDocument 502 /maintenance.html
    ErrorDocument 503 /maintenance.html
</VirtualHost>

参数说明 #

text
┌─────────────────────────────────────────────────────────────┐
│                    BalancerMember 参数                       │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  retry=N          重试次数,默认 60 秒                      │
│  timeout=N        超时时间(秒)                            │
│  ttl=N            连接生存时间                              │
│  min=N            最小连接数                                │
│  max=N            最大连接数                                │
│  smax=N           最大软连接数                              │
│  acquire=N        获取连接超时(毫秒)                      │
│  keepalive=On/Off 保持连接                                  │
│  disablereuse=On  禁用连接重用                              │
│  connectiontimeout=N 连接超时                               │
│  flushpackets=On  刷新数据包                                │
│                                                             │
└─────────────────────────────────────────────────────────────┘

负载均衡管理界面 #

启用管理界面 #

apache
# ============================================
# 负载均衡管理界面
# ============================================

<Location "/balancer-manager">
    SetHandler balancer-manager
    Require ip 192.168.1.0/24
</Location>

<VirtualHost *:80>
    ServerName example.com
    
    <Proxy "balancer://mycluster">
        BalancerMember "http://server1:3000"
        BalancerMember "http://server2:3000"
    </Proxy>
    
    ProxyPass /balancer-manager !
    ProxyPass / balancer://mycluster/
    ProxyPassReverse / balancer://mycluster/
</VirtualHost>

多路径负载均衡 #

按路径分发 #

apache
# ============================================
# 多路径负载均衡
# ============================================

# API 集群
<Proxy "balancer://api">
    BalancerMember "http://api1:3000"
    BalancerMember "http://api2:3000"
</Proxy>

# Web 集群
<Proxy "balancer://web">
    BalancerMember "http://web1:8080"
    BalancerMember "http://web2:8080"
</Proxy>

<VirtualHost *:80>
    ServerName example.com
    
    # API 路径
    ProxyPass /api balancer://api/api
    ProxyPassReverse /api balancer://api/api
    
    # Web 路径
    ProxyPass / balancer://web/
    ProxyPassReverse / balancer://web/
</VirtualHost>

SSL 终止负载均衡 #

HTTPS 负载均衡 #

apache
# ============================================
# HTTPS 负载均衡
# ============================================

<VirtualHost *:443>
    ServerName example.com
    
    SSLEngine on
    SSLCertificateFile /etc/ssl/certs/example.com.crt
    SSLCertificateKeyFile /etc/ssl/private/example.com.key
    
    <Proxy "balancer://backend">
        BalancerMember "http://server1:3000"
        BalancerMember "http://server2:3000"
    </Proxy>
    
    ProxyPass / balancer://backend/
    ProxyPassReverse / balancer://backend/
    
    # 添加 HTTPS 标识
    RequestHeader set X-Forwarded-Proto "https"
</VirtualHost>

完整配置示例 #

apache
# ============================================
# 完整负载均衡配置
# ============================================

# 后端集群定义
<Proxy "balancer://app">
    BalancerMember "http://app1:3000" route=app1 retry=5 timeout=60
    BalancerMember "http://app2:3000" route=app2 retry=5 timeout=60
    BalancerMember "http://app3:3000" route=app3 retry=5 timeout=60
    
    ProxySet lbmethod=byrequests
    ProxySet stickysession=SERVERID
    ProxySet timeout=60
</Proxy>

<VirtualHost *:80>
    ServerName example.com
    
    # 管理界面
    <Location "/balancer-manager">
        SetHandler balancer-manager
        Require ip 192.168.1.0/24
    </Location>
    
    # 排除管理界面
    ProxyPass /balancer-manager !
    
    # 代理配置
    ProxyPass / balancer://app/
    ProxyPassReverse / balancer://app/
    
    # 保留主机名
    ProxyPreserveHost On
    
    # 请求头
    RequestHeader set X-Forwarded-For "%{REMOTE_ADDR}s"
    RequestHeader set X-Forwarded-Proto "%{REQUEST_SCHEME}s"
    
    # 健康检查端点
    ProxyPass /health http://localhost/health-status
    ProxyPassReverse /health http://localhost/health-status
    
    # 故障页面
    ErrorDocument 502 /maintenance.html
    ErrorDocument 503 /maintenance.html
    
    # 日志
    ErrorLog ${APACHE_LOG_DIR}/lb-error.log
    CustomLog ${APACHE_LOG_DIR}/lb-access.log combined
</VirtualHost>

下一步 #

掌握了负载均衡后,继续学习 PHP 集成,了解如何配置 Apache 与 PHP 的集成!

最后更新:2026-03-29