Nginx主动健康检查实现业务平滑转移

文章目录

      • 一、概述
      • 二、被动式检查
      • 三、主动式检查
        • 1.下载Nginx
        • 2.下载插件
        • 3.打补丁
        • 4.编译Nginx
        • 5.创建软链接
        • 6.编辑配置文件
        • 7.测试
          • 1.模拟Java服务端
          • 2.nginx日志

一、概述

Nginx自带健康检查(被动式): Nginx只有当有访问时后,才发起对后端节点探测。

被动式的缺点是:如果后端有不健康节点,负载均衡器需要通过先将请求发给该不健康节点时,才能发现该节点是否健康,如果不健康会将请求转发给其它后端服务,这样就会导致浪费一次转发。

淘宝团队开发的Nginx开源健康检查插件(主动式): 第三访模块nginx_upstream_check_module。

在开启健康检查功能后,nginx会根据设置的间隔向指定的后端服务器端口发送健康检查包,并根据期望的HTTP回复状态码来判断服务是否健康。

二、被动式检查

upstream clusterA {
        server 192.168.0.1:8080 max_fails=2 fail_timeout=30s;
        server 192.168.0.2:8081 max_fails=2 fail_timeout=30s;
    }

关键配置项如下:

  • max_fails:默认值为1。设定Nginx与后端服务器通信的尝试失败的次数。在fail_timeout参数定义的时间段内,如果失败的次数达到此值,Nginx就认为服务器不可用。在下一个fail_timeout时间段,服务器不会再被尝试。 设为0就会停止统计尝试次数,即不对后端节点进行健康检查。认为服务器是一直可用的。

  • fail_timeout:默认值为10秒。设定服务器被认为不可用的时间段以及统计失败尝试次数的时间段。在这段时间中,服务器失败次数达到指定的尝试次数max_fails,服务器就被认为不可用。

三、主动式检查

1.下载Nginx

从官方查看最新版本:http://nginx.org/

mkdir -p /opt/software
cd /opt/software
wget http://nginx.org/download/nginx-1.23.0.tar.gz
tar -xvf nginx-1.23.0.tar.gz
2.下载插件

插件下载:https://github.com/yaoweibin/nginx_upstream_check_module

插件说明:http://tengine.taobao.org/document_cn/http_upstream_check_cn.html

cd /opt/software
wget https://github.com/yaoweibin/nginx_upstream_check_module/archive/master.zip
3.打补丁
yum install unzip -y
unzip master.zip
yum install patch -y
cd /opt/software/nginx-1.23.0
patch -p1 < /opt/software/nginx_upstream_check_module-master/check_1.20.1+.patch 
4.编译Nginx
cd /opt/software/nginx-1.23.0
# 安装依赖
yum -y install gcc pcre-devel zlib-devel openssl openssl-devel
# 配置,指定编译之后安装目录(--prefix=没有指定安装目录,则默认安装到/usr/local)
./configure --prefix=/usr/local/nginx --add-module=/opt/software/nginx_upstream_check_module-master --with-http_ssl_module
# 编译
make && make install
5.创建软链接
ln -s /usr/local/nginx/sbin/nginx /usr/bin/nginx
[root@localhost nginx]# nginx -v
nginx version: nginx/1.23.0
6.编辑配置文件
cd /usr/local/nginx
vim /usr/local/nginx/conf/nginx.conf

配置文件内容:

worker_processes  1;
events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  60;
 
    upstream up_cluster {
        # 将max_fails设置为0,不对后端服务器进行健康检查,同时使fail_timeout参数失效
        server 172.26.20.151:8080 max_fails=0 fail_timeout=120s;
        server 172.26.20.151:8081 max_fails=0 fail_timeout=120s;
        # 10s发送一次,连续成功2次则认为up,连续失败3次则认为down,5s超时
        check interval=10000 rise=2 fall=3 timeout=5000 type=http default_down=true;
        # 向/healthy接口发送GET请求
        check_http_send "GET /healthy HTTP/1.0\r\n\r\n";
        # 默认认为2XX和3XX的状态是健康的
        check_http_expect_alive http_2xx http_3xx;
    }
 
    server {
    		listen       80;
        server_name  localhost;

        location / {
            proxy_pass http://up_cluster;
            proxy_set_header X-Forwarded-Host $host;
            proxy_set_header X-Forwarded-Server $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $host:$server_port;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }   
    }
}

参数意义:

  • interval:向后端发送的健康检查包的间隔。
  • fall(fall_count): 如果连续失败次数达到fall_count,服务器就被认为是down。
  • rise(rise_count): 如果连续成功次数达到rise_count,服务器就被认为是up。
  • timeout: 后端健康请求的超时时间。
  • default_down: 设定初始时服务器的状态,如果是true,就说明默认是down的,如果是false,就是up的。默认值是true,也就是一开始服务器认为是不可用,要等健康检查包达到一定成功次数以后才会被认为是健康的。
  • type:健康检查包的类型,现在支持以下多种类型
    • tcp:简单的tcp连接,如果连接成功,就说明后端正常。
    • ssl_hello:发送一个初始的SSL hello包并接受服务器的SSL hello包。
    • http:发送HTTP请求,通过后端的回复包的状态来判断后端是否存活。
    • mysql: 向mysql服务器连接,通过接收服务器的greeting包来判断后端是否存活。
    • ajp:向后端发送AJP协议的Cping包,通过接收Cpong包来判断后端是否存活。
  • port: 指定后端服务器的检查端口。你可以指定不同于真实服务的后端服务器的端口,比如后端提供的是443端口的应用,你可以去检查80端口的状态来判断后端健康状况。默认是0,表示跟后端server提供真实服务的端口一样。该选项出现于Tengine-1.4.0。
7.测试
1.模拟Java服务端
# 8080服务:
@GetMapping("/healthy")
public String healthy() {
    return "{\"code\": 200, \"msg\": \"success!\"}";
}
curl http://172.26.20.151:8080/healthy
状态代码: 200

# 8081服务:
@GetMapping("/healthy")
@ResponseStatus(code = HttpStatus.BAD_REQUEST, reason = "服务异常!")
public String healthy() {
    return "{\"code\": 400, \"msg\": \"bad request!\"}";
}
curl http://172.26.20.151:8080/healthy
状态代码: 400 
2.nginx日志
tail -500f /usr/local/nginx/logs/error.log
# 服务8081返回400时
2022/07/21 17:29:31 [error] 9241#0: check protocol http error with peer: 172.26.20.151:8081

# 服务down掉
2022/07/21 11:00:36 [error] 9377#0: send() failed (111: Connection refused)

你可能感兴趣的:(Nginx,nginx,服务器,运维)