一:nginx后端健康检查

nginx自带健康检查的缺陷:

  1. Nginx只有当有访问时后,才发起对后端节点探测。
  2. 如果本次请求中,节点正好出现故障,Nginx依然将请求转交给故障的节点,然后再转交给健康的节点处理。所以不会影响到这次请求的正常进行。但是会影响效率,因为多了一次转发
  3. 自带模块无法做到预警
  4. 被动健康检查

使用第三访模块nginx_upstream_check_module

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

二:nginx被动检查

Nginx自带有健康检查模块:ngx_http_upstream_module,可以做到基本的健康检查,配置如下:

upstream cluster{
    server 172.16.0.23:80  max_fails=1 fail_timeout=10s;
    server 172.16.0.24:80  max_fails=1 fail_timeout=10s;
   # max_fails=1和fail_timeout=10s 表示在单位周期为10s钟内,中达到1次连接失败,那么接将把节点标记为不可用,并等待下一个周期(同样时常为fail_timeout)再一次去请求,判断是否连接是否成功。
   # fail_timeout为10s,max_fails为1次。
}
server {
    listen 80;
    server_name xxxxxxx.com; 
    location / {
      proxy_pass         http://cluster;
    }
}

缺点
Nginx只有当有访问时后,才发起对后端节点探测。如果本次请求中,节点正好出现故障,Nginx依然将请求转交给故障的节点,然后再转交给健康的节点处理。所以不会影响到这次请求的正常进行。但是会影响效率,因为多了一次转发,而且自带模块无法做到预警。

三:nginx主动检查

主动地健康检查,nignx定时主动地去ping后端的服务列表,当发现某服务出现异常时,把该服务从健康列表中移除,当发现某服务恢复时,又能够将该服务加回健康列表中。淘宝有一个开源的实现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

3.1 安装nginx_upstream_check_module

# 下载
wget https://codeload.github.com/yaoweibin/nginx_upstream_check_module/zip/master
unzip master

如果是全新编译安装nginx,直接在nginx编译参数后面加上该模块正常安装即可
本次测试是服务器上已经存在编译安装的nginx,版本为:nginx/1.12.0
上传nginx-1.12.0.tar.gz源码包,解压包。

ubuntu@singapore:~/tools$ ll
drwxr-xr-x 9 ubuntu ubuntu   4096 Aug  8 01:22 nginx-1.12.0/
-rw-r--r-- 1 ubuntu ubuntu 980831 Mar 25 01:37 nginx-1.12.0.tar.gz
drwxrwxr-x 6 ubuntu ubuntu   4096 Aug  6 17:39 nginx_upstream_check_module-master/

进入nginx源码目录,进行打该模块的补丁(这一步千万不能遗漏)

cd nginx-1.12.0/
patch -p1 < ../nginx_upstream_check_module-master/check_1.12.1+.patch
patching file src/http/modules/ngx_http_upstream_hash_module.c
patching file src/http/modules/ngx_http_upstream_ip_hash_module.c
patching file src/http/modules/ngx_http_upstream_least_conn_module.c
patching file src/http/ngx_http_upstream_round_robin.c
patching file src/http/ngx_http_upstream_round_robin.h

注意:check版本和Nginx版本要求有限制 1.12以上版本的nginx,补丁为check_1.12.1+.patch 具体参考github

https://github.com/yaoweibin/nginx_upstream_check_module

查看已安装nginx的编译参数:

ubuntu@singapore:~/tools/nginx-1.12.0$ /application/nginx/sbin/nginx -V
....................
configure arguments: --prefix=/application/nginx-1.12.0 --user=www-web --group=www-web --with-http_ssl_module --with-http_v2_module --with-threads --with-file-aio --with-http_stub_status_module

在已安装的编译参数后加上该模块参数:

./configure --prefix=/application/nginx-1.12.0 --user=www-web --group=www-web --with-http_ssl_module --with-http_v2_module --with-threads --with-file-aio --with-http_stub_status_module --add-module=../nginx_upstream_check_module-master/

编译完成后执行make,但不要执行make install
将打过补丁的nginx二进制文件覆盖/application/nginx/sbin/目录中的文件即可

sudo cp /application/nginx/sbin/nginx /application/nginx/sbin/nginx.bak
sudo /bin/cp objs/nginx /application/nginx/sbin/

3.2 模块配置

upstream cluster {
        # simple round-robin(默认是简单的轮徇,加weight就是加权轮徇)
        server 172.17.2.235:80;
        server 172.17.2.235:81;
        server 172.17.2.235:82;
        check interval=3000 rise=2 fall=5 timeout=1000 type=http;
        # 每隔三秒检查后端真实节点状态,成功2次为up状态,失败5次为down状态,超时时间为1秒,检查类型为http
       check_http_send "HEAD / HTTP/1.0\r\n\r\n";
       check_http_expect_alive http_2xx http_3xx;
       # 返回2xx,3xx状态码为正常状态,其它状态码为down状态
}
server {
    listen       80;
    server_name  _;
        location / {
                proxy_pass http://cluster;
        }
        # 查看后端服务器实时的健康状态
        location /status {
                check_status;
                access_log off;
        }
}

