社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  NGINX

Nginx 部署负载均衡服务全解析

芋道源码 • 1 周前 • 55 次点击  

👉 这是一个或许对你有用的社群

🐱 一对一交流/面试小册/简历优化/求职解惑,欢迎加入芋道快速开发平台知识星球。下面是星球提供的部分资料: 

👉这是一个或许对你有用的开源项目

国产 Star 破 10w+ 的开源项目,前端包括管理后台 + 微信小程序,后端支持单体和微服务架构。

功能涵盖 RBAC 权限、SaaS 多租户、数据权限、商城、支付、工作流、大屏报表、微信公众号、ERPCRMAI 大模型等等功能:

  • Boot 多模块架构:https://gitee.com/zhijiantianya/ruoyi-vue-pro
  • Cloud 微服务架构:https://gitee.com/zhijiantianya/yudao-cloud
  • 视频教程:https://doc.iocoder.cn
【国内首批】支持 JDK 17/21 + SpringBoot 3.3、JDK 8/11 + Spring Boot 2.7 双版本 

来源:江南一点雨


关于 Nginx 的配置,松哥之前写过好几篇文章和小伙伴们分享了,不过大部分都是基于全局视角去配置的,今天我们就单纯来聊一聊用 Nginx 做负载均衡的配置。

一 什么是负载均衡

负载均衡(Load Balancing)是一种计算机网络技术,用于将网络流量或请求分发到多个服务器上,以优化资源使用、最大化吞吐量、最小化响应时间,并避免任何单一点过载。负载均衡的目的是确保我们的 Web 应用的高可用性和可靠性,同时提高用户体验。

一般来说,我们可能会在如下场景中用到负载均衡:

  1. 服务器负载均衡:在多个服务器之间分配网络流量,以防止任何单个服务器因请求过多而性能下降。
  2. 数据中心负载均衡:在数据中心的不同位置或不同数据中心之间分配流量,以优化资源利用和提高可靠性。
  3. 云服务负载均衡:在云环境中,负载均衡可以跨多个虚拟机或容器服务分配流量。

虽然我们平时做负载均衡基本上都是 Nginx,但是考虑到文章内容的完整性,松哥还是和大家说一说负载均衡这事可以在不同的网络层面实行,比如:

  • DNS 负载均衡 :通过 DNS 服务将域名解析成不同的 IP 地址,将流量分散到不同的服务器上。
  • 硬件负载均衡 :使用专门的硬件设备(如 F5 BIG-IP)来分配流量。
  • 软件负载均衡 :使用软件解决方案(如 Nginx、HAProxy)来实现负载均衡。
  • 应用层负载均衡 :在应用层(如 HTTP/HTTPS)分配请求到不同的服务器。
  • 传输层负载均衡 :在传输层(如 TCP/UDP)分配连接到不同的服务器。

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/ruoyi-vue-pro
  • 视频教程:https://doc.iocoder.cn/video/

二 常见负载均衡算法

无论你使用哪种工具,在哪进行负载均衡,常见的负载均衡算法主要是下面这几种:

  • 轮询(Round Robin) :将请求轮流分配给每台服务器。
  • 最少连接(Least Connections) :将请求分配给当前连接数最少的服务器。
  • 加权轮询(Weighted Round Robin) :根据服务器的性能权重来分配请求。
  • 加权最少连接(Weighted Least Connections) :根据服务器的性能权重和当前连接数来分配请求。
  • IP 哈希(IP Hash) :根据客户端 IP 地址的哈希值来分配请求,以保证来自同一 IP 的请求总是被分配到同一台服务器上。

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/yudao-cloud
  • 视频教程:https://doc.iocoder.cn/video/

三 Nginx 配置

3.1 轮询(Round Robin)

轮询是 Nginx 默认的负载均衡策略,它将客户端的请求按顺序轮流分配到后端服务器上。如果后端服务器宕机,Nginx 会自动将其剔除出队列,直到该服务器恢复正常。

举个栗子

upstream backend {  
    server backend1.example.com;  
    server backend2.example.com;  
    server backend3.example.com;  
}  
  
server {  
    ...  
    location / {  
        proxy_pass http://backend;  
    }  
    ...  
}

在上面的配置中,Nginx 会将请求依次分配给 backend1、backend2 和 backend3,循环往复。

