搭建高可用负载均衡系统:Nginx 与云服务的最佳实践

搭建高可用负载均衡系统:Nginx 与云服务的最佳实践

引言

在项目开发过程中,我们通常在开发和测试阶段采用单机架构进行开发和测试。这是因为在这个阶段,系统的主要目的是功能实现和验证,单机架构足以满足开发人员的日常需求,且可以简化环境配置和调试过程,方便定位和修复问题。

然而,到了项目上线阶段,系统面临的场景就完全不同了。上线后的系统需要处理真实用户的访问,而用户量在一段时间内可能会迅速增长,从而给系统带来巨大的压力。在这种情况下,单机架构往往难以承载如此高并发的请求和大规模的流量,容易造成服务不可用甚至系统崩溃。这是我们上线前必须要考虑到的问题。

因此,为了应对上线后可能出现的系统压力,保障系统的稳定性和性能表现,我们一般会选择使用多台服务器进行部署,也就是集群架构。这种集群部署方式能够有效地分散流量,避免某台服务器单独承载过多的负载,提升系统的抗压能力和高可用性。通过多台服务器协同工作,系统的整体吞吐量和可靠性都得到了极大的提高,确保即使在用户量快速增加的情况下,服务仍然能够稳定、高效地运行。

实际情况要考虑自己项目的预估上线后一段时间的用户量 不要盲目就采用集群架构。如果是B端产品 往往单体架构就足够。我这里一般说的是C端项目哈

负载均衡

集群架构在我之前的文章中已经有所介绍。而提到集群架构,我们就不得不谈到负载均衡。在集群环境中,负载均衡是系统架构中至关重要的一部分。

负载均衡,简单来说,就是将用户的请求分发到多台服务器上,以便均衡系统负载,防止单个服务器因为请求过多而成为系统的瓶颈。负载均衡的作用不仅仅是将请求"平均分配",更重要的是提高整个系统的可用性、可靠性和性能。它可以有效地分散流量,提高系统的并发处理能力,从而确保系统的稳定和响应速度。

负载均衡的必要性在于应对现代互联网应用中的高并发、高流量场景。随着用户量的增长,单台服务器的处理能力往往会遇到瓶颈,导致请求响应速度变慢,甚至引发系统崩溃。而通过负载均衡,我们可以将请求分发到多台服务器,使得每台服务器的负载保持在合理范围之内,防止某个节点因负载过高而宕机,同时也提高了系统的容错能力。

我们实现负载均衡的实现方式有多种,可以通过硬件设备(如 F5)、软件(如 Nginx、HAProxy),或云服务提供商的负载均衡产品(如阿里云 SLB)来实现。不同的方式各有其特点,适用于不同的场景。无论采用何种方式,要注意我们实现负载均衡的核心目标是确保系统的高可用性和高性能。

负载均衡搭建方案

在我们公司开发部门中,通常都会有专门的运维团队来负责搭建负载均衡的架构。一般情况下,我们会专门拿出一台服务器作为负载均衡服务器,并在这台服务器上配置 Nginx 来实现集群节点之间的负载均衡。这样做的目的是为了将请求合理分发到不同的服务器上,避免单台服务器过载,同时提高系统的高可用性和性能。

我们使用一台专门的服务器来做负载均衡服务器,主要有以下几个原因:

  1. 独立负载均衡,防止瓶颈:如果负载均衡功能与业务服务部署在同一台机器上,那么在系统流量大幅增加时,这台机器很容易成为性能瓶颈。专门拿出一台服务器进行负载均衡,能够避免这种情况,确保请求的分发是高效且均衡的。
  2. 高可用性和可扩展性:独立的负载均衡服务器便于系统扩展,当用户量增加时,可以轻松地增加后端服务器节点,而负载均衡服务器可以继续正常工作而不受到影响。同时,如果负载均衡服务器出现故障,我们也可以很方便地替换或者进行热备。
  3. 集中控制和管理:通过一台专门的负载均衡服务器,所有的请求都会先经过该服务器,再转发到不同的后端节点。这样可以集中管理请求的分发策略,例如调整某些节点的权重、设置健康检查等,从而实现更精细化的负载控制。

像我之前待过开发团队比较小的公司中 一般没有专门的运维负责这些。基本上都是我们开发负责人来进行架构搭建。 这种情况下 如果公司预算充足的情况下 我通常会采用第三方的负载均衡服务,比如阿里云提供的 SLB(Server Load Balancer)(因为我们项目很多都采用的阿里云服务器)。阿里云 SLB 可以自动地将请求分发到多台后端服务器节点,并且由云服务商提供高可用的保证,减少了我们在维护和运维上的复杂性,特别是在应对高并发和流量波动时非常方便。

在接下来的内容中,我们将简单介绍如何使用 Nginx 配置负载均衡,以及如何通过阿里云的 SLB 来实现更为自动化的负载均衡方案。

如何使用 Nginx 搭建负载均衡(CentOS 示例)

在负载均衡的方案中,Nginx 是一个我们非常常用的负载均衡解决方案。接下来我将介绍如何在 CentOS 系统上使用 Nginx 搭建负载均衡,并通过两台服务器来测试是否实现负载均衡。

1. 安装 Nginx

首先,我们买一台用于负载均衡的服务器 并登陆服务器安装 Nginx。以 CentOS 系统为例,可以通过以下命令来安装:

  1. 添加 Nginx 源

    arduino 复制代码
    sudo yum install -y epel-release
  2. 安装 Nginx

    sudo yum install -y nginx
    
  3. 启动 Nginx 服务

    bash 复制代码
    sudo systemctl start nginx
    sudo systemctl enable nginx

确保 Nginx 服务已正常启动。

2. 配置 Nginx 实现负载均衡

