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

相关推荐
hsjcjh3 小时前
Nodemailer使用教程:在Node.js中发送电子邮件
linux·运维·node.js
没有梦想的咸鱼185-1037-16634 小时前
北斗高精度数据解算:破解城市峡谷/长基线/无网区难题,从毫米级定位到自动化交付——(GAMIT/GLOBK底层核心解算技术方法)
运维·arcgis·数据分析·自动化
不怕犯错,就怕不做4 小时前
linux 如何查看自己的帐号密码及samba的帐号和密码
linux·运维·服务器
实在智能RPA4 小时前
Agent 在物流行业能实现哪些自动化?——深度拆解 AI Agent 驱动的智慧物流新范式
运维·人工智能·ai·自动化
张3235 小时前
Linux 启动过程
linux·运维
李彦亮老师(本人)5 小时前
Rocky Linux 9.x 新特性详解
linux·运维·服务器·centos·rocky linux
芳草萋萋鹦鹉洲哦6 小时前
【windows】nginx如何注册为开机自启的服务(WinSW实现)
运维·windows·nginx
猩猩—点灯8 小时前
部署远程利器-RustDesk
运维·服务器·网络
biubiubiu07068 小时前
Linux 中 `source` 和 `systemctl daemon-reload` 的区别与踩坑点
linux·运维·服务器