Nginx 与 LVS 软件负载均衡对比及 Java 项目实践

发布时间:2026/8/31 7:25:18
Nginx 与 LVS 软件负载均衡对比及 Java 项目实践 Nginx 与 LVS 软件负载均衡对比及 Java 项目实践软件负载均衡常见方案Nginx7 层负载均衡与 LVSLinux 内核 4 层负载均衡。本文梳理两者区别、选型方法、与 Java 项目搭配使用方式以及 Nginx「插件」机制如何实现业务定制化。一、先搞懂4 层与 7 层是什么意思这里的「层」指的是OSI 七层网络模型。负载均衡器工作在哪一层决定了它能「看懂」多少报文内容也决定了它的能力和性能上限。OSI 层名称典型协议负载均衡器能看到什么4传输层Transport LayerTCP / UDP只能看到 IP 端口7应用层Application LayerHTTP / HTTPS / DNS / SMTP能看到完整的报文内容URL、Header、Cookie、Body1. 4 层负载均衡LVS 所在层工作在传输层只看 IP 端口不关心应用层协议内容。报文转发效率高因为它不需要解析 HTTP 报文体、不关心你是 GET 还是 POST。典型动作客户端访问VIP:80LVS 根据调度算法把 TCP 连接转给后端某台真实服务器Real Server后端服务器处理后再直接回包DR 模式下甚至不经 LVS 回包。2. 7 层负载均衡Nginx 所在层工作在应用层能看懂 HTTP 报文。因此可以基于 URL 路径、Host 域名、Header、Cookie 等做更细粒度的路由分流。典型动作/api/*转给后端 A 组 Java 服务/static/*转给静态资源服务器/admin/*做鉴权后再转给后端 B 组。一句话记忆4 层看门牌号IP端口7 层看信件内容HTTP 报文。二、Nginx 简介Nginx 是一款高性能的HTTP 反向代理 / Web 服务器同时也能做 4 层的 stream 代理1.9.0 之后支持stream模块。核心特点事件驱动 非阻塞 I/O单机可扛数万到十万级并发连接内存占用低。既是Web 服务器直接返回静态文件又是反向代理转发到后端应用还能做负载均衡。配置灵活支持 upstream 负载均衡算法、健康检查、限流、缓存、HTTPS、重写等。生态丰富可通过模块module扩展功能。典型负载均衡配置示例upstream java_backend { # 负载均衡算法轮询默认/ ip_hash / least_conn / weighted ip_hash; # 会话保持同一 IP 固定到同一后端 server 10.0.0.11:8080 weight3; # Java 节点 1权重 3 server 10.0.0.12:8080 weight2; # Java 节点 2权重 2 server 10.0.0.13:8080 backup; # 备用节点主力全挂才启用 keepalive 32; # 到后端的长连接池 } server { listen 80; server_name api.example.com; # 7 层路由按路径分流 location /api/ { proxy_pass http://java_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; } location /static/ { root /data/www; # 静态资源 Nginx 直接处理 expires 30d; } }支持的负载均衡算法算法说明轮询默认依次分给各后端weight加权轮询按权重分配机器性能不同时使用ip_hash按 client IP 哈希实现会话保持least_conn优先分给当前连接数最少的后端random/consistent_hash第三方随机 / 一致性哈希三、LVS 简介LVSLinux Virtual Server是章文嵩博士发起的开源项目集成在 Linux 内核中ipvs模块是纯粹的4 层负载均衡器。核心特点内核态运行不在用户态转发数据转发性能极高单机可达百万级 PPS / 十万级并发。只做 4 层转发不解析应用层内容无法基于 URL/Header 分流。调度器本身相对傻但稳定、可靠、吞吐大。常与keepalived配合实现高可用VIP 漂移 健康检查 LVS 规则管理。LVS 的三种工作模式面试高频模式工作原理回包路径优劣NATLVS 修改报文目标 IP 转给后端后端回包也经 LVS 改源 IP必须经过 LVS简单但 LVS 容易成瓶颈DRDirect Routing直连路由LVS 只改 MAC 地址IP 不变后端直接把回包回给客户端不经 LVS 回包性能最高要求 LVS 与后端在同一二层网络TUN隧道LVS 对原 IP 报文再封装一层 IP 隧道后端解封装后直连回客户端不经 LVS 回包可跨网段但要求后端支持 IP 隧道LVS 调度算法rr轮询、wrr加权轮询、lc最少连接、wlc加权最少连接、sh源地址哈希、lblc基于局部性的最少连接等。四、Nginx vs LVS 核心区别维度NginxLVS工作层级主要 7 层也支持 4 层 stream纯 4 层运行位置用户态进程Linux 内核态ipvs转发性能高万级~十万级并发极高百万级 PPS路由能力可按 URL/Host/Header/Cookie 精细分流只按 IP端口功能丰富度高代理、缓存、限流、TLS、重写、模块扩展低只做转发配置难度较易热加载nginx -s reload较复杂常配合 keepalived适用场景中小流量 需要应用层策略超大流量 入口转发本质定位应用层网关流量分发器一句话对比LVS 是高速公路收费站只管车往哪个口分流吞吐大但不懂车里装了什么Nginx 是分拣中心能拆箱看内容、按内容分流吞吐略低但功能丰富。五、项目里如何选择选择依据本质是看你的流量规模和是否需要应用层策略单选 Nginx 就够的场景流量中等单机万级并发以内。需要按 URL、域名、Header 分流例如前后端分离、灰度发布、多租户路由。需要 TLS 卸载、静态资源缓存、限流鉴权等应用层能力。大多数中小型 Java Web 项目的入口层。单选 LVS 就够的场景流量极大入口只需把 TCP 连接均匀分到后端无需应用层策略例如 MySQL 读写分离的读请求分发、纯 TCP 服务的入口。对性能和稳定性要求极致功能上够用就行。两者结合最常见的生产架构真正的高并发生产系统几乎都是LVS 在前、Nginx 在后的组合客户端 │ ▼ LVS4 层扛大流量做入口分发 VIP 高可用 │ ▼ Nginx 集群7 层做应用层路由、TLS 卸载、缓存、限流 │ ▼ Java 应用集群Spring Boot / TomcatLVS 负责扛量把海量连接均匀分发给多个 Nginx 节点并用 keepalived 保证入口 VIP 高可用。Nginx 负责干细活TLS 卸载、按路径分流、限流熔断、静态资源直出再代理到后端 Java 服务。Java 应用聚焦业务逻辑不再操心流量分发。决策口诀要应用层策略 → Nginx要扛海量流量 → LVS两者都要 → LVS Nginx 叠加。六、搭配 Java 项目如何使用典型部署拓扑外网用户 │ ▼ [LVS Keepalived] ← VIP 漂移保证入口高可用 │ ▼ [Nginx × N] ← TLS 卸载、7 层路由、限流、静态资源 │ ▼ [Java 应用 × N] ← Spring Boot 内嵌 Tomcat监听 8080 │ ▼ [数据库 / 缓存 / MQ]Java 端需要注意的点获取真实客户端 IPNginx 代理后Java 应用拿到的remoteAddr是 Nginx 的 IP。需要从X-Forwarded-For/X-Real-IP头取Nginx 端要正确设置见上文proxy_set_header。会话保持Session 粘性无状态服务推荐Java 应用设计成无状态Session 存 Redis任何节点都能处理请求。有状态兜底Nginx 用ip_hash或基于 Cookie 的粘性sticky模块把同一用户固定到同一节点。上游健康检查Nginx 开源版默认是被动检查请求失败才标记 down。需要主动健康检查可用nginx_upstream_check_module第三方模块或用商业版 Nginx Plus。Java 端建议暴露/actuator/healthSpring Boot Actuator供健康检查探活。长连接与连接池Nginx 到后端开启keepaliveJava 端 Tomcat 连接器相应调大maxConnections/ acceptCount避免连接排队。优雅停机Java 应用发版时先在 Nginx 把该节点设为down或从注册中心摘除等流量排空再停 JVM避免请求被打断。一个最小可用配置Nginxupstream java_app { least_conn; server 10.0.0.11:8080 max_fails3 fail_timeout30s; server 10.0.0.12:8080 max_fails3 fail_timeout30s; keepalive 32; } server { listen 443 ssl http2; server_name api.example.com; ssl_certificate /etc/nginx/ssl/server.crt; ssl_certificate_key /etc/nginx/ssl/server.key; location /api/ { proxy_pass http://java_app; proxy_http_version 1.1; proxy_set_header Connection ; 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 https; } }Spring Boot 关键配置application.ymlserver:tomcat:max-connections:10000# 配合 Nginx 长连接上调accept-count:200threads:max:400management:endpoint:health:probes:enabled:true# 暴露健康检查供 Nginx/LVS 探活endpoints:web:exposure:include:health,info七、关于「Nginx 插件」—— 它指的是什么如何实现定制化这句话里的插件泛指Nginx 的模块module扩展机制。Nginx 本身是模块化架构绝大部分功能即使是http、ssl、gzip这些基础能力都是通过模块实现的。当内置模块满足不了业务需求时就靠插件/模块来定制。模块的三种类型类型说明示例官方内置模块编译时--with-xxx开启http_ssl、http_v2、http_gzip_static、stream第三方开源模块社区贡献需编译进 Nginxnginx_upstream_check_module主动健康检查、headers-more-nginx-module改 Header、lua-nginx-moduleOpenResty 核心动态模块Nginx 1.9.11 支持无需重新编译主程序load_module加载官方及部分第三方模块提供.so用模块实现业务定制化的常见场景Lua 脚本嵌入业务逻辑最强大的方式通过ngx_http_lua_module或直接用OpenResty——内置 LuaJIT 大量库的 Nginx 发行版在 Nginx 内用 Lua 写业务代码请求到达 Java 前先在 Nginx 做鉴权、限流、参数校验、灰度路由。直接访问 Redis/MySQL把热点数据在网关层缓存Java 应用只处理核心业务。location /api/order { access_by_lua_block { local token ngx.req.get_headers()[X-Token] if not token or not check_token_in_redis(token) then ngx.exit(ngx.HTTP_UNAUTHORIZED) end -- 按 userId 灰度尾号 10 走新版本 local uid ngx.req.get_uri_args()[uid] if tonumber(uid) % 100 10 then ngx.var.upstream java_v2 else ngx.var.upstream java_v1 end } proxy_pass http://$upstream; }主动健康检查内置只做被动检查。引入nginx_upstream_check_module后可周期性主动探测后端 Java 节点的/actuator/health挂掉的节点自动摘除恢复后自动加回。改写请求/响应头headers-more-nginx-module可批量增删改 Header例如给所有响应统一加安全头、给请求注入租户标识。自定义访问控制 / 风控结合 Lua Redis 实现滑动窗口限流、IP 黑名单、接口防刷等在流量进入 Java 之前就拦掉。协议适配通过stream模块代理 MySQL/Redis 等非 HTTP 的 TCP 服务通过grpc模块代理 gRPC给 Java 微服务做流量入口。如何落地一个定制模块优先用 OpenResty它自带 Lua 能力和大量库是做 Nginx 业务定制的首选方案无需自己折腾编译。编译第三方模块用--add-modulepath静态编译或--add-dynamic-modulepath编成.so后load_module加载。动态加载1.9.11模块以.so形式放好在nginx.conf顶部load_module modules/ngx_http_xxx.so;即可升级 Nginx 不必重编。一句话总结所谓Nginx 插件就是 Nginx 的模块机制通过模块尤其是 OpenResty 的 Lua 模块可以在不侵入 Java 代码的前提下把鉴权、限流、灰度、缓存等横切逻辑下沉到网关层实现业务的定制化。八、总结问题结论4 层 vs 7 层4 层看 IP端口LVS7 层看 HTTP 报文Nginx选 Nginx 还是 LVS要应用层策略选 Nginx要扛海量流量选 LVS两者都要则 LVS 在前、Nginx 在后与 Java 搭配LVS 做高可用入口 → Nginx 做 7 层网关 → Java 集群做业务注意真实 IP 透传、健康检查、长连接、优雅停机Nginx 插件指 Nginx 模块机制配合 OpenResty/Lua 可在网关层实现鉴权、限流、灰度等定制化不侵入 Java 业务代码