nginx的upstream模块

一、upstream模块实现负载均衡

1.1 负载均衡配置

upstream在http块内,与server块并列,用于配置负载均衡,虽然upstream模块需要与代理指令一起使用,但代理指令仅仅只是用于转发请求它本身并没有任何负载均衡的功能,upstream才是实现负载均衡的具体模块
1)作用:upstream定义了在反向代理时 Nginx 需要访问的后端服务器集群和负载均衡策略。
2)语法:upstream name { server ip:port; … }
3)在upsream定义的主机组内,每个ip:port后,可以跟检测节点套接字服务状态的参数(基于tcp协议)

状态 概述
down 节点下线,当前节点不参与负载均衡,一般用于临时维护场景
backup 备用节点,平时不生效,一旦全部节点都挂掉才开始工作
max_fails 允许请求失败的次数
fail_timeout 经过max_fails失败后, 该节点被暂停代理的时间
max_conns 限制最大的接收连接数

示例

server {
    listen 8888;
    server_name localhost;
    location ^~ /test/ {
        #1、转发原始请求的 host 头部
        proxy_set_header X-Real-IP $remote_addr;  # 设置真实/原始客户端的 IP 地址
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  # 追加原始客户端的 IP 地址到 X-Forwarded-For 头信息中。这样,在后端服务器中就可以通过读取 X-Forwarded-For 头信息来获取原始客户端的 IP 地址。
        proxy_set_header Host $host;
        #2、转发到upstream块定义的服务器集群
        proxy_pass http://test_balance;
    }
}
#上游服务列表
upstream test_balance {
    server 192.168.43.100:8080 max_fails=3 fail_timeout=5s;
    server 192.168.43.101:8080 max_fails=3 fail_timeout=5s;
    server 192.168.43.102:8080 backup;
}

