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 等依赖的真实状态,实现精准的节点摘除和恢复。

相关推荐
睡不醒男孩03082317 小时前
PostgreSQL 数据库运维转型:从传统模式到 CLup 平台的 25 个核心 FAQ
运维·数据库·postgresql
无限进步_17 小时前
【Linux】系统级文件I/O与文件描述符深度剖析
linux·运维·服务器
虾壳云官方17 小时前
openclaw 一键安装教程(2026年6月15最新)
运维·人工智能·windows·自动化·openclaw
biter down17 小时前
2:Ubuntu 22.04 LTS 的完整下载教程
linux·运维·ubuntu
傻啦嘿哟18 小时前
自动化养号:利用代理池模拟人工操作,进行社交媒体账号维护
运维·自动化·媒体
by————组态18 小时前
Ricon组态技术架构 - 企业级Web组态解决方案
运维·服务器·前端·物联网·架构·组态·组态软件
GlobalSign数字证书18 小时前
Nginx配置SSL证书教程:从零到HTTPS的完整部署指南
nginx·https·ssl
m0_5261194018 小时前
ssh key生成,gitee配置ssh
运维·gitee·ssh
赋缘汇(fableshare)-黄从庆18 小时前
Ubuntu重启后进入initramfs导致无法开机
linux·运维·ubuntu
CHINA红旗下18 小时前
固定虚拟机的IP地址
运维·服务器·网络