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

相关推荐
Asuicao33 分钟前
centos7.9版本升级ssh OpenSSH 9.8p1 源码 OpenSSL 1.1.1w 源码包以及安装升级回滚文档
运维·ssh
志栋智能1 小时前
超自动化安全中的威胁狩猎
运维·安全·自动化
↘"LYong2 小时前
旧版 CentOS 安装 Docker 完整指南(附国内镜像加速)
linux·运维·docker
Elastic 中国社区官方博客2 小时前
Elastic 在 Everest Group 企业搜索产品 PEAK Matrix® 评估 2026 中被评为领导者
大数据·运维·人工智能·elasticsearch·搜索引擎·ai·全文检索
程序员在囧途2 小时前
likeadmin-api API 中转站怎么做统一报价?从 /pricing、/user/balance 到 task_id 回执的落地方法
运维·服务器·数据库·likeadmin-api·api中转站·token计费
想你依然心痛3 小时前
Linux用户空间与内核空间通信:netlink、ioctl、mmap 零拷贝与性能对比
linux·运维·服务器
沉静的小伙4 小时前
在微服务中使用领域事件
java·运维·微服务
wenzhangli74 小时前
oodAgent 4.0 Skills分布式调度 — 从Code Agent实战看自主维护的Agent网络
运维·网络·人工智能·自动化
做个文艺程序员4 小时前
Linux第12篇:性能监控与瓶颈分析——CPU/内存/IO/网络全维度
linux·运维·网络
K姐研究社5 小时前
OiiOii 2.0 实测 – 智能画布实现 AI 视频创作自动化
运维·人工智能·自动化