3.2 加权轮询

加权轮询策略允许你为后端服务器分配不同的权重,权重越高的服务器将接收更多的请求。这可以根据服务器的硬件配置、处理能力等因素进行灵活配置。

http {  
    upstream myapp1 {  # 定义一个名为myapp1的服务器组  
        server backend1.example.com weight=5;  # 添加一个服务器,并设置权重为5  
        server backend2.example.com;  # 添加另一个服务器,权重默认为1  
        server backend3.example.com down;  # 将此服务器标记为down,不参与负载均衡  
        server backup1.example.com backup;  # 将此服务器作为备份服务器  
    }  
  
    server {  
        listen 80;  # 监听80端口  
  
        location / {  # 匹配所有请求  
            proxy_pass http://myapp1;  # 将请求转发到myapp1服务器组  
            proxy_set_header Host $host;  # 设置请求头中的Host字段为原始请求的Host  
            proxy_set_header X-Real-IP $remote_addr;  # 设置请求头中的X-Real-IP字段为客户端的真实IP地址  
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  # 设置请求头中的X-Forwarded-For字段,以记录原始请求和代理链的IP地址  
            proxy_set_header X-Forwarded-Proto $scheme;  # 设置请求头中的X-Forwarded-Proto字段为原始请求的协议(http或https)  
        }  
    }  
}

上面的负载均衡策略是权重,除了权重之外,还有轮询以及 ip_hash 等。

3.3 IP 哈希(IP Hash)

IP 哈希策略根据客户端的 IP 地址进行哈希运算,将相同的请求分配给同一个后端服务器。

这种策略适用于需要保持会话(Session)的场景,因为同一个客户端的请求会被发送到同一个服务器,从而避免了会话信息的丢失。

upstream backend {  
    ip_hash;  
    server backend1.example.com;  
    server backend2.example.com;  
    server backend3.example.com;  
}  
  
server {  
    ...  
    location / {  
        proxy_pass http://backend;  
    }  
    ...  
}

在上面的配置中,Nginx 会根据客户端的 IP 地址进行哈希运算,然后将请求分配到对应的后端服务器。

3.4 最少连接(Least Connections)

最少连接策略将新的请求分配给当前连接数最少的后端服务器。这种策略可以确保每个后端服务器的负载相对均衡,避免某个服务器过载而其他服务器空闲的情况。

注意:Nginx 原生的 Stream 模块支持最少连接,但在 HTTP 模块中通常需要借助第三方插件或脚本实现。

对于 HTTP 模块,可以通过第三方插件如 ngx_http_upstream_fair_module 或编写 Lua 脚本来实现类似的功能。

但在 Stream 模块中,可以直接配置,下面是一个 Stream 中配置的例子:

upstream backend {  
    least_conn;  
    server backend1.example.com;  
    server backend2.example.com;  
    server backend3.example.com;  
}  
  
stream {  
    server {  
        listen 12345;  
        proxy_pass backend;  
    }  
}

3.5 健康检查

在 Nginx 中配置负载均衡的健康检查,可以通过主动健康检查(Active Health Checks)和被动健康检查(Passive Health Checks)两种方式来实现。

主动健康检查

主动健康检查是定期向上游服务器发送请求以检查其健康状况,如果上游服务器未能正确响应,Nginx 将认为该服务器不健康,并停止向其发送流量,直到服务器恢复健康。

配置方式如下:

http {
    upstream backend {
        server backend1.example.com;
        server backend2.example.com;
        check interval=3000 rise=2 fall=5 timeout=1000 type=http;
        check_http_send "HEAD /health HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n";
        check_http_expect_alive http_2xx http_3xx;
    }
    server {
        location / {
            proxy_pass http://backend;
        }
    }
}

在这个配置中,Nginx 将每隔 3 秒(interval=3000)向 /health 端点发送一个 HEAD 请求。如果服务器连续两次返回 2xx 或 3xx 的 HTTP 状态码(rise=2),则认为服务器是健康的。如果服务器连续五次未能正确响应(fall=5),则认为服务器不健康。

被动健康检查

被动健康检查基于实时流量分析,Nginx 根据后端服务器的响应来判断其健康状况。如果服务器返回特定的错误状态码,Nginx 将认为该服务器不健康,并在一段时间内不再将请求发送到该服务器。

