nginx 监控后端服务是否可用

nginx_upstream_check_module 是专门提供负载均衡器内节点的健康检查的外部模块,由淘宝的姚伟斌大神开发,通过它可以用来检测后端 realserver 的健康状态。如果后端 realserver 不可用,则后面的请求就不会转发到该节点上,并持续检查几点的状态。在淘宝自己的 tengine 上是自带了该模块。nginx_upstream_check_module模块对服务器主动健康检查,定时检查某个接口,只要这个接口没有报500,就认为该服务器没有异常。

项目地址:https://github.com/yaoweibin/nginx_upstream_check_module 。 下面的是一个带后端监控检查的 nginx.conf 配置:

upstream backend {
  sticky;     # or simple round-robin
  server 172.29.88.226:8080 weight=2;
  server 172.29.88.226:8081 weight=1 max_fails=2 fail_timeout=30s ;
  server 172.29.88.227:8080 weight=1 max_fails=2 fail_timeout=30s ;
  server 172.29.88.227:8081;
  
  check interval=5000 rise=2 fall=3 timeout=1000 type=http;
  check_http_send "HEAD / HTTP/1.0\r\n\r\n";
  check_http_expect_alive http_2xx http_3xx;
}
server {
  location / {
    proxy_pass http://backend;
  }
  location /status {
    check_status;
    access_log   off;
    allow 172.29.73.23;
    deny all;
  }
}

上面配置的意思是,对name这个负载均衡条目中的所有节点,每个5秒检测一次,请求2次正常则标记 realserver状态为up,如果检测 3 次都失败,则标记 realserver的状态为down,超时时间为1秒。

允许IP访问最后一定要加deny all;表示除了上面allow的其他都禁止

配完之后重启,然后打开http://ip/status 我们可以看到节点的状态

在这里插入图片描述

check指令只能出现在upstream中:

  • interval : 向后端发送的健康检查包的间隔。
  • fall : 如果连续失败次数达到fall_count,服务器就被认为是down。
  • rise : 如果连续成功次数达到rise_count,服务器就被认为是up。
  • timeout : 后端健康请求的超时时间。
  • default_down : 设定初始时服务器的状态,如果是true,就说明默认是down的,如果是false,就是up的。默认值是true,也就是一开始服务器认为是不可用,要等健康检查包达到一定成功次数以后才会被认为是健康的。
  • type:健康检查包的类型,现在支持以下多种类型
  • tcp:简单的tcp连接,如果连接成功,就说明后端正常。
  • http:发送HTTP请求,通过后端的回复包的状态来判断后端是否存活。
  • ajp:向后端发送AJP协议的Cping包,通过接收Cpong包来判断后端是否存活。
  • ssl_hello:发送一个初始的SSL hello包并接受服务器的SSL hello包。
  • mysql: 向mysql服务器连接,通过接收服务器的greeting包来判断后端是否存活。
  • fastcgi:发送一个fastcgi请求,通过接受解析fastcgi响应来判断后端是否存活
  • port: 指定后端服务器的检查端口。你可以指定不同于真实服务的后端服务器的端口,比如后端提供的是443端口的应用,你可以去检查80端口的状态来判断后端健康状况。默认是0,表示跟后端server提供真实服务的端口一样。该选项出现于Tengine-1.4.0。
  • 如果 type 为 http ,你还可以使用check_http_send来配置http监控检查包发送的请求内容,为了减少传输数据量,推荐采用 HEAD 方法。当采用长连接进行健康检查时,需在该指令中添加keep-alive请求头,如: HEAD / HTTP/1.1\r\nConnection: keep-alive\r\n\r\n (或GET /health.html HTTP/1.0\r\n\r\n) 。当采用 GET 方法的情况下,请求uri的size不宜过大,确保可以在1个interval内传输完成,否则会被健康检查模块视为后端服务器或网络异常
  • check_http_expect_alive指定HTTP回复的成功状态,默认认为 2XX 和 3XX 的状态是健康的
check_http_send "GET /web/v2/alive/check HTTP/1.0\r\n\r\n";

实战场景:

Java项目上线迭代时,发版完成后再检查服务是否可用。实现逻辑在/static/alive404文件。发版完成后调用/web/v2/alive/change接口后将文件改名后alive/check就会返回200

package net.test.common.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
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;
import java.io.*;

@Slf4j
@Api(description = "alive文件操作API")
@RestController
@RequestMapping(value = "/alive", produces = {"application/json"})
public class DevOpsFileController {

  public static final String ALIVE = "alive";
  public static final String ALIVE404 = "alive404";

  /**
   * alive文件是否存在
   */
  @ApiOperation("alive文件是否存在")
  @GetMapping("/check")
  public ResponseEntity checkAlive() throws IOException {
    File filePath = new File(System.getProperty("user.dir") + "/static");
    if (!filePath.exists()) {
      return ResponseEntity.notFound().build();
    }
    File fileArr[] = filePath.listFiles();
    File aliveFile = fileArr[0];
    if (aliveFile.exists() && aliveFile.isFile() && ALIVE.equals(aliveFile.getName())) {
    } else {
      return ResponseEntity.notFound().build();
    }
    return ResponseEntity.ok().build();
  }

  /**
   * alive文件重命名
   */
  @ApiOperation("alive文件重命名")
  @GetMapping("/change")
  public ResponseEntity changeStatus() {
    File filePath = new File(System.getProperty("user.dir") + "/static");
    if (!filePath.exists()) {
      return ResponseEntity.notFound().build();
    }
    File fileArr[] = filePath.listFiles();
    File oldFile = fileArr[0];
    if (oldFile.exists() && oldFile.isFile()) {
      String newFileName;
      if (ALIVE404.equals(oldFile.getName())) {
        newFileName = ALIVE;
      } else {
        newFileName = ALIVE404;
      }
      File newFile = new File(System.getProperty("user.dir") + "/static" + "/" + newFileName);
      oldFile.renameTo(newFile);
      return ResponseEntity.ok().build();
    } else {
      return ResponseEntity.notFound().build();
    }
  }
}

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值