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: 是后端专门为健康检查设置的端口

相关推荐
Lary_Rock2 小时前
RK3576 LINUX RKNN SDK 测试
linux·运维·服务器
一坨阿亮5 小时前
Linux 使用中的问题
linux·运维
wclass-zhengge7 小时前
Docker篇(Docker Compose)
运维·docker·容器
李启柱7 小时前
项目开发流程规范文档
运维·软件构建·个人开发·设计规范
力姆泰克9 小时前
看电动缸是如何提高农机的自动化水平
大数据·运维·服务器·数据库·人工智能·自动化·1024程序员节
BPM_宏天低代码9 小时前
低代码 BPA:简化业务流程自动化的新趋势
运维·低代码·自动化
sun0077009 小时前
拷贝 cp -rdp 和 cp -a
linux·运维·服务器
wowocpp9 小时前
ubuntu 22.04 server 安装 anaconda3
linux·运维·ubuntu
tingting011910 小时前
Linux 普通用户禁用sudo su - 命令
linux·运维·服务器
IT-民工2111010 小时前
CI/CD 实践总结
运维·ci/cd·自动化