Nginx 作为负载均衡器的核心配置在于定义 upstream 模块和 server 模块。

  1. 编辑 Nginx 配置文件 :通常情况下,我们可以在 /etc/nginx/nginx.conf 文件中进行配置,或者在 /etc/nginx/conf.d/ 目录下创建一个自定义的配置文件来定义1. 负载均衡。

  2. 定义后端服务器 :比如我有两台后端服务器,其 IP 地址分别为 192.168.0.77192.168.0.76。我们可以通过 upstream 模块来定义这两台服务器。我们在/etc/nginx/conf.d/ 目录下创建一个自定义的配置文件 nginx_upstream.conf

    编辑 Nginx 配置文件,添加如下配置:

    ini 复制代码
    upstream backend_servers {
        server 192.168.0.77:8081;  # 后端服务器 1,监听 8081 端口
        server 192.168.0.76:8081;  # 后端服务器 2,监听 8081 端口
    }
    
    server {
        listen 80;
        #server_name yourdomain.com;
    
        location / {
            proxy_pass http://backend_servers;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }

    这里的 upstream 模块定义了两个后端服务器,proxy_pass 指令将请求转发到这些后端节点。

    1. 节点。
  3. 验证 Nginx 配置并重启服务: 在修改完配置文件后,首先使用以下命令检查配置是否正确:

    sudo nginx -t
    

    如果没有错误提示,则可以重启 Nginx 服务以使配置生效:

    sudo systemctl restart nginx
    
3. 在后端服务器上运行测试服务(验证负载均衡是否生效)

要测试负载均衡是否正常工作,我们需要在两台后端服务器上设置简单的 HTTP 服务。

  1. 在两台服务器上安装 Python:确保 Python 已安装,可以通过以下命令安装:

    sudo yum install -y python3
    
  2. 创建测试页面 :在每台后端服务器上,进入用户的主目录(例如 /home/wwwroot/),创建一个包含不同内容的 index.html 文件:

    • 192.168.0.77 上执行:

      css 复制代码
      mkdir -p /home/wwwroot/html
      echo '<html><body><h1>Response from Server 192.168.0.77</h1></body></html>' > /home/wwwroot/html/index.html
    • 192.168.0.76 上执行:

      css 复制代码
      mkdir -p /home/wwwroot/html
      echo '<html><body><h1>Response from Server 192.168.0.76</h1></body></html>' > /home/wwwroot/html/index.html
  3. 启动简单的 HTTP 服务 :在两台服务器上,分别进入包含 index.html 的目录并启动 HTTP 服务:

    bash 复制代码
    # 在两台服务器上执行
    cd /home/wwwroot/html
    python3 -m http.server 8081

    这样,两台服务器就分别在 8081 端口上提供服务。

4. 测试负载均衡是否生效
  1. 访问负载均衡服务器 : 在浏览器中访问负载均衡服务器的 IP 地址(例如 http://<nginx-server-ip>),或者在命令行中使用 curl 命令:

    arduino 复制代码
    curl http://<nginx-server-ip>
  2. 验证请求的响应 :多次刷新浏览器页面,或者多次运行 curl 命令,我们会看到不同的响应内容,分别来自 192.168.0.77192.168.0.76,如下:

    • Response from Server 192.168.0.77
    • Response from Server 192.168.0.76

    这表明 Nginx 已经将请求分发到不同的后端服务器上,负载均衡功能正常工作。

这样我们就通过nginx简单实现了一个负载均衡示例。


阿里云SLB负载均衡

我们用阿里云提供的负载均衡产品的话。我们登陆阿里云控制台可以看到阿里云提供了三种类型的负载均衡,分别是:应用型负载均衡(ALB)网络型负载均衡(NLB)传统型负载均衡(CLB)

其中每种负载均衡都有其特定的特点和适用场景,我大概介绍下介绍这三种负载均衡的区别、用处以及适用的场景,帮助我们根据实际需求进行选择。

1. 应用型负载均衡(ALB)

应用型负载均衡(Application Load Balancer,ALB) 是专门面向HTTP、HTTPS和QUIC等应用层负载场景的负载均衡服务,具备超强弹性及大规模应用层流量处理能力。ALB具备处理复杂业务路由的能力,与云原生相关服务深度集成,是阿里云官方提供的云原生Ingress网关。

  • 特点
    • 具备强大的应用层负载均衡能力,支持 HTTP/HTTPS 请求。
    • 支持 URL 路由、主机头转发、路径匹配等高级功能。
    • 支持自定义流量调度策略,例如基于请求内容进行路由。
    • 具备灵活的安全策略和 SSL/TLS 加密支持,方便用户实现全链路加密。
  • 适用场景
    • Web 应用:对于需要应用层调度的 Web 应用来说,ALB 非常适合。例如需要根据 URL 路径将请求分发到不同后端服务器的情况。
    • 高并发网站:ALB 适用于需要处理高并发请求的网站,特别是需要对请求进行复杂路由的场景。
    • 基于微服务架构的应用:ALB 可以根据应用层内容来实现流量的调度和分发,适合微服务架构中的不同服务之间的路由需求。
  • 优点
    • 高性能:能够处理大规模的并发连接。
    • 灵活的路由能力:提供七层的请求管理和流量控制能力,支持复杂的流量转发。
2. 网络型负载均衡(NLB)

网络型负载均衡(Network Load Balancer,NLB) 是面向万物互联时代推出的新一代四层负载均衡,支持超高性能和自动弹性能力,单实例可以达到1亿并发连接,可以轻松应对高并发业务。NLB面向海量终端上连、高并发消息服务、音视频传输等业务场景针对性推出了TCPSSL卸载、新建连接限速、多端口监听等高级特性,在物联网MQTTS加密卸载、抗洪峰上联等场景为用户提供多种辅助手段,是适合IOT业务的新一代负载均衡。

  • 特点
    • 主要针对 TCP、UDP、QUIC 协议的负载均衡,工作在网络层(四层)。
    • 具有超低的网络延迟,适合高并发、高吞吐量的场景。
    • 支持超大并发连接数,可以处理大规模并发请求。
    • NLB 的处理效率高,支持较低的网络时延。
  • 适用场景
    • 实时通信应用:对于实时性要求高的应用(如游戏、实时音视频),NLB 非常合适。
    • 需要高吞吐量的应用:对于需要处理大量 TCP/UDP 流量的应用,例如大型网络游戏、视频推流等,NLB 的高吞吐能力非常适用。
    • 企业内部系统:对于一些企业内部的系统,NLB 可以用于实现 TCP/UDP 协议的流量分发和高可用。
  • 优点
    • 低延迟:因为工作在四层,数据包直接转发,处理速度快。
    • 高吞吐量:适合需要高并发和大量连接数的场景。
3. 传统型负载均衡(CLB)

传统型负载均衡(Classic Load Balancer,CLB) 是阿里云最早提供的负载均衡服务,支持四层和七层协议的流量调度。它是将访问流量根据转发策略分发到后端多台云服务器的流量分发控制服务。CLB扩展了应用的服务能力,增强了应用的可用性。

  • 特点
    • 支持 HTTP、HTTPS、TCP、UDP 等多种协议的负载均衡。
    • 集成了四层和七层负载均衡的能力,可以根据需要选择工作在应用层或者网络层。
    • 提供基本的健康检查、会话保持和 SSL 加密支持。
  • 适用场景
    • 传统架构应用:对于一些不需要复杂流量控制的传统应用,CLB 是一个经济实惠的选择。
    • 小型网站或应用:对于小型网站或初创项目,CLB 是一个比较基础的负载均衡解决方案,适合成本敏感的场景。
    • 向新型负载均衡的过渡:对于现有的架构,如果使用的是 CLB,可以逐步过渡到更先进的 ALB 或 NLB。
  • 优点
    • 兼容性强:支持多种协议,覆盖更多类型的应用场景。
    • 易于配置:基础的负载均衡功能,配置简单,适合快速上手。
4. 选择哪种负载均衡器?

选择合适的负载均衡类型取决于应用的特点和需求:

  • 如果应用主要基于 HTTP/HTTPS 协议 ,并且需要应用层路由(例如根据 URL 路径进行流量分发),那么选择 应用型负载均衡(ALB) 更为合适。
  • 如果应用需要处理 TCP/UDP 大量并发连接 ,例如实时通信、视频推流或大型网络游戏,那么 网络型负载均衡(NLB) 是最佳选择,因其低延迟和高吞吐量特性。
  • 如果应用是 传统架构 ,且不需要复杂的负载均衡功能,或者预算有限,那么可以选择 传统型负载均衡(CLB) ,它功能较为基础,但足以应对大多数常见需求。

对于大多数场景,阿里云推荐使用 ALB 或 NLB,因为它们的性能和功能更符合现代应用需求。尤其在基于微服务的架构中,ALB 提供了灵活的应用层流量管理能力,而 NLB 则适用于需要高并发、低延迟的场景。


今天我们以传统型负载均衡(CLB)来举例实现负载均衡。

使用阿里云传统型负载均衡(CLB)搭建负载均衡

1. 创建负载均衡实例

要搭建传统型负载均衡,首先需要在阿里云管理控制台上创建一个 CLB 实例。

  1. 登录阿里云控制台 :访问 阿里云控制台,登录到账户。
  2. 进入负载均衡页面:在控制台中,找到并进入"负载均衡(SLB)"服务1. 页面。
  3. 创建负载均衡实例 :点击"创建负载均衡实例"按钮,开始配置负载均衡:
    • 选择实例类型:选择"传统型负载均衡(CLB)"。
    • 选择区域和可用区:根据我们的后端服务器所在的地域,选择合适的区域和可用区。
    • 选择网络类型:可以选择"专有网络(VPC)"或"经典网络"。推荐使用 VPC 以获得更好的网络隔离和安全性。
    • 选择实例规格:选择合适的规格,通常取决于预计的流量规模。
  4. 确认并创建:确认配置无误后,点击"创建"按钮,完成实例的创建。

因为测试需要 我这边创建了一个低配按量付费的负载均衡实例。接下来我们开始配置负载均衡。

2. 配置监听

创建 CLB 实例之后,需要为其配置监听。监听用于定义负载均衡如何处理来自客户端的请求,以及将请求转发到后端服务器的方式。我们点击实例界面的 点我开始配置 选项开始进行配置。

  1. 选择协议和监听端口
  • 首先,我们需要选择 监听协议 。在配置监听页面中,我们可以看到有四种协议选项可选:
    • TCP:适用于需要可靠传输的应用,如 Web 服务。
    • UDP:适用于实时通信和流媒体等无连接传输的应用。
    • HTTP:适用于需要七层(应用层)代理的 Web 应用。
    • HTTPS:适用于需要加密传输的 Web 应用。
  • 根据我们这次测试的需求,我们选择 TCP 协议(正常项目一般选择http/https协议)。
  • 监听端口 处,填写一个我们希望 CLB 用于外部服务的端口,范围在 1-65535 之间。例如,比如我们希望通过 80 端口提供服务,则填写 80
  1. 填写监听名称(可选)
  • 监听名称 一栏中,我们可以为该监听配置填写一个自定义名称。这对于有多个监听配置的情况下,可以帮助我们更好地进行区分。
  • 如果我们不填写名称,系统会自动分配一个默认名称,例如"协议_端口"。
  1. 标签配置(可选)
  • 标签用于标记和管理我们的负载均衡实例,尤其是当我们需要管理多个负载均衡实例时,可以通过标签方便地查找和过滤。
  • 标签键标签值 都是可选的,我们可以根据我们的项目内部资源管理策略来添加合适的标签。
  1. 高级配置

在配置页面的右下方,我们可以看到高级配置的选项。

  • 调度算法:默认是"轮询"方式。轮询是指将请求平均分配到后端服务器中,确保每个服务器接收到的请求量大致相等。我们也可以根据需要选择其他调度算法(例如最小连接数)。
  • 会话保持 :会话保持用于让同一个客户端的请求始终被分发到同一台后端服务器。对于需要维持用户会话的应用,建议打开会话保持;而对于无状态的服务,可以关闭会话保持。在截图中,默认是 关闭 状态。
  • 访问控制 :访问控制可以设置白名单或黑名单来限制哪些 IP 段可以访问我们的负载均衡实例。默认是 关闭,即没有做任何访问限制。如果我们需要对外部访问进行控制,可以启用该选项并配置相关规则。
  • 监听带宽限制 :可以对监听的带宽进行限制,防止某个监听占用过多的带宽资源。在截图中,这个选项设置为 不限速,这意味着监听不会被带宽限制,但我们也可以根据需要进行调整。
  • 完成以上设置后,点击页面右下角的"下一步"按钮,进入到 后端服务器 的配置步骤。我们将添加实际用于处理请求的 ECS 服务器节点。
3.后端服务器

监听配置完成后,需要将后端服务器添加到负载均衡器中,以实现流量分发。

在这个步骤中,后端服务器的配置用于接收和处理来自负载均衡的请求,从而实现均衡的流量分发,确保各服务器之间的负载压力相对平衡。

在配置后端服务器时,有以下三种服务器组可供选择:

  • 虚拟服务器组:虚拟服务器组是用于逻辑分组多个后端服务器,通常用于多服务集群的流量分发场景,便于更细粒度的管理。
  • 默认服务器组:默认服务器组是最基础的服务器集合,用于大部分基础负载均衡场景,适合不需要复杂逻辑的流量调度。
  • 主备服务器组:主备服务器组通常用于高可用性场景,其中某些服务器为主服务器,另外一些为备份,当主服务器出现故障时,备服务器会接替流量处理。

在本次配置中,我们选择 默认服务器组,以便快速搭建负载均衡,实现流量的基础分发。我们选择刚才用nginx测试负载均衡的两台后端服务器。

  1. 进入"后端服务器"选项卡:在负载均衡实例的详情页面中,找到并点击"后端服务器"选项卡。

  2. 添加服务器

    • 点击"添加后端服务器"按钮,选择需要添加的后端服务器。一般情况下,后端服务器是同一地域内的 ECS 实例。

    • 设置权重 :每台服务器的权重决定了它能分配到的流量比例。默认权重为 100,可以根据服务器的处理能力调整不同的权重。权重越高,服务器分配的请求越多。

  3. 确认添加:确认后端服务器已经正确添加到负载均衡器中。

我们添加完后端服器后会发现界面多了两台服务器 但是列表有个端口选项:

在负载均衡配置中,端口 是用来指定负载均衡器将流量转发到后端服务器的目标端口。也就是说,当负载均衡器接收到来自客户端的请求时,它需要知道应该把这些请求转发到后端服务器的哪个端口上。

例如,比如有一个 Web 应用,运行在后端服务器的 8080 端口上,那么我们就需要在这个端口配置栏中填写 8080,这样负载均衡器在接收到请求后,就会把请求发送到后端服务器的 8080 端口进行处理。

比如上面我们的后端服务器 192.168.0.77192.168.0.76 上运行的是 Web 应用,监听的端口是 8081,那我们应该按如下方式填写端口:

  • 192.168.0.77 的端口填写为 8081
  • 192.168.0.76 的端口也填写为 8081

这样,负载均衡器在接收到客户端的请求后,就会将请求转发到这两台服务器的 8081 端口进行处理。

4.健康检查

添加后端服务器后,下一步是配置健康检查。健康检查的作用是定期检测后端服务器的状态,以确保负载均衡器只将请求转发到健康的服务器上。

在配置健康检查时,有以下几个关键参数需要注意:

  1. 开启健康检查:默认情况下,健康检查是开启的,这可以确保后端服务器的健康状态被持续监控。如果某台服务器出现异常,负载均衡器会自动将其从请求分发列表中移除。
  2. 健康检查协议 :可以选择使用与监听相同的协议(例如 TCP、HTTP 等)进行检查。我们上面提供的截图显示使用的是 TCP 协议,适用于快速判断 TCP 连接是否正常。
  3. 健康检查间隔时间 :设置健康检查的间隔时间,单位为秒。截图中设置为 2 秒,意味着每隔 2 秒对后端服务器进行一次健康检查。
  4. 健康检查响应超时时间 :设置健康检查的超时时间,单位为秒。在截图中设置为 5 秒,表示在 5 秒内如果没有收到健康响应,则认为该次检查失败。
  5. 健康检查健康/不健康阈值
    • 健康阈值 :截图中设置为 3 次,表示只有连续 3 次健康检查通过,服务器才被认为是健康的。
    • 不健康阈值 :截图中设置为 3 次,表示只有连续 3 次健康检查失败,服务器才被标记为不健康,从而从负载均衡列表中移除。

配置好健康检查后,负载均衡器可以持续监控后端服务器的健康状态,确保只有健康的服务器接收请求,从而提高系统的可用性和可靠性。

5.配置审核

在配置完监听、后端服务器和健康检查之后 我们下一步进入配置审核页面。

配置审核是对前面所有步骤的一个总结和检查,以确保所有配置正确无误。在配置审核页面中,我们可以看到以下内容:

  • 协议和监听
    • 负载均衡协议:例如 TCP。
    • 监听端口 :例如 80
    • 访问控制:是否开启访问限制。
    • 调度算法 :例如使用 轮询 算法。
    • 会话保持:是否启用会话保持。
    • 获取客户端真实 IP:是否启用。
  • 健康检查
    • 健康检查协议:例如 TCP。
    • 健康检查间隔时间超时时间健康和不健康阈值
  • 后端服务器
    • 列出已添加的后端服务器,包括 服务器 ID/名称区域VPCIP 地址端口权重

在确认所有配置无误后,可以点击页面右下方的"确认"或"完成"按钮,正式启动负载均衡服务。

6.配置修改保护和删除保护

配置完负载均衡实例后,我们在实例页面可以看到有两个选项:配置修改保护删除保护

  • 配置修改保护:开启配置修改保护后,任何对负载均衡配置的更改都需要进行额外的确认步骤,防止误操作引发的配置错误。开启此保护功能可以帮助在多人协作环境中确保重要配置不被轻易修改。
  • 删除保护:删除保护用于防止负载均衡实例被误删除。开启删除保护后,实例无法直接删除,必须先关闭删除保护,才能执行删除操作。这对于生产环境中的负载均衡实例尤为重要,避免因误操作导致服务中断。

针对这两个选项我建议对于生产环境中的负载均衡实例,建议开启配置修改保护和删除保护,以确保服务的稳定性和避免由于误操作导致的不可用情况。而对于测试环境或临时创建的实例,我们可以根据实际需要决定是否开启保护功能。

7. 健康检查和故障排查

配置完负载均衡实例后,系统会自动开始对后端服务器的 健康检查。健康检查的作用是持续检测后端服务器的健康状态,确保只有正常运行的服务器能够接收流量。当健康检查检测到服务器不健康时,负载均衡器会自动停止将请求转发到该服务器,直到其恢复健康状态。

在健康检查过程中,可能会遇到如截图所示的 异常后端服务器列表,这表示有后端服务器在健康检查中未通过。此时我们需要:

  1. 查看异常原因:点击健康检查中的"发起诊断"按钮,可以查看详细的异常原因。
  2. 排查服务器状态
    • 检查后端服务器的应用服务是否正常启动。
    • 确认服务器监听的端口是否正确配置,且未被防火墙阻止。
    • 检查服务器上的网络配置,确保网络正常,且没有阻止负载均衡器的请求。
  3. 调整健康检查配置:如果发现健康检查参数不合适(例如间隔时间太短或超时时间太短),可以在负载均衡的健康检查设置中对这些参数进行调整,使健康检查更符合实际应用的响应能力。
9. 测试负载均衡功能
  1. 通过域名或公网 IP 访问 :使用浏览器或 curl 命令访问我们配置的负载均衡器的域名或公网 IP 地址。
  2. 验证负载均衡效果:多次刷新页面,查看请求是否被分发到不同的后端服务器。我们可以在每台后端服务器上配置不同的响应内容(例如不同的 HTML 文件),以便确认请求的分发情况。

我这边测试结果跟上面nginx结果是一致的。说明我们使用阿里云负载均衡配置成功。


集群负载均衡的常见问题与解决方案

上面我们通过使用nginx和阿里云的负载均衡产品实现了一个简单的负载均衡架构。但是实际场景中 实现上面的架构只是简单实现了负载 但是如果要投入生产应用往往还不够 因为我们在使用负载均衡服务过程中会遇到很多问题 如多台服务器之间如何保持登陆状态、每台服务器之间的健康检查、负载均衡算法选择、节点扩展和收缩、SSL 终结等。下面我会简单介绍这些常见问题,并提供相应的解决方案和具体示例,帮助我们更好地应对这些问题。

针对下面的问题 我只简单讲解下会出现的问题和大概的解决方案 具体详细操作示例后面我在详细写个demo示例。可以先了解一下搭建完负载均衡服务后需要处理的问题。

1. 会话保持(Session Persistence)

问题描述

在分布式架构中,负载均衡器将请求分发到多个后端服务器以实现负载均衡。然而,如果应用需要记录用户的会话状态(如用户登录状态),负载均衡会导致请求可能分发到不同的服务器上,这样会话信息无法正确传递,导致用户登录失效或会话丢失。例如,用户第一次访问被分发到服务器 A 并登录,后续的请求被分发到服务器 B,而服务器 B 无法获取用户在服务器 A 上的会话状态。

解决方案

为了解决上述会话保持的问题,我们可以使用以下几种方式:

  1. 使用 Nginx 的 ip_hash 模块 进行会话保持。
  2. 阿里云 CLB 中启用会话保持功能,并配置保持时间。
  3. 通过 共享存储(如 Redis)结合 Token 的方式 进行集中会话管理,以便所有服务器共享会话数据。(常用)

解决方案 1:Nginx 使用 ip_hash 模块进行会话保持

在 Nginx 作为负载均衡器时,可以使用 ip_hash 模块根据客户端 IP 地址来分发请求。这样,同一 IP 地址的客户端请求将始终被路由到同一台后端服务器,从而保持会话一致性。

Nginx 配置示例

nginx 复制代码
upstream backend {
    ip_hash;  # 使用 ip_hash 模块
    server 192.168.0.77;
    server 192.168.0.76;
}

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

配置解释

  • ip_hash:指示 Nginx 根据客户端 IP 地址来选择后端服务器,使得同一 IP 地址的请求总是被分发到同一台服务器。这可以确保用户的会话数据始终存在于处理它的那台服务器上,避免会话丢失。
  • upstream backend:定义了多个后端服务器。
  • proxy_pass http://backend; :将请求转发给 upstream 指定的后端服务器组。

优势和局限性

  • 优势:简单有效,不需要改动应用代码即可实现会话保持。
  • 局限性:当用户的 IP 地址发生变化时(如使用移动网络或代理),会话保持机制会失效。此外,某台服务器宕机时,其上维护的会话数据会丢失,且某些服务器可能因流量集中而负载不均衡。

解决方案 2:阿里云 CLB 会话保持功能

阿里云 CLB(云负载均衡)支持会话保持功能,用户可以在 CLB 控制台中为监听器启用会话保持,这样可以确保来自同一客户端的请求总是分发到同一台后端服务器,确保会话状态的一致性。

阿里云 CLB 配置步骤

  1. 登录阿里云控制台
  2. 选择负载均衡实例
    • 在控制台中选择 负载均衡 服务,并找到我们配置的 CLB 实例。
  3. 配置会话保持
    • 进入负载均衡实例的详情页面,选择对应的监听器。
    • 在监听器配置页面中,找到会话保持设置项,点击启用会话保持。
    • 设置会话保持的时间,例如 30 分钟
    • 会话保持的方式通常可以选择基于 Cookie源 IP,其中:
      • Cookie:通过生成或重写 Cookie 实现,适合 HTTP 应用。
      • 源 IP:基于源 IP 地址,将相同 IP 地址的请求分发到同一台服务器,适合 TCP 和 UDP 应用。

优势和局限性

  • 优势:由云平台提供,操作简单,无需额外部署和维护。

  • 局限性:会话保持依赖于源 IP 或 Cookie,当 IP 地址变化或 Cookie 失效时,用户的会话可能会中断。此外,这种方式在服务器扩容或缩容时可能会带来负载不均的问题。

解决方案 3:共享存储解决方案 ------ 使用 Redis 和 Token

在现代分布式系统中,最常用的会话保持方案是通过共享存储的方式,将会话数据集中存储在一个中央存储中,使得所有服务器都可以共享访问。这种方案通常使用 Redis 作为共享存储结合 Token 来管理用户会话状态。

方案描述

  1. 生成 Token 并存储会话数据
    • 当用户登录时,应用程序生成一个唯一的 Token(如 JWT),并将该 Token 发送给客户端保存(例如通过 Cookie 或 LocalStorage)。
    • 同时,应用程序将用户的会话数据(如用户 ID、角色等)存储到 Redis 中,键为 Token,值为用户的会话信息。
  2. 客户端请求时携带 Token
    • 在每次客户端请求时,客户端会将 Token 发送到服务器,服务器根据 Token 在 Redis 中查找用户的会话信息,以此来验证用户的身份并获取会话数据。
    • 这样,无论请求被哪个后端服务器处理,后端服务器都可以通过 Redis 获取到相同的会话数据,从而保持用户的会话状态一致。

**示例流程

  1. 用户登录

    • 用户通过用户名和密码登录。

    • 服务器验证用户身份成功后,生成一个 Token 并存储到 Redis,例如:

      plaintext 复制代码
      Key: "session:<token>"
      Value: { "user_id": 1234, "username": "user1", "role": "admin" }
      Expiry: 30 minutes
    • 服务器将该 Token 返回给客户端。

  2. 后续请求

    • 用户在后续请求中将 Token 作为请求头或 Cookie 发送到服务器。
    • 服务器接收请求后,通过 Token 查询 Redis,获取到对应的用户会话信息。

优势和局限性

  • 优势
    • 高可用性:Redis 可以部署为集群,保证高可用性和可扩展性,即使某个 Redis 节点出现问题,其他节点仍然可以提供服务。
    • 灵活性:这种方式不依赖于 IP 或负载均衡器,因此用户可以自由切换网络,而不会影响会话状态。
    • 集中管理:所有服务器共享一个 Redis 实例,可以确保所有节点看到一致的会话数据,有利于扩展和维护。
  • 局限性
    • 复杂性增加:引入 Redis 作为外部依赖,需要额外的维护工作,如 Redis 的安装、配置和监控。
    • 性能依赖 Redis:每次请求需要访问 Redis 获取会话数据,因此 Redis 的性能和可用性会对整体系统的性能和可用性产生直接影响。
2. 健康检查(Health Check)
  • 问题描述:如果某个后端服务器出现故障,负载均衡器需要检测到故障并停止将请求转发到该服务器。

  • 解决方案

    Nginx 解决方案 :在使用 Nginx 做负载均衡时,检查后端服务器的健康状态非常重要,以便在某些服务器不可用时,Nginx 能自动将流量引导到可用的服务器上。Nginx 可以通过配置 upstream 中的 health_check 以及相关的健康检查机制来完成服务器健康检查。具体实现方式如下:

方式 1: 使用 upstream 模块中的健康检查(被动健康检查)

Nginx 的 upstream 模块支持基本的健康检查,可以通过配置 max_failsfail_timeout 来实现健康状态检测。

nginx 复制代码
http {
    upstream backend {
        # 定义多个后端服务器
        server 192.168.0.76:8081 max_fails=3 fail_timeout=30s;
        server 192.168.0.77:8081 max_fails=3 fail_timeout=30s;

        # 通过 max_fails 和 fail_timeout 配置服务器健康检查
    }

    server {
        listen 80;
        server_name www.example.com;

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

参数解释:

  1. max_fails
    • 该参数定义了允许请求失败的最大次数。在超过该次数后,Nginx 会认为该服务器失效,不再向其发送请求。
  2. fail_timeout
    • 指定了服务器在失败后的恢复时间段。Nginx 会在 fail_timeout 时间后再次尝试与该服务器进行通信,检查它是否恢复正常。

例如:server 192.168.0.76:8081 max_fails=3 fail_timeout=30s; 表示如果某个后端服务器在 30s 内连续失败了 3 次,则它会被标记为不可用。

该方案的局限性

该方案使用upstream 模块中的健康检查方案是一种比较基础的健康检查机制,它是属于一种被动健康检查 ,在一些特定的场景下(例如对高可用性有严格要求的 C 端产品),其实用性确实存在一定的局限性。被动健康检查 ,如 Nginx 的 max_failsfail_timeout 参数,它是通过监测实际请求的失败次数来判断后端服务器的健康状态。它的工作原理是:当 Nginx 转发请求到某个后端服务器,如果在一段时间内连续多次请求失败,Nginx 才会将该服务器标记为不可用,并在一段恢复时间后重新尝试。

局限性特点

  1. 被动响应滞后
    • 滞后性:被动健康检查依赖于实际请求的失败来判断后端服务器的状态。因此,在后端服务器出现问题时,负载均衡器并不会立即知道,只有在连续的用户请求失败时才会触发健康检查。这意味着在服务器已经出现问题的时间段内,C 端用户的请求仍然会被分发到该故障服务器,导致用户体验受损。
    • 用户感知失败:对于高并发的 C 端产品,这种滞后响应会直接影响到很多用户,他们可能会遇到加载缓慢、页面报错等问题,显著降低用户体验。
  2. 对首次故障的用户影响较大
    • max_fails 达到上限之前,负载均衡器依然会将请求分发到故障服务器。这意味着,在服务器真正被标记为不可用之前,有可能会有相当数量的用户请求被错误服务器处理,导致这些请求失败。
    • 对于 C 端产品,这样的失败通常是不能被接受的,因为每一个失败的请求都有可能导致用户流失。
  3. 故障恢复不够及时
    • fail_timeout 指定了服务器在失败后被标记为不可用的时间段。在这段时间内,Nginx 不会再尝试向该服务器发送请求,即使服务器在此期间已经恢复。这导致服务器恢复后的可用资源未被及时利用,降低了资源利用效率。
    • 特别是对于高流量的 C 端产品,在部分服务器恢复之后,迅速将其重新投入负载均衡是非常重要的。
  4. 不支持主动探测后端健康
    • 被动检查不能主动探测后端服务器的状态。例如,当一个后端服务进程崩溃时,Nginx 只能通过用户请求的失败来检测到。而主动健康检查(如定期发送探测请求)可以更快地发现故障,减少因故障导致的服务中断时间。

适用场景

  • 这种被动检查的方式更适合对高可用性要求不太严格,或者流量较小、后端服务器相对稳定的场景,例如一些内部管理系统或企业内部的应用。
  • 它的优点在于配置简单,易于部署和维护,无需额外的工具支持,适合中小型项目非关键业务系统的负载均衡。

对于高并发、高可用性的 C 端产品,我们通常会使用主动健康检查机制。主动健康检查可以定期向后端服务器发送探测请求,以确保只有健康的服务器才能接收流量,从而提高系统的可靠性和用户体验。


方式 2: 使用 nginx_upstream_check_module 模块

Nginx 本身没有内建的主动健康检查功能,但可以通过第三方模块 nginx_upstream_check_module 来实现更为精细的健康检查。该模块可以周期性地向后端服务器发送请求(如 HTTP 请求),判断其是否健康。

下面是一个示例:

nginx 复制代码
http {
    upstream backend {
        # 定义后端服务器
        server 192.168.0.76:8081;
        server 192.168.0.77:8081;

        # 开启健康检查
        check interval=5000 rise=2 fall=3 timeout=1000 type=http;
        check_http_send "HEAD / HTTP/1.1\r\n\r\n";
        check_http_expect_alive http_2xx http_3xx;
    }

    server {
        listen 80;
        server_name www.example.com;

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

参数解释:

  • check :
    • 启用健康检查并配置检查频率。例如:interval=5000 表示每隔 5000 毫秒进行一次健康检查。
    • rise 表示成功检查的次数,达到后将服务器标记为健康。
    • fall 表示失败检查的次数,超过后将服务器标记为不健康。
    • timeout 表示检查超时时间。
  • check_http_send :
    • 定义健康检查时发送的 HTTP 请求,如 HEAD 请求。
  • check_http_expect_alive :
    • 指定预期的响应状态码,如 http_2xxhttp_3xx

方式 3: 使用 http_stub_status_module 配合外部监控工具

Nginx 提供的 http_stub_status_module 模块可以输出关于 Nginx 自身状态的基本统计信息。虽然这不能直接用于主动健康检查,但可以用来配合外部监控工具(如 Prometheus)来收集数据并实现健康检查。

示例如下:

nginx 复制代码
server {
    listen 80;
    server_name status.example.com;

    location /nginx_status {
        stub_status;
        allow 127.0.0.1;  # 只允许本地访问
        deny all;
    }
}

访问 /nginx_status 时,我们可以获得一些关于当前 Nginx 连接情况的数据。然后配合外部脚本或工具分析这些数据来判断是否需要将某些服务器从负载均衡池中移除。

方式 4: 使用 Nginx Plus 的健康检查功能

如果我们使用商业版本的 Nginx Plus,我们可以直接使用其内置的主动健康检查功能,它可以通过 HTTP、TCP 或 UDP 来探测后端服务器的状态,并自动从负载均衡池中移除不健康的服务器。

Nginx Plus 配置示例如下:

nginx 复制代码
upstream backend {
    server 192.168.0.76:8081;
    server 192.168.0.77:8081;

    # 使用 Nginx Plus 的内置健康检查
    health_check interval=5s fails=3 passes=2;
}

参数解释:

  • interval :指定健康检查的频率,例如每 5s
  • fails:指示连续失败次数达到多少次后,将服务器标记为不健康。
  • passes:指示连续成功次数达到多少次后,将服务器标记为健康。
  • 基础健康检查 :通过 max_failsfail_timeout 可以简单地实现健康检查。
  • 主动健康检查 :可以借助第三方模块如 nginx_upstream_check_module 实现主动探测后端服务器。
  • 商业解决方案:Nginx Plus 具有强大的内置健康检查功能,支持 HTTP、TCP、UDP 等协议的检测。

阿里云 CLB 解决方案

阿里云 CLB 提供内置的健康检查功能,可以自动检测后端服务器的健康状态。

示例步骤:登录阿里云控制台,选择负载均衡实例,进入监听配置页面,配置健康检查参数,如检查间隔、超时时间、不健康阈值等。

3. 负载均衡算法选择

问题描述

负载均衡的主要目标是将流量均匀地分布到多台服务器上,从而优化资源利用率和系统响应时间。然而,如果选择不合适的负载均衡算法,可能导致某些服务器负载过高,而其他服务器则负载较轻,造成不均衡问题。因此,根据不同的业务需求选择合适的负载均衡算法非常重要。

解决方案

负载均衡算法的选择需要结合业务场景来决定,我们简单介绍下 Nginx 和阿里云 CLB 支持的几种常见负载均衡算法,以及它们的适用场景和配置示例。

Nginx 负载均衡算法选择

Nginx 作为负载均衡器时,支持以下几种常见的负载均衡算法,每种算法都有其适用的业务场景:

  1. 轮询(Round Robin)

    轮询是 Nginx 默认的负载均衡算法。它将请求按顺序依次分发到每个后端服务器。

    适用场景

    • 适合后端服务器性能和配置相同,且请求处理时间相似的场景。
    • 没有明显的流量波动和不均匀的请求负载的场景。

    示例配置

    nginx 复制代码
    upstream backend {
        server 192.168.0.101;
        server 192.168.0.102;
    }

    特点

    • 简单有效,但不考虑服务器的实际负载情况。如果有某台服务器的性能低于其他服务器,可能会导致负载不均。
  2. 加权轮询(Weighted Round Robin)

    通过设置权重来控制请求的分发频率。权重越高,服务器接收到的请求越多。

    适用场景

    • 适用于服务器硬件配置不同的情况。性能较好的服务器可以被设置更高的权重,以处理更多的请求。
    • 适合扩展时逐步将流量引导至新加入的服务器的场景。

    示例配置

    nginx 复制代码
    upstream backend {
        server 192.168.0.101 weight=3;  # 这台服务器权重为 3
        server 192.168.0.102 weight=1;  # 这台服务器权重为 1
    }

    特点

    • 可以更好地根据服务器性能进行负载分配,适合异构服务器集群。
  3. 最少连接(Least Connections)

    将请求分发给当前处理连接数最少的服务器。这种方式可以动态地选择最闲的服务器来处理请求。

    适用场景

    • 适用于请求处理时间较长且存在显著差异的场景。例如,有的请求是较快的静态文件,有的是需要较长时间的动态计算。
    • 非常适合 C 端产品,确保服务器负载均衡,避免某些服务器处理过多的长连接请求。

    示例配置

    nginx 复制代码
    upstream backend {
        least_conn;  # 使用最少连接算法
        server 192.168.0.101;
        server 192.168.0.102;
    }

    特点

    • 能有效地减少某些服务器的过载问题,但要求后端服务器性能较为接近。
  4. IP 哈希(IP Hash)

    通过对客户端 IP 地址进行哈希运算,将请求分发到特定的后端服务器。这样同一 IP 地址的请求总是会被路由到同一个服务器。

    适用场景

    • 适用于需要会话保持的场景,例如需要保持用户登录状态,确保所有来自同一用户的请求都由同一个后端服务器处理。
    • 通常用于无法通过共享存储解决会话一致性问题的情况下。

    示例配置

    nginx 复制代码
    upstream backend {
        ip_hash;  # 使用 IP 哈希算法
        server 192.168.0.101;
        server 192.168.0.102;
    }

    特点

    • 适合保持用户会话,但会有服务器负载不均衡的风险(例如,部分客户端可能产生比其他客户端更多的流量)。

阿里云 CLB 负载均衡算法选择

阿里云 CLB 提供轮询、加权轮询、最少连接等多种负载均衡算法,可以根据业务需求进行配置。

示例步骤:在阿里云控制台选择负载均衡实例,进入监听配置,选择合适的负载均衡算法。

在高并发的 C 端产品中,我们选择合适的负载均衡算法对系统的可靠性和稳定性至关重要。比如:

  • 对于 会话保持 需求,可以使用 IP 哈希 算法,确保同一用户的请求始终被分发到同一台服务器,避免会话数据不一致的问题。(现在大部分都是采用redis结合缓存的方式)
  • 对于 请求负载差异大 的场景,最少连接 算法是最佳选择,它能够动态地将请求分发到当前负载最轻的服务器上,避免某些服务器因为长连接而过载。
  • 异构集群 中,推荐使用 加权轮询 算法,以充分利用服务器的资源。例如,当集群中存在新加入的服务器或性能不同的服务器时,可以设置不同的权重,使性能较好的服务器承担更多的请求,从而优化整体资源利用率。
  • 特别是在面对 高并发活动 场景时,通过 加权轮询结合主备策略,可以灵活地增加临时服务器以应对流量高峰。例如,为新增加的服务器设置较低的权重,将其作为备用节点,逐步分担流量,确保活动期间系统的平稳运行。

通过合理的选择和配置负载均衡算法,我们可以实现更好的资源利用和用户体验,并确保在扩容和活动期间系统的可靠性和稳定性。

4. 节点扩展和收缩

问题描述

随着业务流量的变化,特别是在 C 端高并发场景下,系统的流量会有明显的波动。比如我们有时候开展活动用户量会比平常高好几倍,活动结束后 用户量又会恢复下来。这样时候如果开展活动升级服务器配置这种方案并不适用,为了保证系统的高可用性和资源利用率,通常需要动态增加或减少后端服务器的数量,以应对流量高峰或降低空闲资源的消耗。

解决方案

不同的负载均衡器在应对节点扩展和收缩方面提供了不同的解决方案。以下是 Nginx 和阿里云 CLB 实现动态扩展和收缩节点的具体方法。

解决方案 1:Nginx 动态节点扩展与收缩

Nginx 本身并不具备自动化扩展和收缩节点的功能,但我们可以通过修改配置文件的方式手动增加或删除后端服务器节点。

  1. 修改 Nginx 配置文件

    • 在 Nginx 的 upstream 中添加或删除后端服务器节点。例如,随着流量增加,可以在 upstream 配置中增加新的服务器节点。
    • 修改配置文件后,需要重新加载 Nginx 的配置,使新的服务器节点生效。

    示例配置

    nginx 复制代码
    upstream backend {
        server 192.168.0.101;
        server 192.168.0.102;
        server 192.168.0.103;  # 动态新增的节点
    }
    
    server {
        listen 80;
        server_name www.example.com;
    
        location / {
            proxy_pass http://backend;
        }
    }
  2. 重新加载 Nginx 配置

    • 修改配置文件后,使用 nginx -s reload 命令重新加载 Nginx 的配置,使新增或删除的服务器节点立即生效。

    示例命令

    bash 复制代码
    # 修改配置文件后,重新加载 Nginx
    nginx -s reload

优点

  • 操作灵活:可以根据业务需求手动添加或删除节点。
  • 立即生效 :通过 nginx -s reload 可以在不中断服务的情况下使新的节点配置生效。

局限性

  • 手动管理:每次节点扩展或收缩都需要手动修改配置文件,适合小规模集群或流量变化较为固定的场景,无法自动化处理。
  • 复杂性增加:当服务器节点数量较多时,管理变得复杂,容易出错。

解决方案 2:阿里云 CLB + 自动伸缩实现动态节点扩展与收缩

对于高并发、业务流量变化大的 C 端产品,推荐使用 阿里云 CLB 结合弹性伸缩(Auto Scaling) 实现节点的动态扩展和收缩。这种方式可以根据业务的流量情况自动调整服务器实例数量,确保系统的弹性和高可用性。

实现步骤

  1. 创建弹性伸缩组
    • 登录 阿里云控制台
    • 弹性伸缩 服务中创建一个 伸缩组 ,并将适当数量的 ECS 实例模板 添加到伸缩组中。
    • 设置最小、最大实例数量。例如,最小实例数量为 2,最大实例数量为 10,以便在流量增加时系统可以自动增加 ECS 实例数量。
  2. 配置伸缩策略
    • 配置基于 CPU 使用率、内存使用率或请求数量等的伸缩策略。例如,当某个实例的 CPU 使用率超过 70% 持续 5 分钟时,可以自动增加 ECS 实例。
    • 设置定时任务,例如在业务高峰时间自动增加实例数量,在流量低谷时自动减少实例数量。
  3. 将伸缩组与 CLB 关联
    • 将自动伸缩组与阿里云的 CLB(云负载均衡) 关联起来。
    • 新增的 ECS 实例会自动注册到 CLB 中,删除的实例也会自动从 CLB 中注销,无需手动管理节点的添加和删除。

示例配置

  1. 弹性伸缩组创建

    • 在阿里云控制台进入 弹性伸缩 服务,点击 创建伸缩组

    • 配置伸缩组的基础信息,包括最小实例数、最大实例数、VPC 选择等。

  2. 伸缩策略设置

    • 在伸缩组中配置 动态伸缩策略定时任务
    • 动态伸缩策略:基于监控指标(如 CPU 使用率)自动触发扩容或缩容。
    • 定时伸缩策略:设置每天的某个时间点自动调整实例数,以应对业务高峰和低谷。
  3. 将伸缩组关联到 CLB

    • 进入负载均衡实例的管理页面,将自动伸缩组关联到负载均衡的监听器上。
    • 自动伸缩组中的 ECS 实例会在伸缩时自动与负载均衡进行注册或注销,保持负载均衡的后端节点始终与业务负载相匹配。

优势

  1. 自动化管理
    • 系统能够根据流量情况自动增加或减少 ECS 实例,无需人工干预。
    • 通过自动伸缩与 CLB 的结合,新加入或删除的节点会自动进行注册和注销,保持系统的弹性。
  2. 高可用性和成本优化
    • 高可用性:通过自动伸缩,能够在流量高峰时迅速扩容,确保系统不会因资源不足而宕机;在低流量时缩容,减少空闲资源浪费。
    • 成本优化:系统可以动态缩减资源,节省服务器成本,确保只为实际需要的资源付费。

解决方案对比

解决方案 优势 局限性
Nginx 配置 + Reload 灵活手动控制节点的增删、配置简单 需手动管理,不适合动态变化场景
阿里云 CLB + 自动伸缩 自动化扩展与缩减、与 CLB 无缝结合,实时响应流量变化 依赖云服务,需一定的配置和维护

总结

  • Nginx 配置方案:适合小规模或流量波动不大的场景,节点增加和删除通过修改 Nginx 配置文件手动实现,然后重新加载配置即可。虽然灵活简单,但不适用于需要频繁变动节点数量的场景。
  • 阿里云 CLB + 自动伸缩方案:适合流量波动大、对高可用性要求高的 C 端产品场景。通过自动伸缩组和 CLB 结合,系统可以根据流量情况自动调整服务器节点数量,确保在业务高峰期能够及时扩容,而在低谷时有效缩容以节省成本。

我们根据实际业务需求选择合适的方案,可以确保系统在流量波动的情况下仍然能够保持高效、稳定的性能。对于需要频繁调整资源的高并发 C 端产品,推荐使用自动伸缩与 CLB 相结合的解决方案,以实现系统的弹性管理和优化资源利用率。

5. SSL 终结和加密流量
  • 问题描述:需要处理 HTTPS 请求,并确保客户端到负载均衡器之间的通信加密。

  • 解决方案

    • Nginx 解决方案:在 Nginx 中配置 SSL 证书,终结 HTTPS 请求。

      • 示例配置

        ini 复制代码
        server {
            listen 443 ssl;
            ssl_certificate /etc/nginx/ssl/nginx.crt;
            ssl_certificate_key /etc/nginx/ssl/nginx.key;
        
            location / {
                proxy_pass http://backend;
            }
        }
    • 阿里云 CLB 解决方案:在 CLB 上配置 SSL 证书,终结 HTTPS 请求。

      • 示例步骤:在阿里云控制台中,选择负载均衡实例,进入监听配置页面 选择https协议,上传 SSL 证书并启用 HTTPS。 (需要在证书管理选项配置域名证书)
6.流量分发和瓶颈以及单点故障问题

问题描述

在高并发和高流量的场景下,负载均衡器本身可能成为系统的瓶颈,导致性能下降,影响系统的可用性。例如,当单个负载均衡器无法处理突发流量或者硬件资源耗尽时,整个系统的性能都会受到影响。因此,需要通过一定的方法来提高负载均衡器的能力,避免单点故障和性能瓶颈。

解决方案概述

为了防止负载均衡器本身成为系统瓶颈,我们可以通过以下解决方案:

  1. Nginx 集群化部署结合 Keepalived 实现高可用性
  2. 使用云服务提供的多层级负载均衡(如阿里云 CLB)结合 DDoS 防护服务

这两种方案的目标都是提升系统的性能和可用性,避免因单个负载均衡器的故障或性能问题而导致系统不可用。

1:Nginx 集群化部署结合 Keepalived 实现高可用性

为了避免 Nginx 本身成为单点故障,可以通过集群化部署多台 Nginx 实例,并使用 Keepalived 来实现负载均衡器的高可用性。Keepalived 能够监控 Nginx 的健康状况,当某个节点故障时,自动将流量切换到其他健康节点。

Keepalived + Nginx 的架构

  1. 多台 Nginx 实例
    • 部署多台 Nginx 实例,这些实例会部署在不同的服务器上,以确保不会因为单点故障导致整个负载均衡失效。
  2. Keepalived 实现高可用性
    • 使用 Keepalived 实现虚拟 IP (VIP),并通过 VRRP(虚拟路由冗余协议) 实现多个 Nginx 节点之间的主备切换。当主 Nginx 负载均衡器故障时,VIP 会自动漂移到备用的 Nginx 节点,保证服务的高可用性。
  3. 流量分发
    • 客户端通过虚拟 IP 地址访问系统,Keepalived 将请求转发给健康的 Nginx 实例,由 Nginx 进行流量分发到后端服务器。

Keepalived 是用来管理多个 Nginx 负载均衡器之间的主备切换,当主节点(运行 Nginx 的服务器)出现故障时,Keepalived 会自动将流量切换到备用节点,从而实现高可用性。Keepalived 使用 VRRP(Virtual Router Redundancy Protocol) 实现虚拟 IP (VIP) 的漂移,这个 VIP 会始终指向正在运行的 Nginx 实例。

配置 Keepalived 与 Nginx 的架构

以下是一个典型的部署方案:

  • 部署多台 Nginx 服务器,每台都使用相同的 Nginx 配置。
  • 使用 Keepalived 管理虚拟 IP,在主节点不可用时,VIP 会漂移到备用节点上。
  • 客户端只需访问虚拟 IP,后台的 Keepalived 负责自动处理切换。

具体配置示例

1. Nginx 配置文件 (nginx.conf)

假设我们有两台 Nginx 服务器,它们都使用相同的 Nginx 配置:

nginx 复制代码
upstream backend {
    server backend1.example.com;
    server backend2.example.com;
}

server {
    listen 80;
    location / {
        proxy_pass http://backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
  • upstream backend 定义了后端服务器,Nginx 将根据负载均衡算法将请求转发到 backend1backend2
  • proxy_pass 用于将请求转发到上游服务器。

2. Keepalived 配置 (/etc/keepalived/keepalived.conf)

Keepalived 安装好后,在每台服务器上配置 keepalived.conf 文件。下面分别是主节点和备份节点的配置。

主节点配置 (MASTER)

conf 复制代码
vrrp_instance VI_1 {
    state MASTER
    interface eth0  # 本机网卡接口名,可能需要根据具体情况调整
    virtual_router_id 51  # 同一个虚拟路由 ID,所有节点需要一致
    priority 100  # 优先级较高,表示为主节点
    advert_int 1

    authentication {
        auth_type PASS
        auth_pass 1234  # 设置验证密码,所有节点应保持一致
    }

    virtual_ipaddress {
        192.168.0.100  # 虚拟 IP 地址
    }
}

备份节点配置 (BACKUP)

conf 复制代码
vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 51
    priority 90  # 优先级低于主节点,表示为备份节点
    advert_int 1

    authentication {
        auth_type PASS
        auth_pass 1234  # 验证密码需与主节点一致
    }

    virtual_ipaddress {
        192.168.0.100  # 与主节点相同的虚拟 IP 地址
    }
}

3. 参数说明

  • vrrp_instance:用于定义一个 VRRP 实例,配置主备切换的基本参数。
  • state :定义 Keepalived 实例的状态,MASTER 表示主节点,BACKUP 表示备份节点。
  • interface :用于指定服务器的网络接口名称,例如 eth0,具体名称需要根据系统中的实际网卡接口来确认。
  • virtual_router_id:虚拟路由 ID,所有节点必须一致,才能作为一个组来进行主备切换。
  • priority:优先级,值越高,优先级越高。主节点的优先级应大于备份节点。
  • auth_typeauth_pass:设置 VRRP 通信的认证方式和密码,确保通信的安全性。
  • virtual_ipaddress:定义虚拟 IP 地址(VIP),客户端会通过该 VIP 访问服务。Keepalived 会根据节点的状态将该 IP 绑定到主节点或备份节点。

4. 启动服务

  • 安装 Keepalived(可以通过包管理工具 aptyum 安装):

    bash 复制代码
    sudo apt-get install keepalived  # 对于 Ubuntu/Debian
    sudo yum install keepalived      # 对于 CentOS/RHEL
  • 修改完成配置文件 /etc/keepalived/keepalived.conf 后,启动 Keepalived:

    bash 复制代码
    sudo systemctl start keepalived
    sudo systemctl enable keepalived
  • 可以通过以下命令查看 Keepalived 的运行状态:

    bash 复制代码
    sudo systemctl status keepalived

Keepalived 和 Nginx 的配合工作方式

  • Keepalived 会监控本地 Nginx 服务的状态,当主节点出现故障(如宕机或服务无法响应)时,Keepalived 会将虚拟 IP 漂移到备份节点。
  • 通过虚拟 IP 实现高可用性,客户端的请求始终指向同一个虚拟 IP 地址,而 Keepalived 会确保这个虚拟 IP 始终对应一个健康的 Nginx 实例。
  • 这种方案可以保证当某个节点故障时,客户端无感知地自动切换到可用节点,实现负载均衡器的高可用性。

使用方案优点

  1. 高可用性:Keepalived 实现了自动主备切换,避免因单个负载均衡节点的故障导致服务不可用。
  2. 简单易用:使用 Keepalived 的配置相对简单,只需要少量配置就可以实现负载均衡器的高可用性。
  3. 无感知切换:VIP 的漂移使得客户端不需要感知服务器变化,提升了服务的连续性和稳定性。

其他注意事项

  • Keepalived 和 Nginx 必须部署在相同的服务器上。
  • 在生产环境中,应考虑使用双机或多机部署的方式来实现高可用性。
  • 还可以结合 Nginx 的健康检查模块(例如使用第三方健康检查模块或 Lua 脚本),以确保只将请求分发给健康的后端节点。

总结来说,通过 Keepalived 配置虚拟 IP 实现主备切换,再结合多台 Nginx 实现负载均衡,可以有效解决负载均衡器的单点故障问题,保障系统的高可用性和稳定性。

2:阿里云 CLB 结合 DDoS 防护实现多层级负载均衡

我们使用阿里云的 CLB(云负载均衡) 方案,特别适合于大规模的企业级应用和高并发场景。我们可以通过以下方式确保负载均衡器的高可用性和高性能:

  1. 多个 CLB 实例进行负载均衡
    • 部署多个 CLB 实例,通过地域划分或其他逻辑,将流量均衡地分发到不同的 CLB 实例,避免单个 CLB 实例成为系统的瓶颈。
    • CLB 本身是由云服务商管理的,可以提供自动扩展的能力来处理峰值流量,从而提高负载均衡器的抗压能力。
  2. 结合 DDoS 防护服务
    • 使用阿里云提供的 Anti-DDoS 防护服务来保护负载均衡器,防止恶意流量的攻击。
    • 当 DDoS 攻击发生时,Anti-DDoS 服务会自动对流量进行清洗,过滤恶意请求,保障 CLB 和后端服务器的稳定性和可用性。
  3. 健康检查
    • CLB 提供内置的健康检查功能,能够自动检测后端服务器的状态并将异常的服务器从负载均衡池中移除,确保流量只会分发给健康的后端服务器。
    • 支持 HTTP、TCP 和 UDP 等多种协议的健康检查,检查频率和超时时间可以根据实际需要配置。

这样配置的优势

  1. 弹性伸缩
    • 阿里云 CLB 支持弹性扩展,能够根据业务流量的变化自动进行扩缩容,确保在高峰期也能承载足够的流量。
  2. 高可用性
    • 阿里云 CLB 是由云服务商维护和管理,天然具备高可用性,并支持多可用区部署,避免因单个数据中心故障影响整体业务。
  3. 防止恶意流量攻击
    • 结合 Anti-DDoS 服务,可以有效防止恶意流量对系统的冲击,保障负载均衡器的稳定性。
    • 防护服务自动过滤恶意请求,保证正常用户的访问不会受到影响。

示例配置

在阿里云控制台中,可以配置多层级负载均衡架构:

  1. 创建多个 CLB 实例,分别位于不同的地域或可用区。
  2. 配置 Anti-DDoS 防护,保护每个 CLB 实例不受恶意流量攻击。
  3. 设置健康检查
    • 在 CLB 控制台为每个后端服务器配置健康检查,例如每 5 秒检查一次,如果 3 次检查失败则将该服务器标记为不健康。

通过这些步骤,可以确保在面对大量恶意流量或 DDoS 攻击时,系统能够承受压力,保证负载均衡器不成为系统的性能瓶颈。

我们如果在阿里云中配置多个 CLB(云负载均衡)实例以来解决负载均衡器本身的瓶颈问题时,对于如何处理访问的 IP 或域名,取决于我们具体的架构设计。有一种比较常见的配置方案可以帮我们合理配置访问入口的 IP 或域名,以实现高可用和高性能的流量分发。

使用 DNS 进行多区域或多 CLB 实例负载均衡

阿里云的多 CLB 部署一般用于提升高可用性和容灾能力。在这种情况下,我们通常通过 DNS 解析 来实现多个 CLB 实例之间的负载均衡。

  1. 配置多个 CLB 实例
    • 我们可以在阿里云的不同区域或同一区域内创建多个 CLB 实例,例如,一个在华东区域,一个在华南区域。
    • 每个 CLB 实例后端绑定一组 ECS 服务器,分别用于处理不同区域内的请求。
  2. 使用 DNS 解析
    • 我们可以将这些 CLB 实例绑定到一个统一的域名。
    • 通过在 DNS 提供商(例如阿里云的 DNS 解析服务)中为这个域名设置多条 A 记录,指向每个 CLB 的公网 IP 地址。
    • 例如,我们可以将 www.example.com 配置为以下多条记录:
      • A 记录www.example.com -> 123.45.67.89(CLB 实例 1 的 IP)
      • A 记录www.example.com -> 98.76.54.32(CLB 实例 2 的 IP)
  • 实现高可用和负载均衡
    • 在这种情况下,当用户访问 www.example.com 时,DNS 会根据负载均衡策略(如轮询、就近访问、健康检查)将流量分发到多个 CLB 实例。
    • 这种方式不仅可以分散流量,还可以在某个 CLB 实例出现故障时,自动将流量引导到其他健康的 CLB 实例上,实现高可用。

但是如果我们使用dns解析来配合多个clb实现负载均衡 还是有一定局限性的:

问题分析:DNS 解析的局限性

  • 被动健康检查
    • DNS 的解析记录更新需要时间(TTL),即使某个 CLB 实例出现故障,DNS 也无法立即感知和做出反应,依然会将请求分发到已经失效的 CLB 实例。
    • 在大多数情况下,DNS 无法实时检测到某个记录是否有效,因此当一个 CLB 实例发生故障时,可能会导致部分用户的请求失败。
  • 延迟与缓存问题
    • 由于 DNS 缓存机制的存在,即便 DNS 记录已更新为其他健康的 CLB 实例,客户端的 DNS 缓存可能仍然存在过期的记录,这会导致用户无法正常访问。

最佳解决方案:多级负载架构

为了提高整体架构的可靠性和实时性,我们可以使用多级负载均衡架构 ,即在多个 CLB 实例前再增加额外的负载均衡层,从而实现一级和二级负载均衡

多级负载架构设计

  1. 一级负载均衡:顶层负载(全局流量管理)
    • 在多个 CLB 实例前使用一个全局流量管理服务,如阿里云的 全局流量管理(GTM) ,来智能调度流量。
    • GTM 可以根据用户的地理位置、服务健康状况等进行智能化调度,将流量动态地分发到不同区域的 CLB 实例上。
  2. 二级负载均衡:区域内负载(多个 CLB 实例)
    • 在不同区域内部署多个 CLB 实例,每个 CLB 实例负责分发该区域内的流量。
    • CLB 实例后端连接多个 ECS 服务器,通过标准的负载均衡算法(如加权轮询、最少连接等)进行流量分发。

优势分析

  • 主动健康检查
    • 顶层的 GTM 服务可以主动对多个 CLB 实例进行健康检查,并根据检查结果将流量引导至健康的 CLB 实例,避免因 DNS 被动监测带来的延迟问题。
  • 高可用性和容灾能力
    • 如果某个 CLB 实例出现故障,GTM 可以迅速将流量切换到其他健康的 CLB 实例,无需依赖 DNS 缓存更新的过程,实现更快速的故障转移。
    • 在某个区域发生灾难时,其他区域的 CLB 实例依然可以提供服务,保证系统的高可用性。
  • 智能流量调度
    • 顶层 GTM 可以根据用户地理位置或网络延迟等因素,将用户请求定向到最适合的 CLB 实例,从而提升用户体验。

示例架构流程

  1. 用户请求
    • 用户访问 www.example.com,请求首先到达 GTM 服务,GTM 会根据地理位置、健康状况、负载情况等将流量分发到合适的 CLB 实例。
  2. 一级负载均衡
    • GTM 对多个 CLB 实例进行主动健康检查,确保将流量分发给状态良好的实例。
  3. 二级负载均衡
    • 每个 CLB 实例再通过内部的负载均衡算法,将请求分发到多个 ECS 服务器上处理。

总结

  • 使用 DNS 解析实现多个 CLB 实例之间的负载均衡,虽然能够在一定程度上提升高可用性和容灾能力,但仍然存在被动健康检查DNS 缓存延迟的问题,导致故障响应不及时。
  • 最佳实践是采用多级负载均衡架构 ,即通过在多个 CLB 实例前加上顶层的全局流量管理(GTM) ,以实现主动健康检查智能化流量调度 ,从而进一步提高系统的可靠性高可用性

这种多级架构设计结合了GTM 的智能调度CLB 的高效分发 ,可以有效地解决单层架构的不足之处,尤其是在面对大规模高并发业务流量动态变化的场景中,能够保障系统的稳定运行和用户的良好体验。


7. 访问控制

在负载均衡器前端有多台服务器处理用户请求,由于请求被均衡分发到不同的后端服务器上,因此需要确保所有服务器具有一致的访问控制策略。访问控制的目标是避免恶意请求对系统造成过载,并限制特定用户组或 IP 的访问权限,确保服务的稳定性和安全性。

解决方案概述

负载均衡环境下的访问控制可以通过以下几种方式实现:

  1. 基于 Nginx 配置的访问控制
  2. 使用阿里云 CLB 的访问控制策略
  3. 结合 Web 应用防火墙(WAF)进行访问控制
  4. 自定义访问控制逻辑,例如基于 Token 的认证方案

解决方案 1:基于 Nginx 配置的访问控制

Nginx 作为负载均衡器时,可以通过其内置模块进行访问控制,主要方式包括基于 IP 地址的黑白名单、限速限流等。

1.1 基于 IP 的黑白名单

可以使用 allowdeny 指令来设置允许或拒绝的 IP 地址范围,从而实现对请求的访问控制。

示例配置

nginx 复制代码
server {
    listen 80;
    server_name www.example.com;

    # 基于 IP 地址的访问控制
    location / {
        # 允许特定的 IP 地址访问
        allow 192.168.1.0/24;
        allow 10.0.0.0/16;

        # 拒绝所有其他 IP 地址
        deny all;

        proxy_pass http://backend;
    }
}
  • allow 指令:允许指定 IP 地址或网段的请求。
  • deny 指令:拒绝所有其他的请求。

1.2 限速限流控制

Nginx 可以通过 limit_reqlimit_conn 模块来对请求进行限速限流控制,防止单个 IP 或恶意用户占用过多资源,影响其他用户的访问。

示例配置

nginx 复制代码
http {
    # 定义限流区域,每秒只允许一个请求
    limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

    server {
        listen 80;
        server_name www.example.com;

        location / {
            # 应用限流区域
            limit_req zone=one burst=5;
            proxy_pass http://backend;
        }
    }
}
  • limit_req_zone:定义限流的规则,基于客户端 IP 地址进行限流。
  • limit_req :应用限流区域,同时允许一些突发请求(burst=5),超出突发请求的请求将被限速处理。

解决方案 2:使用阿里云 CLB 的访问控制策略

阿里云的 CLB(云负载均衡) 提供了访问控制列表(ACL)的功能,可以定义允许或拒绝访问 CLB 实例的 IP 地址或网段,从而在负载均衡层实现访问控制。

阿里云 CLB 访问控制配置步骤

  1. 登录阿里云控制台

  2. 选择负载均衡实例

    • 在控制台中选择 负载均衡 服务,找到要配置的 CLB 实例。
  3. 创建访问控制列表(ACL)

    • 访问控制列表 中创建一个新的 ACL,添加我们希望允许或拒绝的 IP 地址或 IP 段。
    • ACL 支持 白名单模式 (只允许列表中的 IP 访问)或 黑名单模式(拒绝列表中的 IP 访问)。
  4. 应用 ACL 到监听器

    • 将 ACL 关联到负载均衡的监听器上。

    • 通过 ACL 可以控制进入 CLB 的流量,确保只有符合策略的请求才会被转发到后端服务器。

优势

  • 灵活管理:ACL 可以在控制台中灵活管理,不需要直接修改服务器配置。
  • 适用场景广:适用于大规模的云环境,可以集中管理多个负载均衡实例的访问控制策略。

解决方案 3:结合 Web 应用防火墙(WAF)进行访问控制

Web 应用防火墙(WAF) 是专门用来保护 Web 应用的安全设备,可以通过 WAF 实现更复杂的访问控制策略,例如防止 SQL 注入、XSS 攻击、DDOS 攻击等。

如何与负载均衡器结合使用

  1. 部署 WAF
    • 将 WAF 部署在负载均衡器和后端服务器之间,或者将 WAF 与 CLB 结合使用(阿里云也提供了 WAF 服务)。
  2. 配置 WAF 策略
    • 设置 WAF 的访问控制规则,例如基于地理位置、请求的内容、用户行为等。
    • WAF 可以在应用层上过滤恶意请求,确保只有合法的流量才能通过负载均衡器到达后端服务器。
  3. 集成日志和监控
    • WAF 通常集成了日志和监控功能,能够对异常请求进行告警,便于管理员及时响应。

优势

  • 更全面的安全防护:WAF 可以防止多种常见的 Web 攻击,保护 Web 应用的安全。
  • 适用于复杂的业务场景:适合需要处理大量恶意攻击请求、确保应用安全的场景。

解决方案 4:自定义访问控制逻辑(基于 Token 或身份验证)

通过在应用层自定义访问控制逻辑,例如使用 Token、OAuth 认证、JWT 等身份验证机制,可以实现更细粒度的访问控制。这种方式不依赖于负载均衡器,而是由应用层来控制用户的访问权限。

基于 Token 的认证方案

  1. 用户登录
    • 用户登录时,应用服务器生成一个唯一的 Token 并返回给用户。
    • 该 Token 会附加在每次请求的头部,客户端每次请求时都需要提供 Token。
  2. 服务器验证 Token
    • 后端服务器在每次接收到请求时,都会验证 Token 的有效性(可以通过 Redis 或数据库来验证)。
    • 如果 Token 无效或已过期,则拒绝请求,要求用户重新登录。
  3. 与负载均衡器结合
    • 使用这种方法可以确保所有请求在经过负载均衡器分发到任意服务器后,均能正确验证请求的合法性。
    • 所有服务器共享会话数据或使用 Redis 统一管理会话,可以确保分布式环境下的访问控制一致性。

优势和局限性

  • 优势
    • 细粒度的控制:可以控制具体的用户和操作,支持更复杂的权限管理。
    • 高安全性:结合 SSL/TLS 和安全的 Token 机制,可以有效地保护用户数据。
  • 局限性
    • 复杂性增加:需要在应用代码中增加身份验证逻辑,且需要管理 Token 的生命周期。
8.日志与监控

在负载均衡环境中,由于请求被分发到多个后端服务器,因此需要对每个请求进行追踪、记录负载均衡器和后端服务器的性能指标,以及进行日志采集和分析,以快速定位系统中的问题,尤其是在某台后端服务器出现问题时能够快速识别。

解决方案概述

日志和监控是负载均衡系统中不可缺少的一部分。通过日志采集和监控,可以实现以下目标:

  1. 监控负载均衡器的性能指标(如请求量、连接数、健康检查状态)。
  2. 采集访问日志和错误日志,用于问题排查和性能分析。
  3. 快速定位故障服务器,从而缩短故障排除时间,提高系统可用性。

针对这一需求,以下是两个具体的解决方案:

  1. Nginx 日志与监控解决方案 :使用 Nginx 日志配置结合 ELK(Elasticsearch、Logstash、Kibana)进行日志采集和分析。
  2. 阿里云 CLB 解决方案:结合阿里云的监控服务(如云监控和日志服务)对 CLB 实例进行性能监控和日志分析。

解决方案 1:Nginx 日志与监控解决方案

Nginx 可以作为负载均衡器,通过配置访问日志和错误日志,将日志数据存储到文件中,再结合 ELK(Elasticsearch、Logstash、Kibana)进行集中化的日志收集和分析。

1.1 Nginx 日志配置

访问日志配置 : 在 Nginx 配置文件中,可以通过 access_log 指令来配置访问日志,以记录每个请求的详细信息。

nginx 复制代码
http {
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$request_time" "$upstream_addr"';

    access_log /var/log/nginx/access.log main;

    server {
        listen 80;
        server_name www.example.com;

        location / {
            proxy_pass http://backend;
        }
    }
}
  • log_format main:定义了日志的格式,包括客户端 IP 地址、请求时间、响应状态码、后端服务器地址等。
  • access_log:定义了访问日志文件的存储路径,日志将记录所有进入 Nginx 的请求。

错误日志配置 : 通过 error_log 指令配置错误日志。

nginx 复制代码
error_log /var/log/nginx/error.log warn;
  • error_log :记录 Nginx 进程和后端服务器的错误日志,级别可以是 debuginfonoticewarnerror 等。

1.2 集成 ELK 进行日志分析

将 Nginx 产生的日志数据集中收集到 ELK,进行实时分析和可视化。

  • Logstash :用于收集和过滤 Nginx 的日志,并将日志发送到 Elasticsearch。
    • 配置 Logstash 收集 /var/log/nginx/access.log/var/log/nginx/error.log,将日志发送到 Elasticsearch。
  • Elasticsearch:用于存储和索引日志数据,以便于快速搜索。
  • Kibana:用于可视化展示 Elasticsearch 中存储的数据,生成实时的监控图表。

1.3 如何快速定位问题

通过 ELK 的可视化界面(Kibana),我们可以:

  1. 查看请求统计图,了解系统流量趋势。
  2. 实时搜索特定请求日志,查看某个用户或某个 IP 的请求历史。
  3. 过滤错误日志,查找最近的错误请求并确定是哪台服务器返回的错误状态。

借助 Kibana,可以快速查看特定时间段内,哪些后端服务器返回了错误状态,从而快速定位故障服务器。

解决方案 2:阿里云 CLB 解决方案

阿里云 CLB(云负载均衡) 提供了内置的监控和日志服务,可以帮助我们实时监控负载均衡的性能以及后端服务器的健康状况。

2.1 阿里云监控服务

阿里云的 云监控服务 可以对 CLB 的多个指标进行监控,包括:

  • 流量:实时监控 CLB 的流入和流出流量。
  • 连接数:查看并发连接数、活跃连接数等,评估系统的负载。
  • 健康检查状态:查看后端服务器的健康状态,确定哪些服务器状态异常。

步骤

  1. 登录阿里云控制台,进入 云监控 -> 负载均衡 页面。
  2. 选择负载均衡实例,查看其流量、连接数和健康状态。
  3. 可以设置告警规则,当某些指标(如连接数过高或健康检查失败)触发时,系统会发送告警通知,以便快速响应。

2.2 阿里云日志服务

阿里云的 日志服务 可以收集 CLB 的访问日志,帮助分析请求来源、请求路径、错误率等。

配置步骤

  1. 开启 CLB 日志采集
    • 登录阿里云控制台,进入负载均衡实例的详情页面。
    • 选择监听器,开启日志采集功能,将日志发送到日志服务。
  2. 分析日志
    • 日志服务 控制台中,可以查看每个请求的详细记录,包括请求来源、请求路径、后端服务器的响应状态等。
    • 通过过滤请求状态,可以快速找到错误请求以及请求是由哪台后端服务器处理的。

2.3 如何快速定位问题

  • 健康检查:通过健康检查状态实时监控后端服务器的健康状况,快速识别状态异常的服务器。
  • 日志服务:通过阿里云日志服务,可以快速搜索到请求的路径、来源 IP、响应状态,帮助判断是哪个后端服务器在处理请求时出现了问题。

通过阿里云的监控服务结合日志采集,能够快速定位到具体的后端服务器发生的异常,从而及时进行修复和优化。

解决方案对比

解决方案 优势 劣势
Nginx + ELK 实时日志分析、灵活配置、可视化监控,适用于自建部署 需要部署和维护 ELK 集群,复杂度较高
阿里云 CLB + 日志服务 云服务一键配置、集中管理、健康检查、自动告警 依赖云厂商服务,有成本;灵活性相对有限

解决方案选择建议

  • 小规模自建服务器:如果系统规模较小,并且已经在使用 Nginx 作为负载均衡器,推荐使用 Nginx 日志结合 ELK 进行日志监控。这种方案灵活且可自定义各种分析规则。
  • 大规模云部署:如果是使用阿里云 CLB,推荐直接使用阿里云的监控服务和日志服务。这种方案集成度高、操作简单,适合需要快速实现监控和告警的场景。

同城双/多中心

随着我们项目业务规模的不断扩大和用户对服务可用性要求的提高,传统的单一数据中心架构在面对硬件故障、网络中断、自然灾害等情况下,难以保证服务的持续稳定,甚至可能导致业务中断和数据丢失。尤其在高并发、高可用性需求下,如何应对单点故障、如何确保业务的持续运行成为我们设计系统架构设计的关键问题。因此,为了解决这些问题,我们可以考虑部署同城双中心同城多中心架构。

既然写负载均衡了 就了解下这个架构吧 我实际项目中也没有用到过,可能项目规模不够大。

同城双中心

同城双中心(Active-Active 或 Active-Standby)是指在同一城市内建立两个数据中心,这两个数据中心通过高带宽、低延迟的链路相连,并互为备份,从而实现高可用性和业务连续性。

  • Active-Active 模式
    • 描述:两个数据中心同时在线并处理业务流量,通过负载均衡器将流量均衡分发到两个数据中心。
    • 解决问题:在一个中心发生故障时,另一个中心可以立即承担全部业务,确保服务不中断。这种模式提高了系统的资源利用率,适合需要同时处理大规模流量的场景。
  • Active-Standby 模式
    • 描述:一个数据中心在线处理业务,另一个数据中心作为热备份。当主数据中心发生故障时,备用数据中心会迅速接管所有业务。
    • 解决问题:该模式通过备用中心来保证高可用性,适合对系统稳定性要求高但流量较为平稳的场景。

适用场景

  • 适用于对高可用性要求极高的业务场景,例如金融、电商、在线教育等需要确保业务持续性和数据安全的系统。
  • 双中心的设计可以确保当一个数据中心由于硬件、网络或其他因素导致不可用时,另一个中心能够及时接管,从而实现业务的无缝切换和持续运行。
同城多中心

同城多中心(Multi-Center)是指在同一城市中部署多个数据中心,以提供更高的容错能力和更好的负载分担能力。相比于同城双中心,多中心架构能够实现更多的数据冗余和业务分区。

  • 业务分区与扩展
    • 描述:在同城多中心架构中,不同的数据中心可以承载不同的业务模块或业务分区。通过负载均衡器实现跨数据中心的流量调度,避免某个中心的过载。
    • 解决问题:这种方式确保业务能够被灵活分配到多个数据中心,适用于业务模块多样化、大规模并发的场景,确保每个中心都有明确的职责分工,同时具备跨中心的冗余备份能力。
  • 分层冗余
    • 描述:各个数据中心之间相互备份,任何一个中心出现故障,其它中心可以部分或完全接管其业务,从而确保系统的高可用性。
    • 解决问题:通过多中心互为冗余设计,进一步提升系统的容灾能力,尤其是在应对自然灾害、硬件失效等不可控因素时,可以确保业务的平稳运行。

适用场景

  • 适用于大规模并发应用、社交网络等需要高弹性和高容错能力的系统。
  • 多中心架构可以有效地将流量均匀分布在不同的中心,以应对流量的波动,同时保证在某个中心失效时,业务不会受到显著影响。
负载均衡在同城双中心和多中心中的作用

在同城双中心和多中心架构中,负载均衡器是实现流量智能调度、故障自动切换的关键组件。其作用主要包括:

  • 流量智能调度:负载均衡器根据不同的策略(例如基于健康检查、地理位置等)将流量分配到不同的数据中心,不仅提升了系统的整体处理能力,还能平衡各中心之间的负载。
  • 故障自动切换:当某个数据中心出现故障时,负载均衡器能够自动将流量切换到其他可用的数据中心,确保服务的持续可用性,避免业务中断。

总结建议 : 在现代互联网架构中,特别是对于高并发的 C 端产品,高可用性和快速恢复能力是系统设计的重点。通过采用同城双中心 或者同城多中心 架构,结合云产品的负载均衡与监控服务,能够大大提高系统的容灾能力和业务连续性。在集群负载均衡搭建上,能上云就不手动,使用云产品结合高可用架构设计,减少手动运维的复杂性和不可控风险,从而实现系统的更高稳定性和更好用户体验。


最后

上面我简单用 Nginx 和阿里云的负载均衡服务来搭建了一个简单的负载均衡示例,其实搭建负载均衡本身并不复杂。最主要的问题在于集群服务器的链路跟踪,以及我们上面提到的在负载均衡架构下可能会遇到的各种问题。

根据我之前接触的公司情况,大多数项目集群搭建负载均衡已经很少手动使用 Nginx 了。使用 Nginx 手动搭建负载均衡虽然简单,但是在维护和链路分析方面确实非常麻烦,特别是在高并发、复杂业务逻辑的场景下,一旦出现问题,追踪具体节点、分析故障源非常耗时且困难。而通过云产品(例如阿里云负载均衡)结合云监控、链路追踪、日志分析等整套监控工具,能够极大地简化维护难度,同时在出现问题时可以快速定位到问题服务器并进行恢复,大大提高了问题解决的效率和系统的稳定性。

因此,如果项目中用到集群,需要搭建负载均衡的场景,能上云就不要手动搭建。因为发现一个问题就可能会带来十个连锁问题,而云产品提供了更好的可视化管理和一整套解决方案,可以显著减少维护的复杂性。

最后 希望项目用到集群 需要搭建负载均衡的话。能上云就不手动 否则可能会导致发现一个问题就会出现一次损失 自动化挺好。

相关推荐
bug_null21 分钟前
RabbitMQ消息可靠性保证机制7--可靠性分析-rabbitmq_tracing插件
分布式·rabbitmq
kingbal22 分钟前
RabbitMQ:添加virtualHost
分布式·rabbitmq
AI人H哥会Java1 小时前
【Spring】Spring的模块架构与生态圈—Spring MVC与Spring WebFlux
java·开发语言·后端·spring·架构
小屁不止是运维1 小时前
麒麟操作系统服务架构保姆级教程(二)ssh远程连接
linux·运维·服务器·学习·架构·ssh
小马爱打代码1 小时前
SpringCloud(注册中心+OpenFeign+网关+配置中心+服务保护+分布式事务)
分布式·spring·spring cloud
毕设资源大全1 小时前
基于SpringBoot+html+vue实现的林业产品推荐系统【源码+文档+数据库文件+包部署成功+答疑解惑问到会为止】
java·数据库·vue.js·spring boot·后端·mysql·html
Watermelon_Mr1 小时前
Spring(三)-SpringWeb-概述、特点、搭建、运行流程、组件、接受请求、获取请求数据、特殊处理、拦截器
java·后端·spring
eternal__day2 小时前
数据结构十大排序之(冒泡,快排,并归)
java·数据结构·算法
gavin_gxh3 小时前
SAP PP ECN CSAP_MAT_BOM_MAINTAIN
运维·经验分享·其他
BUG研究员_3 小时前
LoadBalancer负载均衡和Nginx负载均衡区别理解
nginx·rpc·负载均衡