配置方式如下:

http {
    upstream backend {
        server backend1.example.com;
        server backend2.example.com max_fails=2 fail_timeout=30s;
    }
    server {
        listen 80;
        location / {
            proxy_pass backend;
            proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
        }
    }
}

在这个配置中,如果后端服务器在 30 秒内连续两次(max_fails=2)未能正确响应,它将被临时从服务器池中移除。proxy_next_upstream 指令指定了哪些错误应该触发使用不同的服务器进行重试。

好啦,Nginx 负载均衡一般来说配置这些就够啦~

一 什么是负载均衡

负载均衡(Load Balancing)是一种计算机网络技术,用于将网络流量或请求分发到多个服务器上,以优化资源使用、最大化吞吐量、最小化响应时间,并避免任何单一点过载。负载均衡的目的是确保我们的 Web 应用的高可用性和可靠性,同时提高用户体验。

一般来说,我们可能会在如下场景中用到负载均衡:

  1. 服务器负载均衡:在多个服务器之间分配网络流量,以防止任何单个服务器因请求过多而性能下降。
  2. 数据中心负载均衡:在数据中心的不同位置或不同数据中心之间分配流量,以优化资源利用和提高可靠性。
  3. 云服务负载均衡:在云环境中,负载均衡可以跨多个虚拟机或容器服务分配流量。

虽然我们平时做负载均衡基本上都是 Nginx,但是考虑到文章内容的完整性,松哥还是和大家说一说负载均衡这事可以在不同的网络层面实行,比如:

  • DNS 负载均衡 :通过 DNS 服务将域名解析成不同的 IP 地址,将流量分散到不同的服务器上。
  • 硬件负载均衡 :使用专门的硬件设备(如 F5 BIG-IP)来分配流量。
  • 软件负载均衡 :使用软件解决方案(如 Nginx、HAProxy)来实现负载均衡。
  • 应用层负载均衡 :在应用层(如 HTTP/HTTPS)分配请求到不同的服务器。
  • 传输层负载均衡 :在传输层(如 TCP/UDP)分配连接到不同的服务器。

二 常见负载均衡算法

无论你使用哪种工具,在哪进行负载均衡,常见的负载均衡算法主要是下面这几种:

  • 轮询(Round Robin) :将请求轮流分配给每台服务器。
  • 最少连接(Least Connections) :将请求分配给当前连接数最少的服务器。
  • 加权轮询(Weighted Round Robin) :根据服务器的性能权重来分配请求。
  • 加权最少连接(Weighted Least Connections) :根据服务器的性能权重和当前连接数来分配请求。
  • IP 哈希(IP Hash) :根据客户端 IP 地址的哈希值来分配请求,以保证来自同一 IP 的请求总是被分配到同一台服务器上。

三 Nginx 配置

3.1 轮询(Round Robin)

轮询是 Nginx 默认的负载均衡策略,它将客户端的请求按顺序轮流分配到后端服务器上。如果后端服务器宕机,Nginx 会自动将其剔除出队列,直到该服务器恢复正常。

举个栗子

upstream backend {  
    server backend1.example.com;  
    server backend2.example.com;  
    server backend3.example.com;  
}  
  
server {  
    ...  
    location / {  
        proxy_pass http://backend;  
    }  
    ...  
}

在上面的配置中,Nginx 会将请求依次分配给 backend1、backend2 和 backend3,循环往复。

3.2 加权轮询

加权轮询策略允许你为后端服务器分配不同的权重,权重越高的服务器将接收更多的请求。这可以根据服务器的硬件配置、处理能力等因素进行灵活配置。

http {  
    upstream myapp1 {  # 定义一个名为myapp1的服务器组  
        server backend1.example.com weight=5;  # 添加一个服务器,并设置权重为5  
        server backend2.example.com;  # 添加另一个服务器,权重默认为1  
        server backend3.example.com down;  # 将此服务器标记为down,不参与负载均衡  
        server backup1.example.com backup;  # 将此服务器作为备份服务器  
    }  
  
    server {  
        listen 80;  # 监听80端口  
  
        location / {  # 匹配所有请求  
            proxy_pass http://myapp1;  # 将请求转发到myapp1服务器组  
            proxy_set_header Host $host;  # 设置请求头中的Host字段为原始请求的Host  
            proxy_set_header X-Real-IP $remote_addr;  # 设置请求头中的X-Real-IP字段为客户端的真实IP地址  
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  # 设置请求头中的X-Forwarded-For字段,以记录原始请求和代理链的IP地址  
            proxy_set_header X-Forwarded-Proto $scheme;  # 设置请求头中的X-Forwarded-Proto字段为原始请求的协议(http或https)  
        }  
    }  
}