interval: 向后端发送的健康检查包的间隔,单位为毫秒
rsie: 如果连续成功次数达到rise_count,服务器就被认为是up
fall: 如果连续失败次数达到fall_count,服务器就被认为是down
timeout: 后端健康请求的超时时间,单位为毫秒
type: 健康检查包的类型,支持tcp、ssl_hello、http、mysql、ajp

Syntax: check interval=milliseconds [fall=count] [rise=count] [timeout=milliseconds] [default_down=true|false] [type=tcp|http|ssl_hello|mysql|ajp] [port=check_port]
Default: 如果没有配置参数,默认值是:interval=30000 fall=5 rise=2 timeout=1000 default_down=true type=tcp
Context: upstream
# port: 指定后端服务器的检查端口。你可以指定不同于真实服务的后端服务器的端口,比如后端提供的是443端口的应用,你可以去检查80端口的状态来判断后端健康状况。默认是0,表示跟后端server提供真实服务的端口一样。该选项出现于Tengine-1.4.0。

健康检查页面访问:http://IP地址/status,如下图:
nginx安装第三访模块nginx_upstream_check_module

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

四:docker中安装

使用Dockerfile编译安装,文件内容如下:

FROM ubuntu:16.04
LABEL maintainer="ginvip@qq.com"
ENV DEBIAN_FRONTEND noninteractive
#ADD sources.list /etc/apt/sources.list
RUN apt-get update -y && apt-get install -y build-essential libtool libpcre3 libpcre3-dev zlib1g-dev openssl libssl-dev && apt-get autoclean -y
ADD nginx-1.16.1.tar.gz /usr/local/src
ADD nginx_upstream_check_module-master.tar.gz /usr/local/src
WORKDIR /usr/local/src/nginx-1.16.1
RUN mkdir /application
RUN useradd -M -s /usr/sbin/nologin nginx
RUN patch -p1 < ../nginx_upstream_check_module-master/check_1.14.0+.patch
RUN ./configure --prefix=/application/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-threads --with-file-aio --with-http_stub_status_module --add-module=../nginx_upstream_check_module-master/ && make && make install
ENV PATH /application/nginx/sbin:$PATH
RUN mkdir /application/nginx/conf/extra
ADD nginx.conf /application/nginx/conf/
EXPOSE 80
ENTRYPOINT ["nginx","-g","daemon off;"]

用到的文件如下:

root@root:~/docker/nginx-compile-check# ll
-rw-r--r-- 1 root root     969 Mar 29 15:49 Dockerfile
-rw-r--r-- 1 root root 1032630 Aug 14  2019 nginx-1.16.1.tar.gz
-rw-r--r-- 1 root root    1353 Mar 29 15:50 nginx.conf
-rw-r--r-- 1 root root  134043 Mar 29 14:28 nginx_upstream_check_module-master.tar.gz

以上文件下载地址:

https://download.csdn.net/download/pcn01/12805024

创建nginx镜像:

docker build -t nginx:16 .

启动nginx容器:

docker run -d  \
--restart unless-stopped \
-p 80:80 \
--name nginx \
-v /data/nginx_docker/data:/application/nginx/html \
-v /data/nginx_docker/logs:/var/log/nginx \
-v /data/nginx_docker/conf.d:/application/nginx/conf/extra \
nginx:16

nginx站点配置文件:

    upstream inve_port {
        server xxxxxxxx:8080 weight=1;
        server xxxxxxxx:8081 weight=1;
        #http health check
        check interval=3000 rise=2 fall=3 timeout=3000 type=http;
        #/health/status为后端健康检查接口
        check_http_send "HEAD /health/status HTTP/1.0\r\n\r\n";
        check_http_expect_alive http_2xx http_3xx;
    }
    server {
        listen       80;
        server_name  _;
        access_log  /var/log/nginx/default_access.log  main;
        error_log  /var/log/nginx/default_error.log  error;
        #root   /application/nginx/html/default;
        location / {
            proxy_pass http://inve_port;
            add_header backendIP $upstream_addr;
            add_header backendCode $upstream_status;
            proxy_set_header X-Forwarded-For $remote_addr;
        }
        # 查看后端服务器实时的健康状态
        location /status {
                check_status;
                access_log off;
        }
        location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
        {
            expires 3650d;
        }
        location ~ .*\.(js|css)?$
        {
            expires 30d;
        }
    }
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