Nginx健康检查

Nginx健康检查nginx_upstream_check_module

nginx健康检查介绍:

​ 主动健康检查,nignx定时主动地去ping后端的服务列表,当发现某服务出现异常时,把该服务从健康列表中移除,当发现某服务恢复时,又能够将该服务加回健康列表中。nginx自带的upstream轮询可以实现业务接口切换, nginx有一个开源的实现nginx_upstream_check_module模块能更加平滑的进行业务切换

nginx自带健康检查的缺陷:

  1. Nginx只有当有访问时后,才发起对后端节点探测。
  2. 如果本次请求中,节点正好出现故障,Nginx依然将请求转交给故障的节点,然后再转交给健康的节点处理。所以不会影响到这次请求的正常进行。但是会影响效率,因为多了一次转发
  3. 自带模块无法做到预警
  4. 被动健康检查, 应用服务器没挂,但是数据库连接池不够导致应用假死, Nginx任然认为它是一个正常节点, 继续把请求打在这台服务器上

使用第三访模块nginx_upstream_check_module:

  1. 区别于nginx自带的非主动式的心跳检测,淘宝开发的tengine自带了一个提供主动式后端服务器心跳检测模块
  2. 若健康检查包类型为http,在开启健康检查功能后,nginx会根据设置的间隔向指定的后端服务器端口发送健康检查包,并根据期望的HTTP回复状态码来判断服务是否健康。
  3. 后端真实节点不可用,则请求不会转发到故障节点
  4. 故障节点恢复后,请求正常转发

介绍nginx_upstream_check_module模块针对nginx1.20+

一、模块下载解压

nginx下载地址:https://nginx.org/en/download.html

nginx_upstream_check_module模块下载:

github地址: https://github.com/yaoweibin/nginx_upstream_check_module

taobao官网:http://tengine.taobao.org/document_cn/http_upstream_check_cn.html

下载

https://codeload.github.com/yaoweibin/nginx_upstream_check_module/zip/master

上传到服务器并解压

bash 复制代码
tar -zxvf nginx-1.22.1.tar.gz
unzip nginx_upstream_check_module-master.zip

二、官方步骤

安装

配置

三、自己安装步骤跟着官网来

安装patch

nginx 复制代码
yum install -y patch

#(重点: 已安装nginx一定是停止运行状态的)
# 注意check_1.20.1+.patch 版本要跟你的nginx版本对应上
#(一定要执行这行命令, 要不然健康检查会报错: http upstream check module can not find any check server, make sure you've added the check servers, client: xxx.xxx.xxx.xxx, server: localhost, request: "GET /status HTTP/1.1", host: "xxx.xxx.xxx.xxx:8087")

# 执行patch命令一定要在(nginx源码目录)
patch -p1 < /home/app/nginx_upstream_check_module-master/check_1.20.1+.patch

安装nginx和模块nginx_upstream_check_module-master

nginx 复制代码
# 进入nginx安装包目录, 执行下面命令, 根据自己的实际情况安装对应参数值改成自己的 (重点: nginx一定是停止运行状态的)
./configure --user=app --group=app --with-http_ssl_module --with-threads --with-file-aio --with-http_stub_status_module --add-module=/opt/app/nginx_upstream_check_module-master/ --prefix=/opt/app/nginx

make && make install

--prefix: nginx主目录
--user: nginx启动用户
--group: nginx启动组
--add-module: 添加模块
--with-http_ssl_model: 启动ssl模块

配置nginx

Nginx会每隔3000毫秒(3秒)向每个服务器发送一个GET请求/dist-app-ytgz-approve/health_check接口ip是对应的server后面的ip端口。如果服务器连续两次(rise=2)返回2xx或3xx状态码,那么Nginx就认为这个服务器是健康的。如果服务器连续五次(fall=5)没有响应或者返回非2xx或3xx的状态码,那么Nginx就认为这个服务器是不健康的,会自动将其剔除。

为什么请求接口带/dist-app-ytgz-approve那是因为我后台application.yaml里面配置的server.servlet.context-path: /dist-app-ytgz-approve

