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

相关推荐
Dawn-bit43 分钟前
Linux磁盘管理详解
linux·运维·服务器·计算机网络·云计算
RisunJan1 小时前
Linux命令-sftp(SSH 文件传输协议客户端)
linux·运维
极客先躯3 小时前
高级java每日一道面试题-2026年05月03日-实战篇[Docker]-如何实现容器化环境的数据加密?
java·运维·docker·容器·金融·加解密·高级面试
泡沫冰@4 小时前
上章节中文件的讲解
前端·网络·nginx
三言老师5 小时前
CentOS7.9:Redis‑Cluster集群部署结构化实战教程
linux·运维·服务器·数据库
attitude.x5 小时前
Cursor+GitOps:自动化运维新姿势
运维·自动化
数智化管理手记6 小时前
主数据重复、错漏频发?一站式主数据管理平台如何落地?
大数据·运维·数据库·人工智能·数据挖掘
Shell运维手记7 小时前
ARP 协议超详细讲解(适合网工考试 / 运维理解)
运维·网络·网络协议·智能路由器
西安景驰电子7 小时前
PCIe 授时卡原理及应用
运维·服务器·windows·单片机·嵌入式硬件·fpga开发
huainingning9 小时前
华三瘦AP切换为胖AP并配置无线功能
运维·网络·网络协议·tcp/ip