nginx+tomcat环境下,nginx对后端Tomcat实例的健康检查机制

Nginx 对后端 Tomcat 的健康检查分为被动检查 (开源版默认)和主动检查(商业版或通过第三方模块实现)两种。


一、被动健康检查(开源 Nginx 原生支持)

原理 :Nginx 在转发请求时,如果发现某个后端节点出现问题,会将其标记为不可用,并在 fail_timeout 时间内不再转发请求给它。

配置示例

nginx 复制代码
upstream tomcat_cluster {
    server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;
    server 192.168.1.11:8080 max_fails=3 fail_timeout=30s;
    server 192.168.1.12:8080 max_fails=3 fail_timeout=30s;
}

server {
    listen 80;
    location / {
        proxy_pass http://tomcat_cluster;
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
    }
}

参数说明

参数 说明
max_fails=3 允许的最大失败次数
fail_timeout=30s 失败超时时间。30秒内如果失败3次,则标记为不可用,后续30秒内不再转发请求
proxy_next_upstream 定义什么情况下认为"失败",会尝试下一个节点

proxy_next_upstream 可配置的状态

状态 说明
error 连接后端时发生网络错误
timeout 连接或读取后端超时
invalid_header 后端返回无效的响应头
http_500 后端返回500错误
http_502 后端返回502错误
http_503 后端返回503错误
http_504 后端返回504错误
off 关闭重试机制

被动检查的局限性

  1. 必须有用户请求才会触发检查。如果节点已经坏了但没人访问,Nginx 不会主动发现
  2. 故障节点恢复后,不会自动回归 。需要等待 fail_timeout 时间后,再接收少量请求"试探",成功后才逐步恢复流量
  3. 不能提前摘除即将出问题的节点(如CPU飙高、Full GC频繁)

二、主动健康检查(Nginx Plus 或 nginx-upsync 模块)

原理:Nginx 主动向后端节点发送探测请求(如 HTTP GET /health),根据响应判断节点健康状态,自动摘除或恢复。

Nginx Plus 配置示例(商业版)

nginx 复制代码
upstream tomcat_cluster {
    zone upstream_zone 64k;
    server 192.168.1.10:8080;
    server 192.168.1.11:8080;
    
    health_check interval=5s fails=3 passes=2 uri=/health match=health_ok;
}

match health_ok {
    status 200;
    header Content-Type = application/json;
    body ~ "status.*UP";
}

参数说明

参数 说明
interval=5s 每5秒检查一次
fails=3 连续3次失败,标记为不可用
passes=2 连续2次成功,标记为可用
uri=/health 检查后端哪个接口
match 匹配规则(状态码、响应头、响应体)

开源替代方案:nginx-upsync + consul

社区常用的方案是使用 nginx-upsync 模块结合 consul 实现动态主动健康检查。


三、Tomcat 端需要提供的健康检查接口

无论用哪种方式,Tomcat 都需要提供一个健康的检查接口(例如 /health),返回当前节点的健康状态。

方案1:Spring Boot Actuator(标准做法)

yaml 复制代码
# application.yml
management:
  endpoints:
    web:
      exposure:
        include: health,ready
  endpoint:
    health:
      show-details: always
  health:
    db:
      enabled: true
    redis:
      enabled: true

访问 /actuator/health 返回:

json 复制代码
{
    "status": "UP",
    "components": {
        "db": {"status": "UP"},
        "diskSpace": {"status": "UP"},
        "redis": {"status": "UP"}
    }
}

方案2:自定义专用健康检查接口(更精细)

java 复制代码
@RestController
public class HealthController {
    
    @Autowired
    private DataSource dataSource;
    @Autowired
    private RedisTemplate redisTemplate;
    