上面的负载均衡策略是权重,除了权重之外,还有轮询以及 ip_hash 等。

3.3 IP 哈希(IP Hash)

IP 哈希策略根据客户端的 IP 地址进行哈希运算,将相同的请求分配给同一个后端服务器。

这种策略适用于需要保持会话(Session)的场景,因为同一个客户端的请求会被发送到同一个服务器,从而避免了会话信息的丢失。

upstream backend {  
    ip_hash;  
    server backend1.example.com;  
    server backend2.example.com;  
    server backend3.example.com;  
}  
  
server {  
    ...  
    location / {  
        proxy_pass http://backend;  
    }  
    ...  
}

在上面的配置中,Nginx 会根据客户端的 IP 地址进行哈希运算,然后将请求分配到对应的后端服务器。

3.4 最少连接(Least Connections)

最少连接策略将新的请求分配给当前连接数最少的后端服务器。这种策略可以确保每个后端服务器的负载相对均衡,避免某个服务器过载而其他服务器空闲的情况。

注意:Nginx 原生的 Stream 模块支持最少连接,但在 HTTP 模块中通常需要借助第三方插件或脚本实现。

对于 HTTP 模块,可以通过第三方插件如 ngx_http_upstream_fair_module 或编写 Lua 脚本来实现类似的功能。

但在 Stream 模块中,可以直接配置,下面是一个 Stream 中配置的例子:

upstream backend {  
    least_conn;  
    server backend1.example.com;  
    server backend2.example.com;  
    server backend3.example.com;  
}  
  
stream {  
    server {  
        listen 12345;  
        proxy_pass backend;  
    }  
}

3.5 健康检查

在 Nginx 中配置负载均衡的健康检查,可以通过主动健康检查(Active Health Checks)和被动健康检查(Passive Health Checks)两种方式来实现。

主动健康检查

主动健康检查是定期向上游服务器发送请求以检查其健康状况,如果上游服务器未能正确响应,Nginx 将认为该服务器不健康,并停止向其发送流量,直到服务器恢复健康。

配置方式如下:




    
http {
    upstream backend {
        server backend1.example.com;
        server backend2.example.com;
        check interval=3000 rise=2 fall=5 timeout=1000 type=http;
        check_http_send "HEAD /health HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n";
        check_http_expect_alive http_2xx http_3xx;
    }
    server {
        location / {
            proxy_pass http://backend;
        }
    }
}

在这个配置中,Nginx 将每隔 3 秒(interval=3000)向 /health 端点发送一个 HEAD 请求。如果服务器连续两次返回 2xx 或 3xx 的 HTTP 状态码(rise=2),则认为服务器是健康的。如果服务器连续五次未能正确响应(fall=5),则认为服务器不健康。

被动健康检查

被动健康检查基于实时流量分析,Nginx 根据后端服务器的响应来判断其健康状况。如果服务器返回特定的错误状态码,Nginx 将认为该服务器不健康,并在一段时间内不再将请求发送到该服务器。

配置方式如下:

http {
    upstream backend {
        server backend1.example.com;
        server backend2.example.com max_fails=2 fail_timeout=30s;
    }
    server {
        listen 80;
        location / {
            proxy_pass backend;
            proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
        }
    }
}

在这个配置中,如果后端服务器在 30 秒内连续两次(max_fails=2)未能正确响应,它将被临时从服务器池中移除。proxy_next_upstream 指令指定了哪些错误应该触发使用不同的服务器进行重试。

好啦,Nginx 负载均衡一般来说配置这些就够啦~


欢迎加入我的知识星球,全面提升技术能力。

👉 加入方式,长按”或“扫描”下方二维码噢

星球的内容包括:项目实战、面试招聘、源码解析、学习路线。

文章有帮助的话,在看,转发吧。

谢谢支持哟 (*^__^*)

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/178686
 
55 次点击