nginx负载均衡and健康检查

负载均衡和反向代理

  • 模块
    • upstream 和 proxy_pass

http {
    include       mime.types;
    default_type  application/octet-stream;
 
    log_format  main 
                      '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
 
 
    sendfile        on;
 
    keepalive_timeout  65;
    upstream worldcup {  # 配置负载均衡
           server 10.124.25.28:8001; 
           server 10.124.25.29:8001;
    # 配置后 访问本机ip 会轮询上面这两个ip
server{
    location / {
        root html;
        index index.html index.htm;
        proxy_pass http://worldcup/; # 反向代理
        # 在server中的location配置 
        # 访问本机的 /目录 会代理到目标url
    }
}

健康检查

  • 模块
    • upstream_check_module
  • 有两种方式
    # 第一种方式 直接在upstream的server中填写检测方式
    # 这种方式为 nginx 被动检查
    
       upstream keep_one {
           server 192.168.1.1:8080 weight=1 max_fails=2 fail_timeout=30s;
           server 192.168.1.2:8080 weight=1 max_fails=2 fail_timeout=30s;
       }
       # max_fails=2 fail_timeout=30s  
       # 意思是 在检查服务器中 30s内 如果有两次检查失败就把该ip踢出
# 第二种方式
# 需要在编译的时候指定添加 upstream_check_module模块 ,或者重编译nginx
# 这种方式为主动检查

# 主动地健康检查,nignx定时主动地去ping后端的服务列表,当发现某服务出现异常时,把该服务从健康列表中移除,当发现某服务恢复时,又能够将该服务加回健康列表中。淘宝有一个开源的实现nginx_upstream_check_module模块
  • 安装 nginx_upstream_check_module
    # 下载
    wget https://codeload.github.com/yaoweibin/nginx_upstream_check_module/zip/master
    unzip master 
    [root@localhost ~]# ls
    anaconda-ks.cfg  initial-setup-ks.cfg  master  nginx-1.19.6  nginx-1.19.6.tar.gz  nginx_upstream_check_module-master
    
  • 进入到nginx源码目录
    [root@localhost nginx-1.16.1]# patch -p1 < ../nginx_upstream_check_module-master/check_1.16.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
    # 出现以上就说明导入模块完成  还要注意 版本号要相同,要不然导入不成功
    
    # 接下来重新编译一下nginx
    # 通过 nginx -V 查看之前编译的模块
    [root@localhost nginx-1.16.1]# nginx -V
    nginx version: nginx/1.16.1
    built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC) 
    configure arguments: --prefix=/usr/local/nginx
    # 在重新编译一下
    [root@localhost nginx-1.16.1]# ./configure --prefix=/usr/local/nginx --add-module=/root/nginx_upstream_check_module-master && make
    # 如果有其他模块的话 要看 nginx -V 然后再添加模块到里面
    # 注意这里不能用make install 因为nginx已经安装上了
    
  • 将 nginx 启动命令重新复制一下
    [root@localhost nginx-1.16.1]# cp objs/nginx /usr/local/nginx/sbin/nginx
    cp:是否覆盖"/usr/local/nginx/sbin/nginx"? y
    # 可以提前备份之前的
  • 编写配置文件
        upstream lmk{
            server 192.168.100.201:80;
            server 192.168.100.202:80;
            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  localhost;
    
            #charset koi8-r;
    
            #access_log  logs/host.access.log  main;
    
            location / {
                root   html;
                index  index.html index.htm;
                proxy_pass http://lmk/;  # 配置代理ip
            }
  • 验证配置文件
    [root@localhost conf]# nginx -t
    nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
    nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
    [root@localhost conf]# nginx # 启动nginx
    # 访问查看是否进行负载均衡 
    [root@localhost conf]# curl 127.0.0.1
    <center><h1>192.168.100.201</h1></center>
    [root@localhost conf]# curl 127.0.0.1
    <center><h1>192.168.100.202</h1></center>
    

补充

# 健康检查的格式
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。
名称 作用
interval 向后端发送的健康检查包的间隔,单位为毫秒
rsie 如果连续成功次数达到rise_count,服务器就被认为是up
fall 如果连续失败次数达到fall_count,服务器就被认为是down
timeout 后端健康请求的超时时间,单位为毫秒
type 健康检查包的类型,支持tcp、ssl_hello、http、mysql、ajp

被动检查和主动检查

被动检查

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

主动检查

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

本博客所有文章是以学习为目的,如果有不对的地方可以一起交流沟通共同学习 邮箱:1248287831@qq.com!