    @GetMapping("/health")
    public ResponseEntity<Map<String, Object>> health() {
        Map<String, Object> status = new HashMap<>();
        
        // 检查数据库连接
        try {
            dataSource.getConnection().close();
            status.put("database", "UP");
        } catch (Exception e) {
            status.put("database", "DOWN: " + e.getMessage());
        }
        
        // 检查Redis连接
        try {
            redisTemplate.getConnectionFactory().getConnection().ping();
            status.put("redis", "UP");
        } catch (Exception e) {
            status.put("redis", "DOWN");
        }
        
        // 判断整体状态
        boolean isHealthy = status.values().stream().allMatch(v -> v.toString().startsWith("UP"));
        
        return ResponseEntity
            .status(isHealthy ? HttpStatus.OK : HttpStatus.SERVICE_UNAVAILABLE)
            .body(status);
    }
}

四、生产环境最佳实践:主被动结合

检查方式 作用 实现位置
被动检查 兜底,防止主动检查漏掉的故障 Nginx max_fails + proxy_next_upstream
主动检查 提前发现故障,快速摘除 Nginx Plus 或 nginx-upsync
应用层健康接口 提供真实的健康状态(不仅进程存活,还要检查依赖) Tomcat /health 接口
监控告警 节点频繁抖动时报警,人工介入 Zabbix/Prometheus

配置建议

nginx 复制代码
upstream tomcat_cluster {
    # 被动检查:兜底
    server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;
    server 192.168.1.11:8080 max_fails=3 fail_timeout=30s;
    
    # 主动检查:Nginx Plus 或 upsync 模块
    # health_check interval=5s fails=3 passes=2 uri=/health;
    
    keepalive 32;  # 保持连接池
}

location / {
    proxy_pass http://tomcat_cluster;
    proxy_next_upstream error timeout http_500 http_502 http_503;
    proxy_next_upstream_tries 2;  # 最多重试2次
    proxy_connect_timeout 3s;     # 连接超时3秒
    proxy_read_timeout 30s;       # 读取超时30秒
}

五、常见问题排查

现象 可能原因 解决
后端已宕机,Nginx 还在转发 被动检查未触发(无请求进来) 增加主动健康检查
健康检查总是失败 /health 接口没实现或返回非200 curl -v http://tomcat:8080/health 手动测试
节点一直在"抖动"(频繁被摘除和恢复) 健康检查超时时间太短,或后端压力大响应慢 调整 fail_timeoutinterval,优化后端
重启 Tomcat 后流量不恢复 fail_timeout 未过,或被动检查还没尝试 配置主动健康检查,或缩短 fail_timeout

六、一句话总结

Nginx 开源版默认只支持被动健康检查(靠转发失败来发现故障),生产环境建议配合主动健康检查(Nginx Plus 或 nginx-upsync 模块),同时让 Tomcat 提供 /health 接口,检查数据库、Redis 等依赖的真实状态,实现精准的节点摘除和恢复。

相关推荐
lucybean0116 分钟前
食品加工行业污水处理曝气装置采购避坑与合规筛选指南
运维
harmony&21 分钟前
DevOps进阶:SonarQube 代码审计与 Harbor 镜像仓库实战
运维·devops
Neighbor_OldY36 分钟前
CSRF跨站请求伪造攻击检测与应急处置实战:伪造请求识别与防护落地
运维·安全·web安全
生活爱好者!43 分钟前
NAS能批量做短视频?docker部署MoneyPrinterTurbo
运维·docker·容器
考虑考虑1 小时前
Redis8.8新特性
运维·redis·后端
云飞云共享云桌面1 小时前
钣金制造研发优化:不采购传统工作站,实现 SolidWorks 团队共用服务器开展三维建模
运维·服务器·网络·数据库·3d·制造
YUJIANYUE1 小时前
AspFox-类NetBox的ASP+Access迷你单文件服务器V202609
运维·服务器
harmony&1 小时前
DevOps 实战:从概念到 CI/CD 持续交付全流程
运维·ci/cd·devops
皮卡丘不断更1 小时前
视频自动剪、内容自动发:我的多平台营销自动化工作台
大数据·运维·自动化·视频剪辑·营销自动化·多平台运营·creatorhub
fengyehongWorld1 小时前
linux Capability中的CAP_NET_BIND_SERVICE
linux·运维·服务器