nginx 复制代码
http {
    upstream approve {
      server xxx.xxx.xxx.xxx:9010;
      server xxx.xxx.xxx.xxx:9090;
      ip_hash;
        
        
      check interval=3000 rise=2 fall=5 timeout=5000 type=http;   
      check_http_send "GET /dist-app-ytgz-approve/health_check HTTP/1.0\r\n\r\n";    
      check_http_expect_alive http_2xx http_3xx;
      # Nginx会每隔3000毫秒(3秒)向每个服务器发送一个GET请求/dist-app-ytgz-approve/health_check接口ip是对应的server后面的ip端口。如果服务器连续两次(rise=2)返回2xx或3xx状态码,那么Nginx就认为这个服务器是健康的。如果服务器连续五次(fall=5)没有响应或者返回非2xx或3xx的状态码,那么Nginx就认为这个服务器是不健康的,会自动将其剔除。
	}

	server {
        listen       8087;
        server_name  localhost;

        location /dist-app-ytgz-approve {

          proxy_pass http://approve;
          proxy_set_header        Host $http_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-Port $server_port;
          proxy_set_header        X-Forwarded-Proto $scheme;

          add_header X-Route-Ip $upstream_addr;
          add_header X-Route-Status $upstream_status;
        }

        location /status {
          check_status;

          access_log off;
        }

    }
}

后台健康检查接口

java 复制代码
package com.dist.ytgz.approve.controller;

import com.dist.common.util.LogUtil;
import com.dist.ytgz.approve.service.HealthCheckService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * TODO
 *
 * @author <a href="mailto:zhangxiao@dist.com.cn">Zhang Xiao</a>
 * @since
 */
@RequestMapping
@RestController
public class HealthCheckController {

    @Autowired
    private HealthCheckService healthCheckService;

    @GetMapping("/health_check")
    public ResponseEntity<String> healthCheck() {
        // 这里可以添加检查数据库连接数的逻辑
        // 如果数据库连接数正常,返回200状态码
        // 如果数据库连接数耗尽,返回503状态码
        Long startTime = System.currentTimeMillis();
        boolean isDatabaseHealthy = healthCheckService.checkDatabaseHealth();

        if (isDatabaseHealthy) {
            Long endTime = System.currentTimeMillis();
            LogUtil.error("健康检查总共耗时: " + (endTime-startTime) / 1000.0);
            return ResponseEntity.ok("Healthy");
        } else {
            Long endTime = System.currentTimeMillis();
            LogUtil.error("不健康检查总共耗时: " + (endTime-startTime) / 1000.0);
            return ResponseEntity.status(503).body("Unhealthy");
        }
    }

}





package com.dist.ytgz.approve.service.impl;

import com.dist.ytgz.approve.service.HealthCheckService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.persistence.EntityManager;
import javax.persistence.Query;

/**
 * TODO
 *
 * @author <a href="mailto:zhangxiao@dist.com.cn">Zhang Xiao</a>
 * @since
 */
@Service
public class HealthCheckServiceImpl implements HealthCheckService {

    @Autowired
    private EntityManager em;

    @Override
    public boolean checkDatabaseHealth() {
        try {
            // 这里的SQL语句应该替换为适合您的数据库的语句
            Query query = em.createNativeQuery("SELECT count(1) from dual");
            query.getSingleResult();
            return true;
        } catch (Exception e) {
            // 如果查询失败,那么可能是数据库连接数耗尽,或者数据库服务器出现了其他问题
            return false;
        }
    }
}

四、启动nginx

nginx健康检查的日志信息

nginx服务器状态


server number: 是后端服务器的数量
generation: 是Nginx reload的次数
Index: 是服务器的索引
Upstream: 是在配置中upstream的名称
Name: 是服务器IP:PORT
Status: 是服务器的状态
Rise counts: 是服务器连续检查成功的次数
Fall counts: 是连续检查失败的次数
Check type: 是检查的方式
Check port: 是后端专门为健康检查设置的端口

相关推荐
用户03284722207018 小时前
如何搭建本地yum源(上)
运维
ping某2 天前
为什么 Nginx 明明监听了 80,转发后端时却用了 4xxxx 端口?
后端·nginx
大树884 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠4 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质4 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
Inhand陈工4 天前
基于台达PLC与映翰通IG502的智慧水产养殖精准投喂与远程运维解决方案
运维·人工智能·物联网·阿里云·信息与通信
酣大智4 天前
ARP代理--工作原理
运维·网络·arp·arp代理
shushangyun_4 天前
2026年快消品B2B系统推荐:支持终端门店订货、促销政策自动化的工具?
java·运维·网络·数据库·人工智能·spring·自动化
施努卡机器视觉4 天前
SNK施努卡侧滑门锁上滑轮总成自动化装配线,从零件到组件,全流程精密制造方案
运维·自动化·制造
AC赳赳老秦4 天前
用 OpenClaw 搭建服务器故障应急响应系统,自动处理 80% 常见运维故障
android·运维·服务器·python·rxjava·deepseek·openclaw