文章目录
-
-
- 1. 负载均衡核心基础{#lb-basic}
-
- [1.1 核心概念](#1.1 核心概念)
- [1.2 主流负载均衡算法](#1.2 主流负载均衡算法)
- [1.3 主流负载均衡工具](#1.3 主流负载均衡工具)
- 2. 实战环境准备与规划{#env-prepare}
-
- [2.1 环境规划(虚拟机/云服务器)](#2.1 环境规划(虚拟机/云服务器))
- [2.2 前置环境配置(所有节点)](#2.2 前置环境配置(所有节点))
- 3. 后端服务集群搭建(Docker+Spring Boot){#backend-cluster}
-
- [3.1 编写Spring Boot测试服务](#3.1 编写Spring Boot测试服务)
- [3.2 构建Docker镜像](#3.2 构建Docker镜像)
- [3.3 启动后端服务容器](#3.3 启动后端服务容器)
- 4. Nginx负载均衡核心配置实战{#nginx-lb-config}
-
- [4.1 安装Nginx(主备节点均执行)](#4.1 安装Nginx(主备节点均执行))
- [4.2 核心负载均衡配置](#4.2 核心负载均衡配置)
- [4.3 配置验证与生效](#4.3 配置验证与生效)
- [4.4 负载均衡效果验证](#4.4 负载均衡效果验证)
- 5. 高可用架构:Keepalived+Nginx实现故障自动切换{#ha-keepalived}
-
- [5.1 Keepalived核心原理](#5.1 Keepalived核心原理)
- [5.2 安装Keepalived(主备节点均执行)](#5.2 安装Keepalived(主备节点均执行))
- [5.3 配置主节点Keepalived](#5.3 配置主节点Keepalived)
- [5.4 配置备节点Keepalived](#5.4 配置备节点Keepalived)
- [5.5 编写Nginx健康检查脚本](#5.5 编写Nginx健康检查脚本)
- [5.6 高可用效果验证](#5.6 高可用效果验证)
- 6. 负载均衡性能优化配置{#lb-optimize}
-
- [6.1 Nginx核心优化配置](#6.1 Nginx核心优化配置)
- [6.2 系统内核参数优化](#6.2 系统内核参数优化)
- 7. 常见问题排查与解决方案{#lb-troubleshoot}
-
- [7.1 服务无法访问](#7.1 服务无法访问)
- [7.2 负载不均衡](#7.2 负载不均衡)
- [7.3 会话丢失(有状态服务)](#7.3 会话丢失(有状态服务))
- [7.4 高可用切换失败](#7.4 高可用切换失败)
- 8. 负载均衡工具选型对比{#lb-tool-select}
- 9. 总结{#summary}
-
1. 负载均衡核心基础{#lb-basic}
1.1 核心概念
负载均衡(Load Balancing)通过特定算法将客户端请求分发到后端多个服务器节点,实现资源共享、负载均匀,核心价值:
-
提升并发处理能力:多节点并行处理请求,突破单服务器性能上限;
-
消除单点故障:某节点故障时,请求自动切换到其他健康节点,不影响业务;
-
优化资源利用率:合理分配请求到不同配置的服务器,避免资源浪费。
1.2 主流负载均衡算法
不同场景适配不同算法,核心算法及适用场景如下:
| 算法类型 | 核心逻辑 | 适用场景 |
|---|---|---|
| 轮询(Round Robin) | 按顺序依次分发请求到后端节点,默认算法 | 后端节点配置一致、无状态服务(如静态资源分发) |
| 加权轮询(Weighted Round Robin) | 按节点权重分配请求,权重越高处理请求越多 | 后端节点配置不均(高配置节点设高权重) |
| IP哈希(IP Hash) | 根据客户端IP哈希值固定分发到同一节点 | 需保持会话一致性场景(如登录状态、购物车) |
| 最少连接数(Least Connections) | 请求分发到当前连接数最少的节点 | 后端节点处理请求时间差异较大(如长任务处理) |
| 响应时间优先(Fair) | 动态根据节点响应时间分配,响应快的优先 | 节点性能差异大且需动态调整的场景(需扩展模块) |
1.3 主流负载均衡工具
-
Nginx:七层负载均衡(HTTP/HTTPS协议),支持多种算法、反向代理、缓存,轻量高效,适合中小型应用;
-
LVS:四层负载均衡(TCP/UDP协议),基于内核态转发,性能极高,适合大规模集群;
-
HAProxy:支持四层/七层负载均衡,并发能力强,适合复杂业务场景;
-
Keepalived:基于VRRP协议,实现负载均衡器高可用,避免单点故障。
本文聚焦"Nginx+Keepalived"组合,兼顾易用性与生产环境可用性。
2. 实战环境准备与规划{#env-prepare}
2.1 环境规划(虚拟机/云服务器)
本次实战采用4台CentOS 7服务器,配置如下(最低2核4G,确保Docker运行流畅):
| 节点角色 | IP地址 | 需安装软件 | 核心作用 |
|---|---|---|---|
| Nginx主节点(Master) | 192.168.1.101 | Nginx+Keepalived | 负载均衡主节点,持有虚拟IP(VIP:192.168.1.100) |
| Nginx备节点(Backup) | 192.168.1.102 | Nginx+Keepalived | 负载均衡备节点,主节点故障时自动接管VIP |
| 后端服务节点1 | 192.168.1.103 | Docker | 运行Spring Boot测试服务(容器化) |
| 后端服务节点2 | 192.168.1.104 | Docker | 运行Spring Boot测试服务(容器化) |
2.2 前置环境配置(所有节点)
关闭防火墙与SELINUX,避免端口拦截:
bash
# 关闭防火墙并禁用自启
systemctl stop firewalld && systemctl disable firewalld
# 临时关闭SELINUX
setenforce 0
# 永久关闭SELINUX(重启生效)
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
# 验证SELINUX状态(输出Disabled即为成功)
getenforce
安装基础依赖:
bash
yum install -y wget gcc gcc-c++ make libtool
3. 后端服务集群搭建(Docker+Spring Boot){#backend-cluster}
采用Docker快速部署Spring Boot测试服务,模拟后端集群,方便后续验证负载均衡效果。
3.1 编写Spring Boot测试服务
创建简单Web接口,返回当前服务IP与端口(用于验证请求分发):
java
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
@RestController
@RequestMapping("/test")
public class TestController {
@GetMapping("")
public String testLoadBalancing() {
try {
// 获取当前服务IP
InetAddress localHost = Inet4Address.getLocalHost();
// 返回IP+端口,便于验证分发效果
return "当前服务节点:" + localHost.getHostAddress() + ":8080";
} catch (UnknownHostException e) {
return "服务响应异常";
}
}
}
3.2 构建Docker镜像
-
打包Spring Boot项目为JAR包(命名为test-lb.jar);
-
在后端节点(192.168.1.103/104)创建Dockerfile:
dockerfile
# 基础镜像
FROM openjdk:8-jdk-alpine
# 维护者信息
MAINTAINER lb-test
# 复制JAR包到容器
COPY test-lb.jar /app/test-lb.jar
# 暴露端口
EXPOSE 8080
# 启动命令
ENTRYPOINT ["java", "-Xms200m", "-Xmx200m", "-jar", "/app/test-lb.jar"]
- 构建Docker镜像:
bash
# 进入Dockerfile所在目录
cd /opt/lb-test
# 构建镜像(标签为test-lb:v1)
docker build -t test-lb:v1 .
3.3 启动后端服务容器
在两个后端节点分别启动容器(确保服务正常运行):
bash
# 启动容器,映射8080端口
docker run -d --name test-lb-node -p 8080:8080 test-lb:v1
# 验证服务是否启动成功(返回服务节点信息即为成功)
curl http://localhost:8080/test
4. Nginx负载均衡核心配置实战{#nginx-lb-config}
4.1 安装Nginx(主备节点均执行)
bash
# 安装Nginx官方源
wget -O /etc/yum.repos.d/nginx.repo http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
# 安装Nginx
yum install -y nginx
# 启动Nginx并设置自启
systemctl start nginx && systemctl enable nginx
# 验证Nginx是否启动(浏览器访问IP,显示Nginx默认页面即为成功)
4.2 核心负载均衡配置
编辑Nginx主配置文件(/etc/nginx/nginx.conf),配置upstream模块实现负载均衡:
nginx
# 全局配置
worker_processes auto; # 自动匹配CPU核心数
events {
worker_connections 10240; # 单进程最大并发连接数
use epoll; # 高性能事件模型(Linux)
multi_accept on; # 一次性接受所有新连接
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# 日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
# 负载均衡后端集群配置(核心)
upstream backend_cluster {
# 负载均衡算法:加权轮询(权重3:2,可根据节点性能调整)
server 192.168.1.103:8080 weight=3 max_fails=2 fail_timeout=30s;
server 192.168.1.104:8080 weight=2 max_fails=2 fail_timeout=30s;
# 可选:IP哈希算法(需保持会话时启用,注释上方加权轮询,启用下方)
# ip_hash;
# server 192.168.1.103:8080;
# server 192.168.1.104:8080;
# 可选:最少连接数算法(长任务场景启用)
# least_conn;
# server 192.168.1.103:8080;
# server 192.168.1.104:8080;
}
# 虚拟主机配置
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://backend_cluster; # 转发请求到后端集群
proxy_set_header Host $host; # 传递主机头信息
proxy_set_header X-Real-IP $remote_addr; # 传递客户端真实IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 传递代理链IP
}
}
}
4.3 配置验证与生效
bash
# 检查配置文件语法是否正确(输出ok and test is successful即为正确)
nginx -t
# 重新加载配置(不中断服务)
nginx -s reload
4.4 负载均衡效果验证
通过VIP(192.168.1.100)多次访问测试接口,观察返回的服务节点信息:
bash
# 多次执行curl命令,观察返回结果
curl http://192.168.1.100/test
预期结果:请求按3:2比例分发到192.168.1.103和192.168.1.104节点,证明负载均衡生效。
5. 高可用架构:Keepalived+Nginx实现故障自动切换{#ha-keepalived}
单Nginx节点存在单点故障风险,通过Keepalived实现主备切换,确保负载均衡服务高可用。
5.1 Keepalived核心原理
基于VRRP(虚拟路由冗余协议),主节点定期向备节点发送通告报文,备节点未收到通告则认为主节点故障,自动抢占VIP并接管服务,业务无感知。
5.2 安装Keepalived(主备节点均执行)
bash
# 安装Keepalived
yum install -y keepalived
# 启动Keepalived并设置自启
systemctl start keepalived && systemctl enable keepalived
5.3 配置主节点Keepalived
编辑配置文件(/etc/keepalived/keepalived.conf):
conf
! Configuration File for keepalived
global_defs {
router_id LVS_MASTER # 节点标识(主备需不同)
}
# 健康检查脚本:检测Nginx是否存活,若停止则触发切换
vrrp_script check_nginx {
script "/etc/keepalived/check_nginx.sh" # 脚本路径
interval 2 # 检查间隔(秒)
weight -20 # 脚本执行失败,节点优先级降低20
}
vrrp_instance VI_1 {
state MASTER # 节点角色:MASTER(主)
interface eth0 # 绑定VIP的网卡(用ip addr查看实际网卡名)
virtual_router_id 51 # 虚拟路由ID(主备必须相同,0-255)
priority 100 # 优先级(主节点>备节点,如备节点设为90)
advert_int 1 # VRRP通告间隔(秒)
# 认证配置(主备必须相同)
authentication {
auth_type PASS
auth_pass 1111 # 密码(1-8位)
}
# 虚拟IP配置(VIP)
virtual_ipaddress {
192.168.1.100/24 # 格式:VIP/子网掩码
}
# 关联健康检查脚本
track_script {
check_nginx
}
}
5.4 配置备节点Keepalived
编辑备节点配置文件(/etc/keepalived/keepalived.conf),仅修改3处:router_id、state、priority:
conf
! Configuration File for keepalived
global_defs {
router_id LVS_BACKUP # 节点标识:与主节点不同
}
vrrp_script check_nginx {
script "/etc/keepalived/check_nginx.sh"
interval 2
weight -20
}
vrrp_instance VI_1 {
state BACKUP # 节点角色:BACKUP(备)
interface eth0
virtual_router_id 51 # 与主节点相同
priority 90 # 优先级:低于主节点
advert_int 1
authentication {
auth_type PASS
auth_pass 1111 # 与主节点相同
}
virtual_ipaddress {
192.168.1.100/24 # 与主节点相同的VIP
}
track_script {
check_nginx
}
}
5.5 编写Nginx健康检查脚本
在主备节点均创建脚本(/etc/keepalived/check_nginx.sh),检测Nginx是否存活:
bash
#!/bin/bash
# 检查Nginx进程是否存在
nginx_pid=$(ps -ef | grep nginx | grep -v grep | wc -l)
if [ $nginx_pid -eq 0 ]; then
# Nginx未运行,尝试重启
systemctl start nginx
# 等待3秒后再次检查
sleep 3
nginx_pid=$(ps -ef | grep nginx | grep -v grep | wc -l)
if [ $nginx_pid -eq 0 ]; then
# 重启失败,停止Keepalived,触发备节点切换
systemctl stop keepalived
fi
fi
添加脚本执行权限:
bash
chmod +x /etc/keepalived/check_nginx.sh
5.6 高可用效果验证
-
正常状态验证:主节点执行
ip addr,可看到VIP(192.168.1.100)绑定在eth0网卡; -
故障切换测试:
bash
# 主节点停止Nginx服务
systemctl stop nginx
# 等待3-5秒,在备节点执行ip addr,观察VIP是否漂移到备节点
ip addr
# 访问VIP测试服务是否正常
curl http://192.168.1.100/test
预期结果:备节点成功绑定VIP,服务正常响应,故障切换生效。
- 故障恢复测试:主节点重启Nginx和Keepalived,VIP自动漂移回主节点(默认抢占模式)。
6. 负载均衡性能优化配置{#lb-optimize}
通过优化Nginx配置与系统内核参数,提升负载均衡并发能力。
6.1 Nginx核心优化配置
nginx
http {
# 1. 连接优化
keepalive_timeout 65; # 长连接超时时间
keepalive_requests 100; # 单个长连接最大请求数
tcp_nopush on; # 合并TCP数据包,提升传输效率
tcp_nodelay on; # 禁用Nagle算法,减少延迟
# 2. 缓存优化(静态资源场景)
open_file_cache max=10000 inactive=60s; # 缓存文件描述符
open_file_cache_valid 30s; # 验证缓存有效性时间
open_file_cache_min_uses 2; # 缓存最小使用次数
open_file_cache_errors on; # 缓存错误信息
# 3. 反向代理优化
proxy_connect_timeout 30s; # 连接后端超时时间
proxy_send_timeout 60s; # 发送请求超时时间
proxy_read_timeout 60s; # 读取响应超时时间
proxy_buffer_size 64k; # 代理缓冲区大小
proxy_buffers 4 64k; # 缓冲区数量与大小
proxy_busy_buffers_size 128k; # 繁忙缓冲区大小
}
# 4. worker进程优化(已在核心配置中设置)
worker_processes auto;
worker_cpu_affinity auto; # 自动绑定CPU核心,减少上下文切换
6.2 系统内核参数优化
编辑内核配置文件(/etc/sysctl.conf),添加以下参数:
conf
# 1. 提升文件描述符限制
fs.file-max = 1000000
# 2. 网络连接优化
net.core.somaxconn = 65535 # 全连接队列最大值
net.ipv4.tcp_max_syn_backlog = 65535 # 半连接队列最大值
net.ipv4.tcp_syncookies = 1 # 防止SYN Flood攻击
net.ipv4.tcp_tw_reuse = 1 # 快速回收TIME_WAIT连接
net.ipv4.tcp_tw_recycle = 0 # NAT环境下禁用(避免连接异常)
net.ipv4.tcp_fin_timeout = 30 # TIME_WAIT超时时间
# 3. 端口范围优化
net.ipv4.ip_local_port_range = 1024 65535 # 可用端口范围
应用内核参数(无需重启):
bash
sysctl -p
7. 常见问题排查与解决方案{#lb-troubleshoot}
7.1 服务无法访问
-
排查步骤:① 检查后端服务是否正常运行(
docker ps、curl 后端IP:8080/test);② 检查Nginx配置语法(nginx -t);③ 检查主备节点Keepalived状态(systemctl status keepalived);④ 检查VIP是否正常绑定(ip addr)。 -
解决方案:修复后端服务、修正Nginx配置、重启Keepalived服务。
7.2 负载不均衡
-
原因:① 算法选择不当;② 后端节点性能差异大未配置权重;③ 会话保持(IP哈希)导致请求集中。
-
解决方案:根据场景选择算法(性能不均用加权轮询)、调整节点权重、非会话场景禁用IP哈希。
7.3 会话丢失(有状态服务)
-
原因:默认轮询算法导致同一客户端请求分发到不同节点,会话未共享。
-
解决方案:① 启用IP哈希算法;② 采用分布式会话(Redis共享会话);③ 会话粘滞(Nginx配置
proxy_cookie_path / /;)。
7.4 高可用切换失败
-
原因:① 主备节点Keepalived配置不一致(virtual_router_id、auth_pass等);② 健康检查脚本错误;③ 防火墙未关闭。
-
解决方案:核对主备配置、测试脚本可用性(
/etc/keepalived/check_nginx.sh)、确保防火墙已禁用。
8. 负载均衡工具选型对比{#lb-tool-select}
不同场景适配不同工具,核心对比如下:
| 工具 | 层级 | 性能 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|---|
| Nginx | 七层(HTTP/HTTPS) | 中高 | 轻量、配置简单、支持缓存/反向代理、多种算法 | 不支持四层原生负载均衡(需扩展) | 中小型Web应用、静态资源分发 |
| LVS | 四层(TCP/UDP) | 极高 | 内核态转发、性能损耗低、支持大规模集群 | 配置复杂、不支持七层特性 | 大型分布式集群、高并发TCP服务 |
| HAProxy | 四层/七层 | 高 | 并发能力强、支持更多算法、健康检查功能完善 | 配置较复杂、学习成本高 | 复杂业务场景、高并发Web应用 |
9. 总结{#summary}
本文围绕"Nginx+Keepalived"实现负载均衡实战搭建,从基础概念到高可用架构,覆盖后端集群部署、核心配置、性能优化及问题排查全流程。核心要点总结:
-
负载均衡算法选择:根据节点配置、业务场景(会话需求、任务时长)选择合适算法;
-
高可用核心:Keepalived+健康检查脚本,确保负载均衡器无单点故障;
-
性能优化:结合Nginx配置与系统内核参数,提升并发处理能力;
-
问题排查:优先检查服务状态、配置语法、网络连通性,再定位算法或架构问题。
实际生产环境中,需根据业务规模(并发量、数据量)、技术栈选择合适的负载均衡方案,中小型应用优先选择Nginx(易用性高),大规模集群可考虑LVS+Nginx组合(性能与功能兼顾)。