load-balancing

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Load Balancing

负载均衡

Distribute traffic across application servers for high availability, scalability, and fault tolerance.
在应用服务器之间分发流量,以实现高可用性、可扩展性和容错能力。

When to Use

使用场景

  • Distributing HTTP/HTTPS traffic across multiple backend servers.
  • Implementing health checks to route around unhealthy instances.
  • Terminating TLS at the load balancer for simplified certificate management.
  • Enabling blue/green or canary deployments with traffic shifting.
  • Scaling horizontally behind a single entry point.
  • 在多个后端服务器之间分发HTTP/HTTPS流量。
  • 实现健康检查,将流量从异常实例路由出去。
  • 在负载均衡器处终止TLS,简化证书管理。
  • 通过流量切换实现蓝绿部署或金丝雀部署。
  • 在单一入口点后进行水平扩展。

Prerequisites

前提条件

  • Two or more backend servers running the same application.
  • TLS certificate for HTTPS termination (ACM, Let's Encrypt, or self-signed for internal).
  • For AWS: VPC with public and private subnets across availability zones.
  • For nginx/HAProxy: Linux server with root access.
  • 两台或更多运行相同应用的后端服务器。
  • 用于HTTPS终止的TLS证书(ACM、Let's Encrypt或内部自签名证书)。
  • 对于AWS:跨可用区的带有公有和私有子网的VPC。
  • 对于nginx/HAProxy:具有root权限的Linux服务器。

nginx Load Balancer

nginx Load Balancer

Basic Round-Robin

基础轮询配置

nginx
undefined
nginx
undefined

/etc/nginx/conf.d/loadbalancer.conf

/etc/nginx/conf.d/loadbalancer.conf

upstream app_backend { server 10.0.1.10:8080; server 10.0.1.11:8080; server 10.0.1.12:8080; }
server { listen 80; server_name app.example.com; return 301 https://$host$request_uri; }
server { listen 443 ssl http2; server_name app.example.com;
ssl_certificate     /etc/ssl/certs/app.example.com.pem;
ssl_certificate_key /etc/ssl/private/app.example.com-key.pem;
ssl_protocols       TLSv1.2 TLSv1.3;
ssl_ciphers         HIGH:!aNULL:!MD5;

location / {
    proxy_pass http://app_backend;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;

    proxy_connect_timeout 5s;
    proxy_read_timeout 30s;
    proxy_send_timeout 30s;
}

location /health {
    access_log off;
    return 200 "OK";
}
}
undefined
upstream app_backend { server 10.0.1.10:8080; server 10.0.1.11:8080; server 10.0.1.12:8080; }
server { listen 80; server_name app.example.com; return 301 https://$host$request_uri; }
server { listen 443 ssl http2; server_name app.example.com;
ssl_certificate     /etc/ssl/certs/app.example.com.pem;
ssl_certificate_key /etc/ssl/private/app.example.com-key.pem;
ssl_protocols       TLSv1.2 TLSv1.3;
ssl_ciphers         HIGH:!aNULL:!MD5;

location / {
    proxy_pass http://app_backend;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;

    proxy_connect_timeout 5s;
    proxy_read_timeout 30s;
    proxy_send_timeout 30s;
}

location /health {
    access_log off;
    return 200 "OK";
}
}
undefined

Weighted and Backup Servers

加权与备用服务器

nginx
upstream app_backend {
    least_conn;  # Route to server with fewest active connections

    server 10.0.1.10:8080 weight=5;      # Gets 5x traffic
    server 10.0.1.11:8080 weight=3;      # Gets 3x traffic
    server 10.0.1.12:8080 weight=1;      # Gets 1x traffic
    server 10.0.1.20:8080 backup;        # Only used when others are down
    server 10.0.1.21:8080 down;          # Temporarily removed from pool
}
nginx
upstream app_backend {
    least_conn;  # Route to server with fewest active connections

    server 10.0.1.10:8080 weight=5;      # Gets 5x traffic
    server 10.0.1.11:8080 weight=3;      # Gets 3x traffic
    server 10.0.1.12:8080 weight=1;      # Gets 1x traffic
    server 10.0.1.20:8080 backup;        # Only used when others are down
    server 10.0.1.21:8080 down;          # Temporarily removed from pool
}

Health Checks (nginx Plus / OpenResty)

健康检查(nginx Plus / OpenResty)

nginx
upstream app_backend {
    zone backend 64k;  # Shared memory zone for health data

    server 10.0.1.10:8080;
    server 10.0.1.11:8080;
    server 10.0.1.12:8080;
}
nginx
upstream app_backend {
    zone backend 64k;  # Shared memory zone for health data

    server 10.0.1.10:8080;
    server 10.0.1.11:8080;
    server 10.0.1.12:8080;
}

Health check (requires nginx Plus or third-party module)

Health check (requires nginx Plus or third-party module)

match healthy {

match healthy {

status 200;

status 200;

body ~ "OK";

body ~ "OK";

}

}

health_check interval=5s fails=3 passes=2 match=healthy;

health_check interval=5s fails=3 passes=2 match=healthy;

undefined
undefined

Sticky Sessions (IP Hash)

粘性会话(IP哈希)

nginx
upstream app_backend {
    ip_hash;  # Same client IP always goes to the same server
    server 10.0.1.10:8080;
    server 10.0.1.11:8080;
    server 10.0.1.12:8080;
}
nginx
upstream app_backend {
    ip_hash;  # Same client IP always goes to the same server
    server 10.0.1.10:8080;
    server 10.0.1.11:8080;
    server 10.0.1.12:8080;
}

HAProxy Configuration

HAProxy配置

Full Production Config

完整生产环境配置

undefined
undefined

/etc/haproxy/haproxy.cfg

/etc/haproxy/haproxy.cfg

global log /dev/log local0 maxconn 4096 daemon ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256 ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11 tune.ssl.default-dh-param 2048
defaults mode http log global option httplog option dontlognull option forwardfor timeout connect 5s timeout client 30s timeout server 30s timeout http-request 10s timeout http-keep-alive 5s retries 3
frontend http_front bind *:80 redirect scheme https code 301 if !{ ssl_fc }
frontend https_front bind *:443 ssl crt /etc/ssl/certs/app.example.com.pem http-request set-header X-Forwarded-Proto https
# Route based on path
acl is_api path_beg /api/
acl is_ws  path_beg /ws/

use_backend api_servers if is_api
use_backend ws_servers  if is_ws
default_backend web_servers
backend web_servers balance roundrobin option httpchk GET /health HTTP/1.1\r\nHost:\ app.example.com http-check expect status 200
cookie SERVERID insert indirect nocache
server web1 10.0.1.10:8080 check inter 5s fall 3 rise 2 cookie web1
server web2 10.0.1.11:8080 check inter 5s fall 3 rise 2 cookie web2
server web3 10.0.1.12:8080 check inter 5s fall 3 rise 2 cookie web3
backend api_servers balance leastconn option httpchk GET /api/health http-check expect status 200
server api1 10.0.2.10:8080 check inter 5s fall 3 rise 2
server api2 10.0.2.11:8080 check inter 5s fall 3 rise 2
backend ws_servers balance source option httpchk GET /health timeout tunnel 1h
server ws1 10.0.3.10:8080 check inter 5s fall 3 rise 2
server ws2 10.0.3.11:8080 check inter 5s fall 3 rise 2
listen stats bind *:8404 stats enable stats uri /stats stats refresh 10s stats admin if LOCALHOST
undefined
global log /dev/log local0 maxconn 4096 daemon ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256 ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11 tune.ssl.default-dh-param 2048
defaults mode http log global option httplog option dontlognull option forwardfor timeout connect 5s timeout client 30s timeout server 30s timeout http-request 10s timeout http-keep-alive 5s retries 3
frontend http_front bind *:80 redirect scheme https code 301 if !{ ssl_fc }
frontend https_front bind *:443 ssl crt /etc/ssl/certs/app.example.com.pem http-request set-header X-Forwarded-Proto https
# Route based on path
acl is_api path_beg /api/
acl is_ws  path_beg /ws/

use_backend api_servers if is_api
use_backend ws_servers  if is_ws
default_backend web_servers
backend web_servers balance roundrobin option httpchk GET /health HTTP/1.1\r\nHost:\ app.example.com http-check expect status 200
cookie SERVERID insert indirect nocache
server web1 10.0.1.10:8080 check inter 5s fall 3 rise 2 cookie web1
server web2 10.0.1.11:8080 check inter 5s fall 3 rise 2 cookie web2
server web3 10.0.1.12:8080 check inter 5s fall 3 rise 2 cookie web3
backend api_servers balance leastconn option httpchk GET /api/health http-check expect status 200
server api1 10.0.2.10:8080 check inter 5s fall 3 rise 2
server api2 10.0.2.11:8080 check inter 5s fall 3 rise 2
backend ws_servers balance source option httpchk GET /health timeout tunnel 1h
server ws1 10.0.3.10:8080 check inter 5s fall 3 rise 2
server ws2 10.0.3.11:8080 check inter 5s fall 3 rise 2
listen stats bind *:8404 stats enable stats uri /stats stats refresh 10s stats admin if LOCALHOST
undefined

HAProxy Management

HAProxy管理

bash
undefined
bash
undefined

Test config before reloading

Test config before reloading

haproxy -c -f /etc/haproxy/haproxy.cfg
haproxy -c -f /etc/haproxy/haproxy.cfg

Reload without dropping connections

Reload without dropping connections

sudo systemctl reload haproxy
sudo systemctl reload haproxy

View stats from CLI

View stats from CLI

echo "show stat" | sudo socat stdio /var/run/haproxy/admin.sock
echo "show stat" | sudo socat stdio /var/run/haproxy/admin.sock

Drain a server (stop new connections, let existing finish)

Drain a server (stop new connections, let existing finish)

echo "set server web_servers/web1 state drain" | sudo socat stdio /var/run/haproxy/admin.sock
echo "set server web_servers/web1 state drain" | sudo socat stdio /var/run/haproxy/admin.sock

Set server to maintenance

Set server to maintenance

echo "set server web_servers/web1 state maint" | sudo socat stdio /var/run/haproxy/admin.sock
echo "set server web_servers/web1 state maint" | sudo socat stdio /var/run/haproxy/admin.sock

Re-enable server

Re-enable server

echo "set server web_servers/web1 state ready" | sudo socat stdio /var/run/haproxy/admin.sock
undefined
echo "set server web_servers/web1 state ready" | sudo socat stdio /var/run/haproxy/admin.sock
undefined

AWS Application Load Balancer (ALB)

AWS应用负载均衡器(ALB)

Create ALB via CLI

通过CLI创建ALB

bash
undefined
bash
undefined

Create the load balancer

Create the load balancer

aws elbv2 create-load-balancer
--name my-app-alb
--subnets subnet-aaa111 subnet-bbb222
--security-groups sg-xxx123
--type application
--scheme internet-facing
aws elbv2 create-load-balancer
--name my-app-alb
--subnets subnet-aaa111 subnet-bbb222
--security-groups sg-xxx123
--type application
--scheme internet-facing

Create a target group

Create a target group

aws elbv2 create-target-group
--name my-app-targets
--protocol HTTP
--port 8080
--vpc-id vpc-xxx123
--health-check-protocol HTTP
--health-check-path /health
--health-check-interval-seconds 15
--healthy-threshold-count 2
--unhealthy-threshold-count 3
--target-type instance
aws elbv2 create-target-group
--name my-app-targets
--protocol HTTP
--port 8080
--vpc-id vpc-xxx123
--health-check-protocol HTTP
--health-check-path /health
--health-check-interval-seconds 15
--healthy-threshold-count 2
--unhealthy-threshold-count 3
--target-type instance

Register targets

Register targets

aws elbv2 register-targets
--target-group-arn arn:aws:elasticloadbalancing:us-east-1:123456:targetgroup/my-app-targets/abc123
--targets Id=i-0123456789abc Id=i-0987654321def
aws elbv2 register-targets
--target-group-arn arn:aws:elasticloadbalancing:us-east-1:123456:targetgroup/my-app-targets/abc123
--targets Id=i-0123456789abc Id=i-0987654321def

Create HTTPS listener

Create HTTPS listener

aws elbv2 create-listener
--load-balancer-arn arn:aws:elasticloadbalancing:us-east-1:123456:loadbalancer/app/my-app-alb/abc123
--protocol HTTPS
--port 443
--certificates CertificateArn=arn:aws:acm:us-east-1:123456:certificate/abc-123
--default-actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:us-east-1:123456:targetgroup/my-app-targets/abc123
aws elbv2 create-listener
--load-balancer-arn arn:aws:elasticloadbalancing:us-east-1:123456:loadbalancer/app/my-app-alb/abc123
--protocol HTTPS
--port 443
--certificates CertificateArn=arn:aws:acm:us-east-1:123456:certificate/abc-123
--default-actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:us-east-1:123456:targetgroup/my-app-targets/abc123

Create HTTP redirect listener

Create HTTP redirect listener

aws elbv2 create-listener
--load-balancer-arn arn:aws:elasticloadbalancing:us-east-1:123456:loadbalancer/app/my-app-alb/abc123
--protocol HTTP
--port 80
--default-actions Type=redirect,RedirectConfig='{Protocol=HTTPS,Port=443,StatusCode=HTTP_301}'
undefined
aws elbv2 create-listener
--load-balancer-arn arn:aws:elasticloadbalancing:us-east-1:123456:loadbalancer/app/my-app-alb/abc123
--protocol HTTP
--port 80
--default-actions Type=redirect,RedirectConfig='{Protocol=HTTPS,Port=443,StatusCode=HTTP_301}'
undefined

Check Target Health

检查目标健康状态

bash
undefined
bash
undefined

Check health of registered targets

Check health of registered targets

aws elbv2 describe-target-health
--target-group-arn arn:aws:elasticloadbalancing:us-east-1:123456:targetgroup/my-app-targets/abc123
undefined
aws elbv2 describe-target-health
--target-group-arn arn:aws:elasticloadbalancing:us-east-1:123456:targetgroup/my-app-targets/abc123
undefined

AWS Network Load Balancer (NLB)

AWS网络负载均衡器(NLB)

bash
undefined
bash
undefined

Create NLB (for TCP, UDP, or TLS traffic)

Create NLB (for TCP, UDP, or TLS traffic)

aws elbv2 create-load-balancer
--name my-tcp-nlb
--subnets subnet-aaa111 subnet-bbb222
--type network
--scheme internet-facing
aws elbv2 create-load-balancer
--name my-tcp-nlb
--subnets subnet-aaa111 subnet-bbb222
--type network
--scheme internet-facing

Create TCP target group

Create TCP target group

aws elbv2 create-target-group
--name my-tcp-targets
--protocol TCP
--port 5432
--vpc-id vpc-xxx123
--health-check-protocol TCP
--target-type ip
undefined
aws elbv2 create-target-group
--name my-tcp-targets
--protocol TCP
--port 5432
--vpc-id vpc-xxx123
--health-check-protocol TCP
--target-type ip
undefined

ALB with Terraform

使用Terraform配置ALB

hcl
resource "aws_lb" "app" {
  name               = "my-app-alb"
  internal           = false
  load_balancer_type = "application"
  security_groups    = [aws_security_group.alb.id]
  subnets            = var.public_subnet_ids

  enable_deletion_protection = true
}

resource "aws_lb_target_group" "app" {
  name     = "my-app-tg"
  port     = 8080
  protocol = "HTTP"
  vpc_id   = var.vpc_id

  health_check {
    path                = "/health"
    port                = "traffic-port"
    healthy_threshold   = 2
    unhealthy_threshold = 3
    timeout             = 5
    interval            = 15
    matcher             = "200"
  }

  deregistration_delay = 30

  stickiness {
    type            = "lb_cookie"
    cookie_duration = 86400
    enabled         = true
  }
}

resource "aws_lb_listener" "https" {
  load_balancer_arn = aws_lb.app.arn
  port              = 443
  protocol          = "HTTPS"
  ssl_policy        = "ELBSecurityPolicy-TLS13-1-2-2021-06"
  certificate_arn   = aws_acm_certificate.cert.arn

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.app.arn
  }
}

resource "aws_lb_listener" "http_redirect" {
  load_balancer_arn = aws_lb.app.arn
  port              = 80
  protocol          = "HTTP"

  default_action {
    type = "redirect"
    redirect {
      port        = "443"
      protocol    = "HTTPS"
      status_code = "HTTP_301"
    }
  }
}
hcl
resource "aws_lb" "app" {
  name               = "my-app-alb"
  internal           = false
  load_balancer_type = "application"
  security_groups    = [aws_security_group.alb.id]
  subnets            = var.public_subnet_ids

  enable_deletion_protection = true
}

resource "aws_lb_target_group" "app" {
  name     = "my-app-tg"
  port     = 8080
  protocol = "HTTP"
  vpc_id   = var.vpc_id

  health_check {
    path                = "/health"
    port                = "traffic-port"
    healthy_threshold   = 2
    unhealthy_threshold = 3
    timeout             = 5
    interval            = 15
    matcher             = "200"
  }

  deregistration_delay = 30

  stickiness {
    type            = "lb_cookie"
    cookie_duration = 86400
    enabled         = true
  }
}

resource "aws_lb_listener" "https" {
  load_balancer_arn = aws_lb.app.arn
  port              = 443
  protocol          = "HTTPS"
  ssl_policy        = "ELBSecurityPolicy-TLS13-1-2-2021-06"
  certificate_arn   = aws_acm_certificate.cert.arn

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.app.arn
  }
}

resource "aws_lb_listener" "http_redirect" {
  load_balancer_arn = aws_lb.app.arn
  port              = 80
  protocol          = "HTTP"

  default_action {
    type = "redirect"
    redirect {
      port        = "443"
      protocol    = "HTTPS"
      status_code = "HTTP_301"
    }
  }
}

Load Balancing Algorithms

负载均衡算法

AlgorithmUse CasenginxHAProxy
Round RobinDefault, equal servers
(default)
balance roundrobin
Least ConnectionsUneven request durations
least_conn
balance leastconn
IP HashSession persistence without cookies
ip_hash
balance source
URI HashCache locality per URL
hash $request_uri
balance uri
Random with TwoLarge server pools
random two least_conn
balance random(2)
算法适用场景nginxHAProxy
Round Robin默认方案,服务器性能均等
(default)
balance roundrobin
Least Connections请求时长不均衡的场景
least_conn
balance leastconn
IP Hash无需Cookie的会话持久化
ip_hash
balance source
URI Hash基于URL的缓存一致性
hash $request_uri
balance uri
Random with Two大型服务器池场景
random two least_conn
balance random(2)

Troubleshooting

故障排查

SymptomCauseFix
All backends show "unhealthy"Health check path returns non-200Verify
/health
endpoint returns 200; check security groups
502 Bad GatewayBackend not running or wrong portConfirm backend is listening on the configured port
Uneven traffic distributionSticky sessions or weighted configCheck session affinity settings; review server weights
Connection timeoutsBackend too slow or timeout too lowIncrease
proxy_read_timeout
or HAProxy
timeout server
TLS handshake failuresCertificate mismatch or expired certVerify cert matches the domain; renew if expired
ALB returns 503No healthy targets registeredCheck target group health; verify targets are in correct subnets
WebSocket disconnectsProxy not configured for upgradesAdd
proxy_set_header Upgrade
and
Connection "upgrade"
症状原因解决方法
所有后端显示“异常”健康检查路径返回非200状态码验证
/health
端点返回200;检查安全组配置
502 Bad Gateway后端未运行或端口配置错误确认后端正在监听配置的端口
流量分发不均衡粘性会话或加权配置问题检查会话亲和性设置;查看服务器权重配置
连接超时后端响应过慢或超时时间设置过短增大
proxy_read_timeout
或HAProxy的
timeout server
TLS握手失败证书不匹配或已过期验证证书与域名匹配;过期则重新颁发
ALB返回503无健康目标实例注册检查目标组健康状态;验证目标实例是否在正确子网中
WebSocket断开连接代理未配置升级支持添加
proxy_set_header Upgrade
Connection "upgrade"
配置

Related Skills

相关技能

  • reverse-proxy - Reverse proxy configuration patterns
  • dns-management - DNS records pointing to load balancers
  • cdn-setup - CDN in front of load balanced origins
  • service-mesh - Service-level load balancing in Kubernetes
  • reverse-proxy - 反向代理配置模式
  • dns-management - 指向负载均衡器的DNS记录配置
  • cdn-setup - 负载均衡源站前端的CDN配置
  • service-mesh - Kubernetes中的服务级负载均衡