Nginx 负载均衡
掌握 Nginx 作为负载均衡器的配置和最佳实践
什么是负载均衡?
负载均衡是一种将网络流量分发到多个服务器的技术,以提高系统的可用性、可靠性和性能。通过负载均衡,您可以:
- 提高系统容量和吞吐量
- 实现故障转移和高可用性
- 优化资源利用
- 简化应用程序扩展
Nginx 负载均衡基础配置
http {
# 上游服务器组配置
upstream backend {
server backend1.example.com weight=5;
server backend2.example.com;
server 192.168.0.100:8080 max_fails=3 fail_timeout=30s;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://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;
}
}
}
配置说明
- upstream - 定义上游服务器组,包含多个后端服务器
- server - 定义后端服务器,可以是域名、IP地址或Unix套接字
- weight - 设置服务器权重,默认为1,权重越高,接收的请求越多
- max_fails - 在fail_timeout时间内最大失败次数,超过则标记为不可用
- fail_timeout - 服务器标记为不可用的时间
负载均衡算法
轮询(默认)
轮询是Nginx默认的负载均衡算法,按顺序将请求分发到后端服务器。
upstream backend {
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
}
权重轮询
根据服务器权重分发请求,权重越高,接收的请求越多。
upstream backend {
server backend1.example.com weight=5;
server backend2.example.com weight=3;
server backend3.example.com weight=2;
}
IP哈希
根据客户端IP地址哈希值分发请求,确保同一客户端始终访问同一服务器。
upstream backend {
ip_hash;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
}
最少连接
将请求分发到当前活跃连接数最少的服务器。
upstream backend {
least_conn;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
}
通用哈希
根据指定的键(如请求URI)哈希值分发请求。
upstream backend {
hash $request_uri consistent;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
}
健康检查配置
被动健康检查
通过监控连接尝试自动检测服务器健康状态。
upstream backend {
server backend1.example.com max_fails=3 fail_timeout=30s;
server backend2.example.com max_fails=3 fail_timeout=30s;
server backend3.example.com max_fails=3 fail_timeout=30s;
}
主动健康检查(ngx_http_upstream_check_module)
需要安装第三方模块ngx_http_upstream_check_module。
upstream backend {
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
check interval=3000 rise=2 fall=5 timeout=1000 type=http;
check_http_send "HEAD /health HTTP/1.0\r\n\r\n";
check_http_expect_alive http_2xx http_3xx;
}
会话保持配置
IP哈希会话保持
upstream backend {
ip_hash;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
}
Sticky 会话(nginx-sticky-module)
需要安装第三方模块nginx-sticky-module。
upstream backend {
sticky;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
}
高级负载均衡配置
动静分离
upstream static_backend {
server static1.example.com;
server static2.example.com;
}
upstream dynamic_backend {
server app1.example.com;
server app2.example.com;
server app3.example.com;
}
server {
listen 80;
server_name example.com;
# 静态资源
location ~* \.(jpg|jpeg|png|gif|css|js|ico)$ {
proxy_pass http://static_backend;
}
# 动态内容
location / {
proxy_pass http://dynamic_backend;
}
}
基于URL路径的负载均衡
upstream api_backend {
server api1.example.com;
server api2.example.com;
}
upstream web_backend {
server web1.example.com;
server web2.example.com;
}
server {
listen 80;
server_name example.com;
location /api/ {
proxy_pass http://api_backend;
}
location / {
proxy_pass http://web_backend;
}
}
实践练习
练习1:基本负载均衡配置
- 准备3台后端服务器,分别运行在3000、3001、3002端口
- 配置Nginx负载均衡,将请求分发到这3台服务器
- 测试负载均衡是否生效,观察请求是否分发到不同服务器
练习2:会话保持配置
- 配置IP哈希会话保持
- 测试同一客户端是否始终访问同一服务器
- 模拟服务器故障,观察故障转移情况
练习3:健康检查配置
- 配置被动健康检查
- 模拟服务器故障,观察Nginx是否自动将其标记为不可用
- 恢复服务器,观察Nginx是否自动将其标记为可用
常见问题解答
Q: 负载均衡与反向代理的区别是什么?
A: 反向代理是将请求转发到单个后端服务器,而负载均衡是将请求分发到多个后端服务器,提高系统可用性和性能。
Q: 如何选择合适的负载均衡算法?
A: 根据应用场景选择:
- 轮询:适用于服务器配置相似的场景
- 权重轮询:适用于服务器配置不同的场景
- IP哈希:需要会话保持的场景
- 最少连接:长连接较多的场景
Q: 负载均衡器如何处理会话保持?
A: 可以使用IP哈希、cookie粘性会话或应用层会话共享来实现会话保持。
Q: 如何监控负载均衡状态?
A: 可以使用Nginx的status模块、Prometheus+Grafana或专业监控工具如Zabbix。