后端web可能存放有缓存,清理掉rm -rf /var/cache/nginx/*

1.2 慢启动

1、nginx的商业版本nginx plus提供了一个slow_start参数

Nginx Plus是一个由Nginx开发的商业版,提供了比开源版Nginx更多的功能和支持。官网:https://www.nginx-cn.net/products/nginx/

Nginx Plus提供的slow_start参数用于控制向后端服务器增加负载的速度。这个参数在服务器恢复后的第一次使用或者在服务器被修复完毕、刚刚启动时非常有用,因为在这些情况下,服务器可能无法立刻承受大量的请求。
slow_start参数值设定了一个时间段,新添加的服务器或恢复的服务器,在这个时间段内将从0开始逐步被增加请求。
以下是一个包含 slow_start 参数的示例配置:

upstream backend {
    server backend1.example.com slow_start=30s;
    server backend2.example.com;
    server backend3.example.com;
}

在这个配置中,如果backend1.example.com服务器重新上线或刚启动,Nginx在前30秒内会逐渐增加传送到这个服务器的请求,而不是一下子把大量请求打过去。
其中需要注意的是:
slow_start的值不能设置得过低,否则新服务器或恢复的服务器可能无法承受突然增加的请求。但也不能设置得过高,否则可能影响服务的性能。
2.slow_start的作用时间结束后,服务器就会正常参与负载均衡。
3.slow_start只有在round-robin 和 least_conn 这两种分配策略中才有效。
4.slow_start仅在Nginx 1.11.5及更高版本中可用。

2、开源的nginx如何实现类似的效果

对于开源版本的NGINX,虽然没有内置的slow_start功能,但有一些策略可以实现类似的效果:
1、使用权重调整策略:你可以开始时将失败的后端服务器的负载均衡权重设置得较低,然后逐步提高权重。这需要手动操作或者编写脚本定时调整权重。
2、灵活使用负载均衡算法:NGINX支持多种负载均衡算法,例如轮询(Round Robin)、最少链接(Least Connections)等,通过合理使用这些算法,可以在一定程度上实现slow_start的效果。
3、使用其他开源工具:还有一些开源工具如HAProxy也提供了slow_start的功能,可以根据实际需求选择使用。
这些方法都有其局限性,如果slow_start对你的业务十分重要,可能需要考虑使用NGINX Plus或者其他提供了此功能的工具。

1.3 负载均衡常见问题

1)问题:服务活着,接口代码出错了

负载均衡管理的多个节点中,某个节点上的套接字服务本身挂掉了,会导致负载均衡与其连接超时
这种情况下,Nginx是本身是有机制的,就是你之前在upstream模块内ip与port后增加的一些连接失败的尝试参数,
nginx会根据这些参数判定节点是否挂掉,如果出现一个节点挂掉的时候,Nginx会更据你具体负载均衡的设置,将请求转移到其他的节点上,

但是可能会出现这种情况,就是负载均衡管理的后台节点上的套接字服务是运行ok的,都能正常接收负载均衡发来的请求
即该节点没有down掉,问题是出在内部代码错误而返回如:504、502、500等异常码的情况,导致用户访问失败

此时,会给用户造成不好的影响,为了能够避免这种问题
我们需要加一个负载均衡的设置,如下:proxy_next_upstream http_500 | http_502 | http_503 | http_504 |http_404;
意思是,当其中一台返回错误码404,500...等错误时,可以分配到下一台服务器程序继续处理,提高平台访问成功率。

示例

============================>web01
server {
    listen 8080;
    server_name 192.168.71.14;

    location ~* / {
        default_type text/html;
        return 200 "web01";
    }
}
============================>web02
server {
    listen 8080;
    server_name 192.168.71.15;

    location ~* / {
        return 500; # ======》 这台服务器端口正确启动着服务本身并无异常,但是接口层模拟代码运行出错返回500
    }
}
============================>web03
server {
    listen 8080;
    server_name 192.168.71.16;

    location ~* / {
        default_type text/html;
        return 200 "web03";
    }
}
============================>负载均衡
http {
    upstream webserver {
      server 192.168.71.14:8080;
      server 192.168.71.15:8080;
      server 192.168.71.16:8080;
    }
    server {
        listen       9090;
        server_name  192.168.71.12;
        location / {
           proxy_pass  http://webserver;
           proxy_set_header X-Real-IP $remote_addr; 
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
           proxy_set_header Host $http_host;
        }
    }
}
============================>测试
访问:192.168.71.12:9090,有一次访问是500错误,后端服务并没有down掉,只是接口层面出错返回500了,这就让用户感觉很不好

2)解决问题的模块

Syntax: proxy_next_upstream error | timeout | invalid_header | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | http_429 | non_idempotent | off ...;
Default:    proxy_next_upstream error timeout;
Context:    http, server, location

3)配置

[root@lb01 ~]# vim /etc/nginx/conf.d/linux.wp.com.conf
upstream blog {
    server 172.16.1.7;
    server 172.16.1.8;
}

server {
    listen 80;
    server_name linux.wp.com;

    location / {
        proxy_pass http://blog;
        include proxy_params;
        #可以配置在这里,当然也可以写到include指定的文件里
        proxy_next_upstream error timeout http_500 http_502 http_503 http_504 http_403 http_404;
    }
}

#重启
[root@lb01 ~]# systemctl restart nginx

接口报错上述code的不会被返回给客户端,upstream会重新请求ok的web服务器来得到正常响应

1.4 负载均衡调度算法

Nginx 负载均衡有 rr轮询(默认)、wrr加权轮询、ip_hash、url_hash、fair 五种策略,不同的应用场景使用不同的负载均衡策略/调度算法。

调度算法 概述
轮询(默认) 按时间顺序逐一分配到不同的后端服务器(默认)
weight 加权轮询,weight值越大,分配到的访问几率越高
ip_hash 每个请求按访问IP的hash结果分配,这样来自同一IP的固定访问一个后端服务器
url_hash 按照访问URL的hash结果来分配请求,是每个URL定向到同一个后端服务器
least_conn 最少链接数,哪个机器链接数少就分发
fari 智能/公平调度

1 rr轮询(默认)

轮询方式,依次将请求分配到各个后台服务器中,默认的负载均衡策略。

每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器 down 掉,能自动剔除。

适用于后台机器性能一致的情况。

示例:不用指定,默认就是rr
http {
    upstream backend {
        server backend1.example.com;
        server backend2.example.com;
    }

    server {
        location / {
            proxy_pass http://backend;
        }
    }
}

2、wrr加权轮询

根据权重来分发请求到不同的机器中,指定轮询几率,参数 weight 和 访问比率成正比。

权重越高的服务器实例,分担越大的负载量。所以硬件配置较好的服务器应该设置较高的权重。

适用于后端服务器性能不均的情况。

示例:指定权重,就是wrr
http {
    upstream backend {
        server backend1.example.com weight=3;
        server backend2.example.com weight=2;
        server backend2.example.com weight=5;
    }

    server {
        location / {
            proxy_pass http://backend;
        }
    }
}

3、ip_hash

每个请求按访问 IP 的哈希结果分配,使来自同一个 IP 的访客固定访问一台后端服务器,并且可以有效解决动态网页存在的 session 共享问题。俗称IP绑定。

优势:在处理需要会话保持(session persistence)的请求时,使用ip_hash非常有用。
局限性:固定服务器实例如果宕机,那么这台服务器上保存的 Session 信息会丢失。

示例:负载均衡策略:ip_hash,固定ip由固定服务器实例处理
http {
    upstream backend {
        ip_hash;
        server backend1.example.com;
        server backend2.example.com;
    }

    server {
        location / {
            proxy_pass http://backend;
        }
    }
}
测试的使用建议用curl命令进行测试,规避浏览器缓存带来的影响

4 url_hash

按访问的 URL 的哈希结果来分配请求,使每个 URL 定向到一台后端服务器,可以进一步提高后端缓存服务器的效率。

Nginx 本身不支持 url_hash,如果需要这种调度算法,则必须安装并启用nginx-sticky-module模块。
安装与使用:https://egonlin.com/?p=9444

示例
http {
    upstream backend {
        sticky path;
        server backend1.example.com;
        server backend2.example.com;
    }

    server {
        location / {
            proxy_pass http://backend;
        }
    }
}

5、least_conn

upstream backend {
    least_conn;
    server backend1.example.com;
    server backend2.example.com;
}
在这个配置中,Nginx会把每个新请求传送到活跃连接数量最少的服务器。
然而,有一点需要注意,虽然 least_conn 可以提高系统处理能力,但它并不是所有情况下的最佳选择。比如当服务器处理请求的速度差异很大时,最快的服务器可能会收到更多的请求,这可能会导致最快的服务器过载。在这种情况下,你可能需要根据具体的业务需求和后端服务器的能力,选择其他的负载均衡策略,例如轮询或者权重。

6、公平调度算法(fair)

fair采用的不是内建负载均衡使用的轮换的均衡算法,而是可以根据页面大小、加载时间长短智能的进行负载均衡。 

Nginx 本身不支持 fair,如果需要这种调度算法,这需要安装并启用nginx_upstream_fair模块。
安装与启用见:https://egonlin.com/?p=9447

示例
http {
    upstream backend {
        server backend1.example.com;
        server backend2.example.com;
        fair;
    }

    server {
        location / {
            proxy_pass http://backend;
        }
    }
}

1.4 其他

# 负载均衡的叫法
1.负载均衡
2.负载
3.LB
4.Load Balance

# 公有云中常见的负载均衡
1.SLB       #阿里云产品
2.LB        #青云产品
3.CLB       #腾讯云产品
4.ULB       #Ucloud产品

# 负载均衡软件
1.nginx
2.Haproxy
3.LVS

# 负载均衡的分类:四层与七层负载均衡
复习见:https://egonlin.com/?cat=44

二、负载均衡的健康检查(扩展)

2.1 什么是健康检查

健康检查就是负载均衡器对后台的节点周期性进行存活性检查
这可以在确保用户请求到来之前,就及时发现问题节点并剔除,以此提升用户访问体验

2.2 健康检查的意义

之前你学习的可以在upstream模块内的ip:port后加的一些max_fails、fail_timeout参数,针对的都是用户请求进来之后,负载均衡去尝试访问某个节点而尝试失败的次数与停用试验,一切都是发生在用户请求来的时候,负载均衡本身并不知道后端节点是活着的还是死了的,只能试,如果节点是挂掉的,你尝试这几次本身就是耗费时间的。
所以,能不能在用户请求来之前,你负载均衡就提前能发现一些节点不可用了,如此,请求便连试都没有试的必要了,用户访问体验更快啊,这个就是健康检查的关键意义

细说没有健康健康情况下的问题
1、故障节点无法发现:健康检查的一个主要作用就是能够检测服务是否可用。如果没有健康检查,故障或者异常的节点可能无法及时发现,继续将请求路由到这样的节点,会导致请求失败,影响用户体验。
2、显著影响性能:如果请求被分发到了一个故障或已关闭的服务器,那么该请求会失败或者超时,这将显著影响系统的性能,并可能导致其他服务的延迟增加。
3、负载分配不均衡:没有健康检查,负载均衡器可能会把请求发到无法处理请求的服务器上,使其他健康的服务器负载增加,负载分配不均,影响服务的效率。
4、影响整体系统稳定性:由于无法及时发现并隔离故障节点,可能出现一连串的问题,最后甚至可能导致整个系统出现严重故障或者瘫痪。
5、影响运维效率:没有健康检查,运维人员需要手动去检查每个服务节点的状态,这无疑会大大增加运维的难度和工作量,降低运维效率

负载均衡的健康检查就是用来解决上述问题的

2.3 nginx实现负载均衡如何增加健康检查功能

在Nginx官方模块提供的模块中,没有对负载均衡后端节点的健康检查模块,但可以使用第三方模块。
nginx_upstream_check_module来检测后端服务的健康状态。

该模块作用
1、故障排除:健康检查可以快速检测到后端服务器是否出现故障,如果某个后端服务器出现故障,那么负载均衡器可以将其从服务池中移除,这样用户的请求就不会被路由到故障的服务器上,提高了服务的可用性。
2、宽容处理:除了能够移除故障的服务器,健康检查还可以自动监测到恢复正常的服务器,并将它们重新加入到服务池中。这样做有助于提高系统的容错性,防止服务因单点问题而完全中断。

1.安装依赖

[root@lb02 ~]# yum install -y gcc glibc gcc-c++ pcre-devel openssl-devel patch

2.下载第三方模块

[root@lb02 ~]# wget http://nginx.org/download/nginx-1.14.2.tar.gz
[root@lb02 ~]# wget https://github.com/yaoweibin/nginx_upstream_check_module/archive/master.zip

3.解压及安装

[root@lb02 ~]# tar xf nginx-1.14.2.tar.gz
[root@lb02 ~]# unzip master.zip

4.进入nginx目录,打补丁(nginx的版本是1.14补丁就选择1.14的,p1代表在nginx目录,p0是不在nginx目录)

[root@lb02 ~]# cd nginx-1.14.2/

[root@lb02 nginx-1.14.2]# patch -p1 <../nginx_upstream_check_module-master/check_1.14.0+.patch

[root@lb02 nginx-1.14.2]# ./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --add-module=/root/nginx_upstream_check_module-master --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie'

[root@lb02 nginx-1.14.2]# make && make install

5.在已有的负载均衡上增加健康检查的功能

[root@lb01 conf.d]# cat proxy_web.conf
upstream web {
    server 172.16.1.7:80 max_fails=2 fail_timeout=10s;
    server 172.16.1.8:80 max_fails=2 fail_timeout=10s;
    check interval=3000 rise=2 fall=3 timeout=1000 type=tcp;
    #interval  检测间隔时间,单位为毫秒
    #rise      表示请求2次正常,标记此后端的状态为up
    #fall      表示请求3次失败,标记此后端的状态为down
    #type      类型为tcp
    #timeout   超时时间(达到失败次数后,timeout时间内不会被调度),单位为毫秒
}

server {
    listen 80;
    server_name linux.lb.com;
    location / {
        proxy_pass http://web;
        include proxy_params;
    }

    location /upstream_check {
        check_status;
    }
}

6.重启访问页面

#重启
#配置hosts
#访问
http://linux.lb.com/upstream_check
上一篇
下一篇
Copyright © 2022 Egon的技术星球 egonlin.com 版权所有 帮助IT小伙伴学到真正的技术