27-高性能负载均衡集群

以下为你展示几种不同类型高性能负载均衡集群的图示及简要说明,我将使用 Mermaid 代码来生成架构图。

1. 基于硬件负载均衡器的 Web 服务器集群

此架构使用硬件负载均衡器(如 F5 Big - IP)将用户请求分发到多个 Web 服务器,Web 服务器共享后端数据库。

graph LR
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px

    A(用户请求):::process --> B(硬件负载均衡器):::process
    B --> C1(Web 服务器 1):::process
    B --> C2(Web 服务器 2):::process
    B --> C3(Web 服务器 3):::process
    C1 --> D(数据库):::process
    C2 --> D(数据库):::process
    C3 --> D(数据库):::process

说明

  • 用户的请求首先到达硬件负载均衡器,它根据预设的算法(如轮询、最少连接数等)将请求分发到不同的 Web 服务器上。
  • 各个 Web 服务器处理请求,并根据需要从数据库中读取或写入数据。

2. 多级负载均衡集群架构

这种架构采用两级负载均衡,第一级负载均衡器负责将请求分发到多个第二级负载均衡器,第二级负载均衡器再将请求分发给具体的应用服务器。

graph LR
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px

    A(用户请求):::process --> B(一级负载均衡器):::process
    B --> C1(二级负载均衡器 1):::process
    B --> C2(二级负载均衡器 2):::process
    C1 --> D1(应用服务器 1):::process
    C1 --> D2(应用服务器 2):::process
    C2 --> D3(应用服务器 3):::process
    C2 --> D4(应用服务器 4):::process
    D1 --> E(数据库):::process
    D2 --> E(数据库):::process
    D3 --> E(数据库):::process
    D4 --> E(数据库):::process

说明

  • 一级负载均衡器作为入口,将大量的用户请求分散到多个二级负载均衡器,减轻单个二级负载均衡器的压力。
  • 二级负载均衡器进一步将请求分发到具体的应用服务器,提高整个系统的并发处理能力。
  • 所有应用服务器共享后端数据库。

3. 包含缓存和分布式存储的负载均衡集群

在这个架构中,引入了缓存(如 Redis)和分布式存储(如 Ceph)来提升系统性能和数据存储能力。

graph LR
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px

    A(用户请求):::process --> B(负载均衡器):::process
    B --> C1(Web 服务器 1):::process
    B --> C2(Web 服务器 2):::process
    C1 --> D(Redis 缓存):::process
    C2 --> D(Redis 缓存):::process
    D -->|缓存命中| C1
    D -->|缓存命中| C2
    C1 --> E(Ceph 分布式存储):::process
    C2 --> E(Ceph 分布式存储):::process
    C1 --> F(数据库):::process
    C2 --> F(数据库):::process

说明

  • 用户请求通过负载均衡器分发到 Web 服务器。
  • Web 服务器在处理请求时,首先检查 Redis 缓存中是否存在所需数据,如果缓存命中则直接返回,减少对数据库的访问压力。
  • 对于静态资源或大文件,Web 服务器会从 Ceph 分布式存储中读取。
  • 如果缓存未命中,Web 服务器会从数据库中获取数据。

集群是什么

集群的定义

在 Linux 运维中,集群是一组相互连接的计算机(节点),它们通过网络协作,作为一个统一的系统来提供服务或执行任务。集群的主要目标是提升系统的可用性、可扩展性和性能。以下将从不同类型的集群展开介绍并给出 mermaid 图解。

高可用性集群(High Availability Cluster)

原理

高可用性集群旨在确保服务的持续运行。通过心跳机制监控节点状态,当某个节点出现故障时,备用节点会迅速接管其工作,保证服务不中断。

mermaid 代码

graph LR
    classDef node fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px
    classDef storage fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px
    classDef network fill:#FFEBEB,stroke:#E68994,stroke-width:2px

    A([Active Node]):::node <-->|Heartbeat| B([Standby Node]):::node
    A -->|Access| C([Shared Storage]):::storage
    B -->|Access| C
    D(Users):::node -->|Requests| A
    style D fill:#ffffff,stroke:#000000,stroke-width:1px

解释

  • 有两个节点:Active Node(活动节点)和 Standby Node(备用节点)。
  • 它们之间通过 Heartbeat(心跳)连接,用于监测彼此状态。
  • 两个节点都可以访问 Shared Storage(共享存储),保证数据一致性。
  • 用户的请求首先发送到 Active Node,当该节点故障时,Standby Node 会接管服务。

负载均衡集群(Load Balancing Cluster)

原理

负载均衡集群将用户请求均匀分配到多个节点上,避免单个节点负载过高,提升系统整体性能和响应速度。负载均衡器依据特定算法(如轮询、加权轮询等)进行请求分配。

mermaid 代码

graph LR
    classDef lb fill:#FFEBEB,stroke:#E68994,stroke-width:2px
    classDef node fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px

    A([Load Balancer]):::lb --> B([Node 1]):::node
    A --> C([Node 2]):::node
    A --> D([Node 3]):::node
    E(Users):::node -->|Requests| A
    style E fill:#ffffff,stroke:#000000,stroke-width:1px

解释

  • 用户的请求首先到达 Load Balancer(负载均衡器)。
  • 负载均衡器将请求分配给 Node 1Node 2Node 3 中的一个进行处理。
  • 通过这种方式,各个节点的负载得以平衡,提高系统处理能力。

高性能计算集群(High Performance Computing Cluster)

原理

高性能计算集群用于解决复杂的科学计算和工程问题。多个计算节点通过高速网络连接,协同并行处理大型计算任务,以提升计算能力。

mermaid 代码

graph LR
    classDef node fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px
    classDef head fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px

    A([Compute Node 1]):::node <-->|High - speed Network| B([Compute Node 2]):::node
    A <-->|High - speed Network| C([Compute Node 3]):::node
    B <-->|High - speed Network| C
    D([Head Node]):::head -->|Task Distribution| A
    D -->|Task Distribution| B
    D -->|Task Distribution| C
    E(Users):::node -->|Submit Tasks| D
    style E fill:#ffffff,stroke:#000000,stroke-width:1px

解释

  • Compute Node 1Compute Node 2Compute Node 3 是计算节点,它们通过高速网络相互连接。
  • Head Node(头节点)负责接收用户提交的任务,并将任务分配给各个计算节点。
  • 计算节点完成任务后,将结果反馈给 Head Node 进行汇总处理。

综合架构

简单地说,集群就是指一组(若干个)相互独立的计算机,利用高速通信网络组成的一个较大的计算机服务系统,每个集群节点(即集群中的每台计算机)都是运行各自服务的独立服务器。

这些服务器之间可以彼此通信,协同向用户提供应用程序,系统资源和数据,并以单一系统的模式加以管理。

当用户请求集群系统时,集群给用户的感觉就是一个单一独立的服务器,而实际上用户请求的是一组集群服务器。

举个例子:

打开谷歌,百度的页面,看起来好简单,也许你觉得用几分钟就可以制作出相似的网页,而实际上,这个页面的背后是由成千上万台服务器集群协同工作的结果。

若要用一句话描述集群,即一堆服务器合作做同一件事,这些机器可能需要统一协调管理,可以分布在一个机房,也可以分布在全国全球各个地区的多个机房。

和传统的高性能计算机技术相比,集群技术可以利用各档次的服务器作为节点,系统造价低,可以实现很高的运算速度,完成大运算量的计算,具有较高的响应能力,能够满足当今日益增长的信息服务的需求。

集群技术是一种通用的技术,其目的是为了解决单机运算能力的不足、IO能力的不足、提高服务的可靠性、获得规模可扩展能力,降低整体方案的运维成本(运行、升级、维护成本)。

只要在其他技术不能达到以上的目的,或者虽然能够达到以上的目的,但是成本过高的情况下,就可以考虑采用集群技术。

简单说就是

集群是一堆服务器在一起干活,提供如网站功能。

为什么要集群

为什么要使用集群

在 Linux 运维中,使用集群主要是为了实现高可用性、提升性能和可扩展性,下面通过 mermaid 图详细解释原因。

1. 高可用性(High Availability)

  • 原因:在实际生产环境中,单个服务器可能会因为硬件故障、软件崩溃、电力中断等原因而停止工作,这会导致服务中断,给业务带来巨大损失。通过构建高可用性集群,当某个节点出现故障时,其他节点可以迅速接管其工作,保证服务的持续运行。
  • mermaid 代码

    graph LR
      classDef node fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px
      classDef storage fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px
      classDef network fill:#FFEBEB,stroke:#E68994,stroke-width:2px
    
      A([Node 1]):::node <-->|Heartbeat| B([Node 2]):::node
      A -->|Access| C([Shared Storage]):::storage
      B -->|Access| C
      D(Users):::node -->|Requests| A
      style D fill:#ffffff,stroke:#000000,stroke-width:1px
    
      subgraph Normal Operation
          A -.->|Serving| D
      end
    
      subgraph Failure Scenario
          A -.->|Failed| x([Failure]):::network
          B -.->|Takeover| D
      end
    
  • 解释
    • 在正常运行时,Node 1 为用户提供服务。Node 1Node 2 通过心跳机制相互监测状态,并且都可以访问共享存储。
    • Node 1 出现故障时,Node 2 检测到心跳丢失,会迅速接管 Node 1 的工作,继续为用户提供服务,从而保证了服务的高可用性。

2. 性能提升(Performance Improvement)

  • 原因:随着业务的发展,用户请求量不断增加,单个服务器的处理能力可能无法满足需求。负载均衡集群可以将用户的请求均匀地分配到多个节点上,充分利用集群中各个节点的资源,从而提高系统的整体性能和响应速度。
  • mermaid 代码

    graph LR
      classDef lb fill:#FFEBEB,stroke:#E68994,stroke-width:2px
      classDef node fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px
    
      A([Load Balancer]):::lb --> B([Node 1]):::node
      A --> C([Node 2]):::node
      A --> D([Node 3]):::node
      E(Users):::node -->|Requests| A
      style E fill:#ffffff,stroke:#000000,stroke-width:1px
    
      subgraph Single Server
          F([Single Server]):::node -->|Limited Capacity| G([Slow Response]):::network
      end
    
      subgraph Load Balanced Cluster
          E -->|Distributed Requests| A
          A -->|Balanced| B
          A -->|Balanced| C
          A -->|Balanced| D
          B -.->|Process| E
          C -.->|Process| E
          D -.->|Process| E
      end
    
  • 解释
    • 单个服务器的处理能力有限,当面对大量用户请求时,容易出现响应缓慢的问题。
    • 而在负载均衡集群中,负载均衡器将用户请求均匀地分配到 Node 1Node 2Node 3 上,各个节点并行处理请求,从而提高了系统的整体性能和响应速度。

3. 可扩展性(Scalability)

  • 原因:随着业务的增长,需要不断增加系统的处理能力。集群具有良好的可扩展性,可以通过添加新的节点来满足业务增长的需求,而不需要对整个系统进行大规模的改造。
  • mermaid 代码

    graph LR
      classDef lb fill:#FFEBEB,stroke:#E68994,stroke-width:2px
      classDef node fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px
    
      A([Load Balancer]):::lb --> B([Node 1]):::node
      A --> C([Node 2]):::node
      E(Users):::node -->|Requests| A
      style E fill:#ffffff,stroke:#000000,stroke-width:1px
    
      subgraph Initial Cluster
          A --> B
          A --> C
      end
    
      subgraph Expansion
          A --> D([New Node]):::node
      end
    
  • 解释
    • 初始的集群由 Node 1Node 2 组成,负载均衡器将用户请求分配到这两个节点上。
    • 当业务需求增加时,可以方便地添加新的节点(如 New Node)到集群中,负载均衡器会自动将请求分配到新节点上,实现系统的扩展。

高性能

一些国家重要的计算密集型应用(如天气预报,核试验模拟等),需要计算机有很强的运算处理能力。以全世界现有的技术,即使是大型机,其计算能力也是有限的,很难单独完成此任务。

因为计算时间可能会相当长,也许几天,甚至几年或更久。

因此,对于这类复杂的计算业务,便使用了计算机集群技术,集中几十上百台,甚至成千上万台计算机进行计算。

假如你配一个LNMP环境,每次只需要服务10个并发请求,那么单台服务器一定会比多个服务器集群要快。

只有当并发或总请求数量超过单台服务器的承受能力时,服务器集群才会体现出优势。

价格有效性

通常一套系统集群架构,只需要几台或数十台服务器主机即可。与动辄价值上百万元的专用超级计算机相比便宜了很多。在达到同样性能需求的条件下,采用计算机集群架构比采用同等运算能力的大型计算机具有更高的性价比。

早期的淘宝,支付宝的数据库等核心系统就是使用上百万元的小型机服务器。

后因使用维护成本太高以及扩展设备费用成几何级数翻倍,甚至成为扩展瓶颈,人员维护也十分困难,最终使用PC服务器集群替换之,比如,把数据库系统从小机结合Oracle数据库迁移到MySQL开源数据库结合PC服务器上来。

不但成本下降了,扩展和维护也更容易了。

可伸缩性

当服务负载,压力增长时,针对集群系统进行较简单的扩展即可满足需求,且不会降低服务质量。

通常情况下,硬件设备若想扩展性能,不得不增加新的CPU和存储器设备,如果加不上去了,就不得不购买更高性能的服务器,就拿我们现在的服务器来讲,可以增加的设备总是有限的。

如果采用集群技术,则只需要将新的单个服务器加入现有集群架构中即可,从访问的客户角度来看,系统服务无论是连续性还是性能上都几乎没有变化,系统在不知不觉中完成了升级,加大了访问能力,轻松地实现了扩展。

集群系统中的节点数目可以增长到几千乃至上万个,其伸缩性远超过单台超级计算机。

高可用性

单一的计算机系统总会面临设备损毁的问题,如CPU,内存,主板,电源,硬盘等,只要一个部件坏掉,这个计算机系统就可能会宕机,无法正常提供服务。在集群系统中,尽管部分硬件和软件也还是会发生故障,但整个系统的服务可以是7*24小时可用的。

集群架构技术可以使得系统在若干硬件设备故障发生时仍可以继续工作,这样就将系统的停机时间减少到了最小。

集群系统在提高系统可靠性的同时,也大大减小了系统故障带来的业务损失,目前几乎100%的互联网网站都要求7*24小时提供服务。

透明性

多个独立计算机组成的松耦合集群系统构成一个虚拟服务器。

用户或客户端程序访问集群系统时,就像访问一台高性能,高可用的服务器一样,集群中一部分服务器的上线,下线不会中断整个系统服务,这对用户也是透明的。

可管理性

整个系统可能在物理上很大,但其实容易管理,就像管理一个单一映像系统一样。在理想状况下,软硬件模块的插入能做到即插即用。

可编程性

在集群系统上,容易开发及修改各类应用程序。

集群分类

负载均衡集群和高可用性集群是互联网行业常用的集群架构模式,也是我们要学习的重点。

负载均衡集群

负载均衡集群为企业提供了更为实用,性价比更高的系统架构解决方案。

负载均衡集群可以把很多客户集中的访问请求负载压力尽可能平均地分摊在计算机集群中处理。客户访问请求负载通常包括应用程序处理负载和网络流量负载。

这样的系统非常适合使用同一组应用程序为大量用户提供服务的模式,每个节点都可以承担一定的访问请求负载压力,并且可以实现访问请求在各节点之间动态分配,以实现负载均衡。

负载均衡集群运行时,一般是通过一个或多个前端负载均衡器将客户访问请求分发到后端的一组服务器上,从而达到整个系统的高性能和高可用性。一般高可用性集群和负载均衡集群会使用类似的技术,或同时具有高可用性与负载均衡的特点。

负载均衡集群的作用为:

  • 分摊用户访问请求及数据流量(负载均衡)

  • 保持业务连续性,即7*24小时服务(高可用性)。

  • 应用于Web及数据库等服务器的业务

典型支持负载均衡的开源软件,就是nginx。

image-20220514165457176

高可用性负载均衡集群

在集群中任意一个节点失效的情况下,该节点上的所有任务会自动转移到其他正常的节点上。

此过程并不影响整个集群的运行。

当集群中的一个节点系统发生故障时,运行着的集群服务会迅速作出反应,将该系统的服务分配到集群中其他正在工作的系统上运行。

考虑到计算机硬件和软件的容错性,高可用性集群的主要目的是使集群的整体服务尽可能可用。

如果高可用性集群中的主节点发生了故障,那么这段时间内将由备节点代替它。

备节点通常是主节点的镜像。当它代替主节点时,它可以完全接管主节点(包括IP地址及其他资源)提供服务,因此,使集群系统环境对于用户来说是一致的,即不会影响用户的访问。

高可用性集群使服务器系统的运行速度和响应速度会尽可能的快。他们经常利用在多台机器上运行的冗余节点和服务来相互跟踪。如果某个节点失败,它的替补者将在几秒钟或更短时间内接管它的职责。因此,对于用户而言,集群里的任意一台机器宕机,业务都不会受影响(理论情况下)。

高可用性集群的作用为:

  • 当一台机器宕机时,另外一台机器接管宕机的机器的IP资源和服务资源,提供服务。

  • 高可用性集群常用的开源软件包括Keepalived,Heartbeat等,其架构图如下图所示:

image-20220514165626109

企业常见LB软件、硬件

企业常见的负载均衡(LB)软件和硬件

在企业环境中,负载均衡起着至关重要的作用,它可以将流量均匀分配到多个服务器上,提高系统的可用性和性能。以下将介绍常见的负载均衡软件和硬件,并使用 mermaid 进行图解。

常见的负载均衡软件和硬件介绍

软件负载均衡
  • Nginx:一款轻量级的高性能 Web 服务器、反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在企业中广泛用于 HTTP 负载均衡。它具有高并发处理能力、低内存消耗等优点。
  • HAProxy:是一个使用 C 语言编写的自由及开放源代码软件,提供高可用性、负载均衡以及基于 TCP 和 HTTP 的应用程序代理。常用于 TCP 和 HTTP 负载均衡场景。
硬件负载均衡
  • F5 Big - IP:F5 Networks 公司的旗舰产品,是一款功能强大的硬件负载均衡器,具备高级的流量管理、应用交付和安全功能。适用于对性能和可靠性要求极高的大型企业。
  • Citrix ADC:Citrix 公司的应用交付控制器,提供负载均衡、应用加速、安全防护等功能,可优化企业应用的交付和性能。

mermaid 图解

graph LR
    classDef client fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px
    classDef lb fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px
    classDef server fill:#FFEBEB,stroke:#E68994,stroke-width:2px
    classDef software fill:#D5F5E3,stroke:#2ECC71,stroke-width:2px
    classDef hardware fill:#FDEBD0,stroke:#F39C12,stroke-width:2px

    A(Client):::client -->|Traffic| B(Load Balancer):::lb
    subgraph Load Balancer Types
        direction LR
        C(Nginx):::software
        D(HAProxy):::software
        E(F5 Big - IP):::hardware
        F(Citrix ADC):::hardware
    end
    B --> C
    B --> D
    B --> E
    B --> F
    C -->|Distribute| G(Server 1):::server
    C -->|Distribute| H(Server 2):::server
    D -->|Distribute| G
    D -->|Distribute| H
    E -->|Distribute| G
    E -->|Distribute| H
    F -->|Distribute| G
    F -->|Distribute| H

解释

  • 客户端(Client):代表企业的用户或外部系统,他们发起的请求流量会首先到达负载均衡器。
  • 负载均衡器(Load Balancer):是整个架构的核心,负责接收客户端的请求并将其分配到后端服务器上。
  • 负载均衡器类型
    • 软件负载均衡:包含 NginxHAProxy,它们以软件形式运行,可以部署在普通的服务器上,具有成本低、易于部署和配置的特点。
    • 硬件负载均衡:包含 F5 Big - IPCitrix ADC,它们是专门的硬件设备,性能强大、功能丰富,但成本相对较高。
  • 后端服务器(Server 1 和 Server 2):负责实际处理客户端的请求,负载均衡器会根据一定的算法(如轮询、加权轮询等)将请求分配到这些服务器上。

互联网公司常用的开源软件、nginx、lvs、haproxy、keepalived、heartbeat。

商业集群软件,有F5、Netscaler等。

商业LB硬件Netscaler

image-20220514170528992


image-20220514170546414


image-20220514170614238

https://www.citrix.com/content/dam/citrix/zh-cn/documents/products-solutions/netscaler-data-sheet.pdf

商业LB硬件F5

image-20220514170749586


image-20220514170805804


image-20220514170853114

软件、硬件对比

当企业业务重要,技术力量又薄弱,并且希望出钱购买产品及获取更好的服务时,可以选择硬件负载均衡产品,如F5,Netscaler,Radware等,此类公司多为传统的大型非互联网企业,如银行,证券,金融业及宝马,奔驰公司等

对于门户网站来说,大多会并用软件及硬件产品来分担单一产品的风险,如淘宝,腾讯,新浪等。融资了的企业会购买硬件产品,如赶集网等网站。

中小型互联网企业,由于起步阶段无利润可赚或者利润很低,会希望通过使用开源免费的方案来解决问题,因此会雇佣专门的运维人员进行维护。例如:51CTO等

相比较而言,商业的负载均衡产品成本高,性能好,更稳定,缺点是不能二次开发,开源的负载均衡软件对运维人员的能力要求较高,如果运维及开发能力强,那么开源的负载均衡软件是不错的选择,目前的互联网行业更倾向于使用开源的负载均衡软件。

开源LB软件选择

中小企业互联网公司网站在并发访问和总访问量不是很大的情况下,建议首选Nginx负载均衡

理由是Nginx负载均衡配置简单,使用方便,安全稳定,社区活跃,使用的人逐渐增多,成为流行趋势。

另外一个实现负载均衡的类似产品为Haproxy(支持L4和L7负载,同样优秀,但社区不如Nginx活跃)。

如果要考虑Nginx负载均衡的高可用功能,建议首选Keepalived软件,理由是安装和配置简单,使用方便,安全稳定,与Keepalived服务类似的高可用软件还有Heartbeat(使用比较复杂,并不建议初学者使用)

图解负载均衡

image-20220514171559564

正向代理

正向代理的概念

正向代理是一种位于客户端和目标服务器之间的代理服务器。客户端向正向代理发送请求,代理服务器接收到请求后,代替客户端向目标服务器发起请求,并将目标服务器的响应返回给客户端。正向代理主要用于隐藏客户端的真实 IP 地址,突破访问限制等。

mermaid 代码实现正向代理图解

graph LR
    classDef client fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px
    classDef proxy fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px
    classDef server fill:#FFEBEB,stroke:#E68994,stroke-width:2px

    A(Client):::client -->|Request with Proxy Configuration| B(Forward Proxy):::proxy
    B -->|Request on Behalf of Client| C(Target Server):::server
    C -->|Response| B
    B -->|Response to Client| A

图解解释

  1. 客户端(Client):发起请求的一方,通常是用户的浏览器或者其他应用程序。客户端需要进行正向代理的配置,将请求发送到正向代理服务器。
  2. 正向代理(Forward Proxy):接收客户端的请求,代替客户端向目标服务器发起请求。正向代理在请求过程中会隐藏客户端的真实 IP 地址,目标服务器只能看到正向代理的 IP 地址。
  3. 目标服务器(Target Server):接收正向代理发送的请求,并处理请求,将响应返回给正向代理。
  4. 请求与响应流程
    • 客户端向正向代理发送请求。
    • 正向代理接收到请求后,向目标服务器发起请求。
    • 目标服务器处理请求,并将响应返回给正向代理。
    • 正向代理将响应转发给客户端。

通过正向代理,客户端可以隐藏自己的真实身份,同时也可以突破一些访问限制,访问一些原本无法直接访问的资源。

正向代理(forward proxy):是一个位于客户端和目标服务器之间的服务器(代理服务器),为了从目标服务器取得内容,客户端向代理服务器发送一个请求并指定目标,然后代理服务器向目标服务器转交请求并将获得的内容返回给客户端。

这种代理其实在生活中是比较常见的,比如访问外国网站技术,其用到的就是代理技术。

有时候,用户想要访问某国外网站,该网站无法在国内直接访问,但是我们可以访问到一个代理服务器,这个代理服务器可以访问到这个国外网站。

这样呢,用户对该国外网站的访问就需要通过代理服务器来转发请求,并且该代理服务器也会将请求的响应再返回给用户。这个上网的过程就是用到了正向代理。

image-20220514174057665

所以正向代理,是proxy-server 代理了 client,然后与web服务器交互。

通过正向代理访问目标服务器,目标服务器就无法知道真正的client到底是谁。

用途

  • 通过代理服务器,突破client本身的ip访问限制,访问国外资源。
  • 隐藏client真实信息,可以保护client服务器,隐藏自己的ip,免受攻击。

反向代理

反向代理的概念

反向代理是一种代理服务器,它位于服务器端前面,客户端并不知道请求实际上是由反向代理转发到后端的真实服务器进行处理的。反向代理接收客户端的请求,然后根据一定的规则将请求转发到合适的后端服务器上,最后把后端服务器的响应返回给客户端。反向代理常用于负载均衡、安全防护、缓存等场景。

mermaid 代码实现反向代理图解

graph LR
    classDef client fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px
    classDef proxy fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px
    classDef server fill:#FFEBEB,stroke:#E68994,stroke-width:2px

    A(Client):::client -->|Request| B(Reverse Proxy):::proxy
    B -->|Forward Request| C(Backend Server 1):::server
    B -->|Forward Request| D(Backend Server 2):::server
    C -->|Response| B
    D -->|Response| B
    B -->|Return Response| A

图解解释

  1. 客户端(Client):可以是浏览器、移动应用等发起请求的终端。客户端向反向代理服务器发送请求,它并不知道后端具体有哪些服务器在处理请求。
  2. 反向代理(Reverse Proxy):作为客户端和后端服务器之间的中间层。它接收客户端的所有请求,并根据预设的规则(如负载均衡算法、URL 规则等)将请求转发到合适的后端服务器。同时,它还负责接收后端服务器的响应,并将响应返回给客户端。
  3. 后端服务器(Backend Server 1 和 Backend Server 2):真正处理业务逻辑的服务器。它们接收反向代理转发过来的请求,进行相应的处理,并将处理结果返回给反向代理。
  4. 请求与响应流程
    • 客户端向反向代理发送请求。
    • 反向代理根据规则将请求转发到后端服务器 1 或后端服务器 2。
    • 后端服务器处理请求后,将响应返回给反向代理。
    • 反向代理把响应返回给客户端。

反向代理的使用可以提高系统的性能、安全性和可扩展性。例如,通过负载均衡功能可以将请求均匀地分配到多个后端服务器上,避免单个服务器负载过高;同时,反向代理可以隐藏后端服务器的真实 IP 地址,起到一定的安全防护作用。

image-20220514172735343

反向代理(reverse proxy):是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。

1. client 访问 web-server,但是并不知道访问的其实是一个反向代理服务器,在client眼里,这个代理服务器就是web服务器。

2. 代理服务器获取到web服务器的数据后,返回给client。

3. 此时的client 无须做任何的设置,只需要正常访问即可,因此此时被隐藏的是服务端(web-server)。

所以你会发现,反向代理,这个代理机器,代理的是服务端。

客户端的访问请求,到底被转发给了哪一个web-server,我们无从得知,也无须得知。

用途

  • 隐藏服务端真实IP,保护远端服务器安全。
  • 负载均衡,反向代理服务器可以根据用户请求决定转发给哪一个后端节点服务器。
  • 提高访问速度,反向代理服务器可以缓存大多数静态资源,提高静态请求的解析速度。
  • 提供安全保证,反向代理服务器可以作为应用防火墙,提供https访问认证,防止ddos攻击,用户访问行为分析等。

对比正向代理、反向代理(精华)

正向代理与反向代理对比

正向代理

正向代理是客户端的代理,客户端明确知道要使用代理服务器,通过代理服务器来访问目标服务器。它主要用于隐藏客户端的真实身份、突破访问限制等。

反向代理

反向代理是服务器端的代理,客户端并不知道有反向代理的存在,它以为直接访问的就是目标服务器。反向代理用于负载均衡、安全防护、缓存等,将客户端请求转发到合适的后端服务器。

mermaid 代码实现对比图解

graph LR
    classDef client fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px
    classDef proxy fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px
    classDef server fill:#FFEBEB,stroke:#E68994,stroke-width:2px

    subgraph 正向代理
        A(Client):::client -->|Request with Proxy Config| B(Forward Proxy):::proxy
        B -->|Request on Behalf of Client| C(Target Server):::server
        C -->|Response| B
        B -->|Response to Client| A
    end

    subgraph 反向代理
        D(Client):::client -->|Request| E(Reverse Proxy):::proxy
        E -->|Forward Request| F(Backend Server 1):::server
        E -->|Forward Request| G(Backend Server 2):::server
        F -->|Response| E
        G -->|Response| E
        E -->|Return Response| D
    end

图解解释

正向代理部分

  • 客户端(Client):用户设备或应用程序,需要手动配置使用正向代理服务器。
  • 正向代理(Forward Proxy):接收客户端的请求,以自己的名义向目标服务器发起请求,隐藏客户端的真实 IP 地址。
  • 目标服务器(Target Server):提供资源的服务器,它只能看到正向代理的 IP 地址。
  • 流程:客户端将请求发送给正向代理,正向代理代替客户端向目标服务器请求资源,目标服务器响应给正向代理,正向代理再将响应返回给客户端。

反向代理部分

  • 客户端(Client):与正向代理中的客户端类似,但它不知道反向代理的存在,认为直接访问的就是目标服务器。
  • 反向代理(Reverse Proxy):接收客户端的所有请求,根据规则将请求转发到合适的后端服务器,同时接收后端服务器的响应并返回给客户端。
  • 后端服务器(Backend Server 1 和 Backend Server 2):实际处理业务逻辑的服务器,反向代理可以将请求均匀分配到多个后端服务器上实现负载均衡。
  • 流程:客户端向反向代理发送请求,反向代理将请求转发到后端服务器,后端服务器处理请求后将响应返回给反向代理,反向代理再将响应返回给客户端。

通过这个对比图,可以清晰地看到正向代理和反向代理在结构和工作流程上的差异。正向代理侧重于客户端的代理,而反向代理侧重于服务器端的代理。

虽然会发现,正向、反向代理服务器,都是处于client、server之间,并且做的事情也都是吧client的请求转发给server,然后进行响应,但是二者的目的是不一样的。

  • 正向代理其实是,代理客户端
    • 帮助客户端访问一些受限的资源,如国外的资料,如企业内部的内网资料。
    • 一般是客户端搭建,如安装某一个代理软件,填入代理服务器的ip、port
    • 此时server无法得知client到底是谁,看到的只能是proxy的IP。
  • 反向代理其实是代理服务端
    • 帮助服务端做负载均衡,安全防护
    • 一般是在服务端搭建,如部署nginx代理服务器。
    • 此时client无法得知server到底是谁,以为自己访问的就是真实的server。

灵魂画手

img

一、实战Nginx反向代理

官网
https://nginx.org/en/docs/http/ngx_http_proxy_module.html

Nginx 反向代理原理

Nginx 反向代理是指客户端的请求首先到达 Nginx 服务器,Nginx 根据配置规则将请求转发到后端的真实服务器进行处理,处理完成后将结果返回给客户端。客户端并不知道真正处理请求的是后端服务器,以为是直接与 Nginx 交互。

mermaid 代码

graph LR
    classDef client fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px
    classDef nginx fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px
    classDef backend fill:#FFEBEB,stroke:#E68994,stroke-width:2px

    A(Client):::client -->|Request| B(Nginx Reverse Proxy):::nginx
    B -->|Forward Request| C(Backend Server 1):::backend
    B -->|Forward Request| D(Backend Server 2):::backend
    B -->|Forward Request| E(Backend Server 3):::backend
    C -->|Response| B
    D -->|Response| B
    E -->|Response| B
    B -->|Return Response| A

详细解释

  1. 客户端(Client)
    • 代表发起请求的终端设备或应用程序,比如浏览器、移动应用等。客户端向 Nginx 反向代理服务器发送 HTTP 请求。
  2. Nginx 反向代理(Nginx Reverse Proxy)
    • 作为客户端和后端服务器之间的中间层。Nginx 接收客户端的请求后,会根据其配置文件中的规则(例如根据请求的 URL、请求方法等)将请求转发到合适的后端服务器。在这个过程中,Nginx 可以实现负载均衡功能,将请求均匀地分配到多个后端服务器上,避免单个服务器负载过高。
  3. 后端服务器(Backend Server 1、Backend Server 2、Backend Server 3)
    • 是实际处理业务逻辑的服务器。它们接收 Nginx 转发过来的请求,进行相应的处理,如数据库查询、文件读取等,然后将处理结果作为响应返回给 Nginx。
  4. 请求与响应流程
    • 客户端向 Nginx 发送请求。
    • Nginx 根据配置规则将请求转发到一个或多个后端服务器。
    • 后端服务器处理请求并将响应返回给 Nginx。
    • Nginx 接收到后端服务器的响应后,将其返回给客户端。

Nginx 反向代理的优势

  • 负载均衡:通过将请求分发到多个后端服务器,提高系统的整体处理能力和响应速度。
  • 安全性:可以隐藏后端服务器的真实 IP 地址,防止外部直接攻击后端服务器。
  • 缓存:Nginx 可以缓存一些静态资源,减少后端服务器的压力。
  • 统一入口:作为所有客户端请求的统一入口,方便进行管理和配置。

核心参数解释

使用反向代理,难点在于请求转发之后,你得注意保留client本身的信息。

因为nginx反向代理是又再次向后端节点发出新请求。

在 Nginx 中进行反向代理配置时,有许多核心参数和变量起着关键作用,下面为你详细介绍:

核心参数

1. proxy_pass

  • 作用:指定后端服务器的地址,Nginx 会将客户端的请求转发到该地址对应的服务器上。
  • 示例
    location /app {
      proxy_pass http://backend_server;
    }
    
    上述配置表示当客户端请求的 URL 以 /app 开头时,Nginx 会将请求转发到 backend_server 这个后端服务器上。backend_server 可以是具体的 IP 地址和端口,也可以是在 upstream 块中定义的服务器组名称。

2. proxy_set_header

  • 作用:用于修改或添加请求头信息,将客户端的一些请求信息传递给后端服务器,或者添加自定义的请求头。
  • 示例
    location / {
      proxy_pass http://backend_server;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
    
    • proxy_set_header Host $host:将客户端请求的主机名传递给后端服务器,确保后端服务器能正确处理请求。
    • proxy_set_header X-Real-IP $remote_addr:将客户端的真实 IP 地址传递给后端服务器,方便后端服务器进行日志记录和访问控制。
    • proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for:记录客户端的完整 IP 地址链,当请求经过多个代理服务器时,该头信息会包含所有代理服务器的 IP 地址。

3. proxy_connect_timeout

  • 作用:设置 Nginx 与后端服务器建立连接的超时时间。如果在该时间内无法建立连接,Nginx 将返回错误信息给客户端。
  • 示例
    location / {
      proxy_pass http://backend_server;
      proxy_connect_timeout 10s;
    }
    
    上述配置表示 Nginx 尝试与后端服务器建立连接的最长时间为 10 秒。

4. proxy_read_timeout

  • 作用:设置 Nginx 从后端服务器读取响应的超时时间。如果在该时间内没有从后端服务器接收到任何数据,Nginx 将关闭连接。
  • 示例
    location / {
      proxy_pass http://backend_server;
      proxy_read_timeout 60s;
    }
    
    此配置意味着 Nginx 等待后端服务器响应的最长时间为 60 秒。

5. proxy_send_timeout

  • 作用:设置 Nginx 向后端服务器发送请求的超时时间。如果在该时间内无法将请求数据发送到后端服务器,Nginx 将关闭连接。
  • 示例
    location / {
      proxy_pass http://backend_server;
      proxy_send_timeout 30s;
    }
    
    这里表示 Nginx 向后端服务器发送请求的最长时间为 30 秒。

核心变量

1. $host

  • 含义:表示客户端请求的主机名,即请求头中的 Host 字段值。如果请求头中没有 Host 字段,则使用 Nginx 服务器的 IP 地址。
  • 示例
    location / {
      proxy_pass http://backend_server;
      proxy_set_header Host $host;
    }
    

2. $remote_addr

  • 含义:表示客户端的真实 IP 地址。
  • 示例
    location / {
      proxy_pass http://backend_server;
      proxy_set_header X-Real-IP $remote_addr;
    }
    

3. $proxy_add_x_forwarded_for

  • 含义:包含客户端的 IP 地址以及经过的代理服务器的 IP 地址。如果请求经过多个代理服务器,该变量会按顺序记录所有 IP 地址。
  • 示例
    location / {
      proxy_pass http://backend_server;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
    

4. $request_uri

  • 含义:表示客户端请求的完整 URI,包括请求的路径和查询字符串。
  • 示例
    location / {
      proxy_pass http://backend_server$request_uri;
    }
    
    此配置会将客户端请求的完整 URI 传递给后端服务器。

关于这些转发参数,主要用于为了解决一些业务需求,而设置,否则一般默认即可。

proxy_set_header Host       $http_host; 
lb服务器将用户访问网站的hosts信息转发给后端节点

proxy_set_header  X-Forwarded-For   $proxy_add_x_forwarded_for ;
将用户真实的ip传递给后端的节点

proxy_connect_timeout 60s;
peoxy和server的连接超时,要求不超过75s;

proxy_send_timeout 60s;
proxy等待server回传数据的超时时间

proxy_read_timeout 60s;
proxy等待server响应的超时;

proxy_buffering on | off;
把server返回的数据先放入缓冲区,然后再返回给client,一边收数据,一边传递,而不是全部接收完再传递。

proxy_buffers  4 128k;
缓冲区的容量参数;

图解部署流程

image-20220514193409749

0.nginx反向代理参数优化

在使用 Nginx 进行反向代理时,合理优化相关参数能够显著提升系统的性能、稳定性和安全性。以下从连接管理、缓冲设置、超时控制、日志记录等方面为你介绍参数优化的方法。

连接管理参数优化

worker_processes

  • 作用:指定 Nginx 工作进程的数量。一般设置为服务器 CPU 核心数,以充分利用多核 CPU 的性能。
  • 示例
    worker_processes auto;
    
    使用 auto 会让 Nginx 自动检测服务器的 CPU 核心数并设置相应的工作进程数量。

worker_connections

  • 作用:每个工作进程允许同时打开的最大连接数。增大该值可以处理更多的并发连接,但要注意系统资源的限制。
  • 示例
    events {
      worker_connections 10240;
    }
    

upstream 模块中的 keepalive

  • 作用:启用与后端服务器的长连接,减少频繁建立和关闭连接的开销。
  • 示例
    upstream backend {
      server backend1.example.com;
      server backend2.example.com;
      keepalive 32;
    }
    
    这里的 32 表示每个 Nginx 工作进程与后端服务器保持的长连接数量。

缓冲设置参数优化

proxy_buffer_size

  • 作用:设置从后端服务器接收的响应头的缓冲区大小。如果响应头较大,需要适当增大该值,避免响应头被截断。
  • 示例
    location / {
      proxy_pass http://backend;
      proxy_buffer_size 16k;
    }
    

proxy_buffers

  • 作用:设置用于存储后端服务器响应的缓冲区数量和大小。合理设置可以提高数据传输效率。
  • 示例
    location / {
      proxy_pass http://backend;
      proxy_buffers 4 32k;
    }
    
    表示有 4 个大小为 32k 的缓冲区。

proxy_busy_buffers_size

  • 作用:设置在处理响应时处于忙碌状态的缓冲区的总大小。通常设置为 proxy_buffers 中单个缓冲区大小的 2 倍。
  • 示例
    location / {
      proxy_pass http://backend;
      proxy_busy_buffers_size 64k;
    }
    

超时控制参数优化

proxy_connect_timeout

  • 作用:设置 Nginx 与后端服务器建立连接的超时时间。避免长时间等待无法连接的后端服务器。
  • 示例
    location / {
      proxy_pass http://backend;
      proxy_connect_timeout 5s;
    }
    

proxy_read_timeout

  • 作用:设置 Nginx 从后端服务器读取响应的超时时间。防止因后端服务器响应缓慢而占用过多资源。
  • 示例
    location / {
      proxy_pass http://backend;
      proxy_read_timeout 15s;
    }
    

proxy_send_timeout

  • 作用:设置 Nginx 向后端服务器发送请求的超时时间。
  • 示例
    location / {
      proxy_pass http://backend;
      proxy_send_timeout 10s;
    }
    

日志记录参数优化

access_log

  • 作用:可以根据实际需求调整日志的记录级别和格式,或者关闭不必要的访问日志记录,以减少磁盘 I/O 开销。
  • 示例
    access_log off;
    
    关闭访问日志记录。如果需要记录,可以指定日志文件路径和日志格式:
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for"';
    access_log /var/log/nginx/access.log main;
    

安全相关参数优化

proxy_set_header

  • 作用:通过设置请求头信息,隐藏客户端的真实 IP 地址等敏感信息,同时传递必要的信息给后端服务器。
  • 示例
    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;
      proxy_set_header X-Forwarded-Proto $scheme;
    }
    

add_header

  • 作用:添加响应头信息,增强安全性,如设置 X-Frame-Options 防止页面被嵌入到其他网站的框架中。
  • 示例
    location / {
      proxy_pass http://backend;
      add_header X-Frame-Options SAMEORIGIN;
      add_header X-XSS-Protection "1; mode=block";
      add_header X-Content-Type-Options nosniff;
    }
    

nginx反向代理的参数可能会很多,如何你每一个虚拟主机server{}都设置,配置文件将会非常丑陋,因此可以利用include导入。

cat > /etc/nginx/proxy_params.conf << 'EOF'
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 30;
proxy_send_timeout 60;
proxy_read_timeout 60;
proxy_buffering on;
proxy_buffer_size 32k;
proxy_buffers 4 128k;
EOF

ansible-playbook部署nginx反向代理集群

以下是使用 Ansible Playbook 部署 Nginx 反向代理集群的完整方案,支持动态配置负载均衡策略和多后端服务器管理,适用于生产环境。


文件结构

nginx-proxy-cluster/
├── inventory/         # 清单文件
│   ├── production     # 生产环境主机分组
│   └── group_vars/
│       └── all.yml    # 全局变量
├── roles/
│   └── nginx_proxy/  # Nginx 角色
│       ├── tasks/
│       │   └── main.yml      # 主任务
│       ├── templates/
│       │   └── nginx-proxy.conf.j2  # 动态配置模板
│       └── handlers/
│           └── main.yml      # 重载Nginx触发器
└── playbook.yml       # 主Playbook

1. 清单文件 inventory/production

[nginx_proxy]  # Nginx反向代理服务器组
nginx-node1 ansible_host=192.168.1.100
nginx-node2 ansible_host=192.168.1.101

[backend_servers]  # 后端应用服务器组
app-node1 ansible_host=192.168.1.200
app-node2 ansible_host=192.168.1.201
app-node3 ansible_host=192.168.1.202

2. 全局变量 inventory/group_vars/all.yml

# Nginx 配置参数
nginx_proxy_port: 80
load_balancing_method: "least_conn"  # 可选: ip_hash/round-robin/least_conn
health_check_enabled: true

# 后端服务器动态获取(自动从 inventory 的 backend_servers 组获取)
backend_servers: "{{ groups['backend_servers'] | map('extract', hostvars, ['ansible_host']) | list }}"
backend_port: 8080  # 后端应用默认端口

3. 角色任务 roles/nginx_proxy/tasks/main.yml

---
- name: 安装 EPEL 仓库 (仅限 CentOS/RHEL)
  when: ansible_os_family == "RedHat"
  package:
    name: epel-release
    state: present

- name: 安装 Nginx
  package:
    name: nginx
    state: latest
  notify: reload nginx

- name: 创建 Nginx 配置目录
  file:
    path: /etc/nginx/conf.d
    state: directory
    mode: 0755

- name: 生成动态反向代理配置
  template:
    src: nginx-proxy.conf.j2
    dest: /etc/nginx/conf.d/proxy_cluster.conf
    validate: nginx -t -c %s
  notify: reload nginx

- name: 开放防火墙端口
  firewalld:
    port: "{{ nginx_proxy_port }}/tcp"
    permanent: true
    state: enabled
  when: ansible_os_family == "RedHat"
  notify: restart firewalld

- name: 确保 Nginx 服务自启并运行
  service:
    name: nginx
    state: started
    enabled: true

4. 配置模板 roles/nginx_proxy/templates/nginx-proxy.conf.j2

upstream backend {
    {{ load_balancing_method }};
    {% for server in backend_servers %}
    server {{ server }}:{{ backend_port }};
    {% endfor %}

    {% if health_check_enabled %}
    # 被动健康检查 (需 Nginx 版本 >= 1.7.11)
    max_fails=3 fail_timeout=30s;
    {% endif %}
}

server {
    listen {{ nginx_proxy_port }};
    server_name _;

    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;
        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_connect_timeout 2s;
        proxy_read_timeout 30s;
        proxy_send_timeout 30s;

        {% if health_check_enabled %}
        proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
        {% endif %}
    }

    # 主动健康检查 (需 nginx_upstream_check_module)
    {% if health_check_enabled %}
    location /nginx_status {
        check_status;
        access_log off;
        allow 127.0.0.1;
        deny all;
    }
    {% endif %}
}

5. 触发器 roles/nginx_proxy/handlers/main.yml

- name: reload nginx
  service:
    name: nginx
    state: reloaded

- name: restart firewalld
  service:
    name: firewalld
    state: restarted

6. 主 Playbook playbook.yml

---
- name: 部署 Nginx 反向代理集群
  hosts: nginx_proxy
  become: yes
  roles:
    - nginx_proxy

执行命令

# 检查清单配置
ansible-inventory -i inventory/production --list

# 语法检查
ansible-playbook -i inventory/production playbook.yml --syntax-check

# 执行部署
ansible-playbook -i inventory/production playbook.yml

# 限速执行(控制并发)
ansible-playbook -i inventory/production playbook.yml --limit nginx-node1 -f 5

高阶优化方案

  1. 动态后端发现
    结合 Consul 或 etcd 实现服务发现,通过 template 模块动态更新配置。

  2. SSL 终止
    添加 Let's Encrypt 证书自动签发(使用 acme.sh 角色):

    - name: 部署 SSL 证书
      include_role:
        name: nginx_ssl
      vars:
        ssl_domains: ["example.com"]
    
  3. 性能调优
    nginx.conf.j2 中调整以下参数:

    worker_processes auto;
    worker_connections 4096;
    keepalive_timeout 65;
    gzip on;
    
  4. 监控集成
    添加 Prometheus exporter 监控:

    - name: 部署 nginx_exporter
      become: yes
      package:
        name: nginx-prometheus-exporter
        state: present
    

架构图解

                [客户端]
                   |
         +---------+---------+
         |                   |
   [Nginx节点1]        [Nginx节点2]   → 通过 Keepalived 实现 VIP
         |                   |
         +---------+---------+
                   |
           +-------v-------+ 
           | 负载均衡策略    |
           | ({{ load_balancing_method }})
           +-------+-------+
                   |
         +----------v----------+
         | 后端服务器组          |
         | app-node1:8080      |
         | app-node2:8080      |
         | app-node3:8080      |
         +---------------------+

此方案通过 Ansible 实现了配置与代码的分离,支持快速扩展节点和策略调整,适合大规模集群管理。

1.lb-5机器实践

1. 安装nginx,配置yum源,依然使用官网最新的nginx
[root@lb-5 ~]#cat  /etc/yum.repos.d/nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key


2.安装nginx
yum clean all
yum install nginx -y

3.创建转发proxy参数文件
cat > /etc/nginx/proxy_params.conf << 'EOF'
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 30;
proxy_send_timeout 60;
proxy_read_timeout 60;
proxy_buffering on;
proxy_buffer_size 32k;
proxy_buffers 4 128k;
EOF

[root@lb-5 ~]#ls /etc/nginx/
conf.d  fastcgi_params  mime.types  modules  nginx.conf  proxy_params.conf  scgi_params  uwsgi_params


4.创建反向代理配置文件
cat > /etc/nginx/conf.d/proxy.conf <<EOF
server {
    listen 80;
    server_name wordpress.yuchaoit.cn;
    location / {
        proxy_pass http://172.16.1.8:8080;
        include /etc/nginx/proxy_params.conf;
    }
}
EOF

5.启动代理nginx服务
[root@lb-5 ~]#systemctl start nginx

2.部署后端节点(web-8)

1.注意我们是修改了后端节点的入口为 172.16.1.8:8080

2.修改配置文件
[root@web-8 ~]#cat  /etc/nginx/conf.d/wordpress.conf 
server{
    listen 8080;
    server_name wordpress.yuchaoit.cn;

    # 静态请求,资源存放路径
    root /code/wordpress;
    index index.php index.html;

    # 动态请求处理
    location ~ \.php$ {

        root /code/wordpress;
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

3.启动nginx(后端节点)
[root@web-8 ~]#systemctl start nginx

3.后端节点日志设置(web-8)

通过nginx的访客日志,查看具体的请求详细信息
[root@web-8 ~]#cat /etc/nginx/nginx.conf 

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/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"';

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

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

4.测试访问(windows)

client 访问 lb-5代理服务器,请求会转发给 web-8,最终一步步返回。

注意修改dns了
10.0.0.5 www.yuchaoit.cn wecenter.yuchaoit.cn wordpress.yuchaoit.cn

4.1 做好日志监测

lb-5

[root@lb-5 ~]#tail -f /var/log/nginx/access.log

web-8

[root@web-8 ~]#tail -f /var/log/nginx/access.log

4.2 windows客户端访问

使用强制刷新

image-20220514193914920

4.3 查看日志

lb-5

[root@lb-5 ~]#tail -f /var/log/nginx/access.log

web-8

[root@web-8 ~]#tail -f /var/log/nginx/access.log

image-20220514194416282

5.试试去掉转发参数呢?

5.1 去掉客户端真实ip

proxy_set_header Host $http_host;
#proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 30;
proxy_send_timeout 60;
proxy_read_timeout 60;
proxy_buffering on;
proxy_buffer_size 32k;
proxy_buffers 4 128k;

Web-8机器看不到windows-client的地址了。

5.2 去掉客户端主机信息

#proxy_set_header Host $http_host;
#proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 30;
proxy_send_timeout 60;
proxy_read_timeout 60;
proxy_buffering on;
proxy_buffer_size 32k;
proxy_buffers 4 128k;

由于是通过域名访问,且代理服务器没有添加客户端的主机信息,无法正确访问携带域名的请求。

wordpress.yuchaoit.cn

image-20220514195533770

反向代理总结图解

image-20220514195752413

Nginx负载均衡

1. Nginx反向代理和负载均衡的联系

  • 反向代理:反向代理是指以代理服务器来接受Internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给Internet上请求连接的客户端,此时代理服务器对外就表现为一个服务器。
  • 负载均衡:负载均衡是一种将请求均匀地分配到多个服务器上的技术,目的是避免单个服务器负载过高,从而提高系统的整体性能和可用性。

两者的联系在于,反向代理可以作为实现负载均衡的一种手段。Nginx在进行反向代理时,可以通过一定的算法将客户端的请求分发到多个后端服务器上,从而实现负载均衡的功能。也就是说,负载均衡是反向代理的一个高级应用场景。

2. Mermaid图解

以下是一个使用Mermaid绘制的流程图,展示了Nginx反向代理和负载均衡的工作原理:

graph LR
    classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
    classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px;

    A([客户端请求]):::startend --> B(Nginx反向代理):::process
    B --> C{负载均衡算法}:::decision
    C -->|轮询| D(后端服务器1):::process
    C -->|IP哈希| E(后端服务器2):::process
    C -->|最少连接| F(后端服务器3):::process
    D --> G([响应结果]):::startend
    E --> G
    F --> G
    G --> B
    B --> A

3. 代码解释

  • 客户端请求:客户端向Nginx反向代理服务器发送请求。
  • Nginx反向代理:Nginx接收到客户端的请求后,根据配置的负载均衡算法进行处理。
  • 负载均衡算法:Nginx支持多种负载均衡算法,如轮询、IP哈希、最少连接等。根据不同的算法,Nginx将请求分发到不同的后端服务器上。
  • 后端服务器:后端服务器接收到请求后进行处理,并将响应结果返回给Nginx。
  • 响应结果:Nginx将后端服务器的响应结果返回给客户端。

通过这种方式,Nginx实现了反向代理和负载均衡的功能,提高了系统的性能和可用性。

  • 刚才超哥讲解的是反向代理的设置,与应用
  • 现在你需要将后端节点部署多个,从而实现负载均衡。

1.什么是LB

1. web服务器需要解析用户大量的并发七牛,单机难以负荷
2. 使用多个web机器组成集群,前端用nginx负载均衡,将请求打散到多个后端节点。
3. 极大的提高整体系统的性能,安全,高可用。

2.负载均衡和反向代理

反向代理,代理的是一组服务器,因此就实现了负载均衡的效果。

3.四层负载、七层负载区别

四层负载和七层负载的区别

1. 工作层面不同

  • 四层负载均衡:工作在OSI模型的传输层(第四层),主要基于IP地址和端口进行负载均衡决策。常见的协议如TCP和UDP。它不关心应用层的数据内容,只是简单地将客户端的请求包转发到合适的后端服务器。
  • 七层负载均衡:工作在OSI模型的应用层(第七层),能够理解应用层协议(如HTTP、HTTPS、SMTP等)的内容。它可以根据请求的URL、HTTP头、Cookie等信息进行更细致的负载均衡决策。

2. 负载均衡粒度不同

  • 四层负载均衡:以连接为粒度进行负载均衡。当客户端发起一个TCP或UDP连接时,四层负载均衡器会选择一个后端服务器,并将该连接的所有数据包都转发到该服务器。
  • 七层负载均衡:以请求为粒度进行负载均衡。对于同一个客户端的不同请求,七层负载均衡器可以根据请求的具体内容将其转发到不同的后端服务器。

3. 灵活性不同

  • 四层负载均衡:灵活性相对较低,主要根据IP地址和端口进行分发,无法根据应用层的具体信息进行复杂的路由决策。
  • 七层负载均衡:具有更高的灵活性,可以根据应用层的各种信息进行负载均衡,例如根据URL将不同类型的请求分发到不同的后端服务器。

4. 性能开销不同

  • 四层负载均衡:由于不需要解析应用层数据,处理速度快,性能开销相对较小。
  • 七层负载均衡:需要对应用层数据进行解析,处理过程相对复杂,性能开销较大。

Mermaid 图解

graph LR
    classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
    classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px;

    subgraph 四层负载均衡
        style 四层负载均衡 fill:#ffffff,stroke:#000000,stroke-width:2px
        A([客户端请求]):::startend --> B(四层负载均衡器):::process
        B --> C{基于IP和端口选择}:::decision
        C -->|选择| D(后端服务器1):::process
        C -->|选择| E(后端服务器2):::process
        D --> F([响应结果]):::startend
        E --> F
        F --> B
        B --> A
    end

    subgraph 七层负载均衡
        style 七层负载均衡 fill:#ffffff,stroke:#000000,stroke-width:2px
        G([客户端请求]):::startend --> H(七层负载均衡器):::process
        H --> I{基于应用层信息选择}:::decision
        I -->|如URL匹配| J(后端服务器3):::process
        I -->|如Cookie匹配| K(后端服务器4):::process
        J --> L([响应结果]):::startend
        K --> L
        L --> H
        H --> G
    end

代码解释

  • 四层负载均衡部分

    • 客户端发起请求到四层负载均衡器。
    • 四层负载均衡器根据IP地址和端口信息选择一个后端服务器。
    • 后端服务器处理请求并返回响应结果,经过负载均衡器再返回给客户端。
  • 七层负载均衡部分

    • 客户端发起请求到七层负载均衡器。
    • 七层负载均衡器解析应用层信息(如URL、Cookie等),根据这些信息选择合适的后端服务器。
    • 后端服务器处理请求并返回响应结果,经过负载均衡器再返回给客户端。

这个图清晰地展示了四层负载均衡和七层负载均衡在工作方式上的差异。

nginx强大在于可以针对用户访问的url进行判断,从而决定后续的动作。

想到这里,记得第一份工作老大问我,nginx熟么,说说七层代理,和四层代理区别。

来,教大家怎么回答。。当然,回答只是为了技术交流,看看你是否会用nginx。

img

这里的几层,主要指的是OSI网络模型的一共七层。

3.1 四层负载均衡

1. 基本概念

四层负载均衡工作在 OSI 模型的传输层(第四层),主要依据 IP 地址和端口号对网络流量进行分发。它并不关心应用层的数据内容,只是简单地将客户端的请求连接转发到合适的后端服务器。常见的基于传输层的协议如 TCP(传输控制协议)和 UDP(用户数据报协议),四层负载均衡器会根据一定的算法在多个后端服务器之间分配这些连接。

2. 工作原理

当客户端向服务器发起请求时,请求首先到达四层负载均衡器。负载均衡器接收到请求后,会查看请求的源 IP 地址、目的 IP 地址、源端口号和目的端口号等信息。然后,根据预先配置好的负载均衡算法,从可用的后端服务器列表中选择一台服务器。最后,负载均衡器将客户端的请求连接转发到所选的后端服务器上。当后端服务器处理完请求并返回响应时,响应也会经过负载均衡器再返回给客户端。

3. 常见算法

3.1 轮询(Round Robin)

  • 原理:负载均衡器按照顺序依次将客户端请求分配到后端服务器列表中的每一台服务器上。当所有服务器都分配过一次后,再从头开始循环。
  • 示例:假设有三台后端服务器 Server1、Server2、Server3,客户端的请求依次会被分配到 Server1、Server2、Server3、Server1、Server2……
  • 适用场景:适用于后端服务器性能相近的场景,能够平均分配负载。

3.2 加权轮询(Weighted Round Robin)

  • 原理:为每台后端服务器分配一个权重值,权重值越高,表示该服务器的处理能力越强。负载均衡器在分配请求时,会根据服务器的权重比例进行分配。
  • 示例:Server1 权重为 3,Server2 权重为 2,Server3 权重为 1。那么在分配请求时,会按照 Server1、Server1、Server1、Server2、Server2、Server3 的顺序进行分配。
  • 适用场景:适用于后端服务器性能差异较大的场景,可以根据服务器的实际处理能力合理分配负载。

3.3 IP 哈希(IP Hash)

  • 原理:根据客户端的 IP 地址进行哈希计算,将计算结果与后端服务器列表进行映射,从而将同一个客户端的请求始终分配到同一台后端服务器上。
  • 示例:客户端 A 的 IP 地址经过哈希计算后,映射到 Server2,那么客户端 A 的所有请求都会被分配到 Server2 上。
  • 适用场景:适用于需要保持会话状态的场景,如用户登录状态的保持。

3.4 最少连接(Least Connections)

  • 原理:负载均衡器会实时监控每台后端服务器的连接数,将新的请求分配到当前连接数最少的服务器上。
  • 示例:Server1 有 10 个连接,Server2 有 5 个连接,Server3 有 8 个连接,那么新的请求会被分配到 Server2 上。
  • 适用场景:适用于后端服务器处理请求的时间差异较大的场景,能够动态地平衡服务器的负载。

4. 优缺点

4.1 优点

  • 性能高:由于不需要解析应用层数据,只处理传输层的信息,所以处理速度快,性能开销相对较小。
  • 通用性强:可以处理任何基于 TCP 或 UDP 的应用,不依赖于应用层协议。
  • 部署简单:配置相对简单,不需要对应用层进行深入了解。

4.2 缺点

  • 灵活性低:只能根据 IP 地址和端口进行负载均衡决策,无法根据应用层的具体信息(如 URL、HTTP 头、Cookie 等)进行复杂的路由。
  • 会话保持问题:对于需要保持会话状态的应用,可能需要额外的配置来实现会话保持。

5. 常见实现

  • 硬件负载均衡器:如 F5 Big - IP、Citrix NetScaler 等。这些硬件设备专门用于负载均衡,性能高、稳定性好,但价格昂贵。
  • 软件负载均衡器:如 Linux 内核自带的 IPVS(IP Virtual Server)、HAProxy(支持四层和七层负载均衡)等。软件负载均衡器成本低,易于部署和扩展。

6. 应用场景

  • 基础网络服务:如 TCP 代理、UDP 代理等,像 DNS 服务、流媒体服务等,这些服务主要基于传输层协议,四层负载均衡可以很好地满足需求。
  • 对性能要求高的场景:当系统对响应时间和吞吐量要求较高时,四层负载均衡的高性能优势可以得到充分发挥。例如大型电商网站的商品展示页面,需要快速响应用户的请求。

指的就是前四层,一直到TCP/IP层,传输层。

传输层,指的就是基于ip+port的通信,以及负载均衡。

四层负载均衡软件有LVS,性能更高,因为四层LB在接收到client的请求后,只需要通过数据包的目的地址信息(ip+port)然后将流量转发给后端节点。

因此是只针对ip+port协议的数据包转发,而不需要做一些额外复杂逻辑处理,效率就很高。

通过学习,使用LVS来实现负载均衡即可理解过程。

3.2 七层负载均衡

1. 基本概念

七层负载均衡工作在 OSI 模型的应用层(第七层),它能够理解应用层协议的内容,如 HTTP、HTTPS、SMTP 等。与四层负载均衡仅依据 IP 地址和端口进行流量分发不同,七层负载均衡可以根据请求的具体内容,如 URL、HTTP 头、Cookie 等信息,将客户端的请求转发到合适的后端服务器。

2. 工作原理

当客户端发送请求到七层负载均衡器时,负载均衡器会对请求的应用层数据进行解析。它会读取请求中的各种信息,如请求的 URL、HTTP 方法(GET、POST 等)、HTTP 头字段(如 User - Agent、Referer 等)以及 Cookie 等内容。然后,根据预先配置好的规则和算法,负载均衡器从后端服务器池中选择一台最合适的服务器,并将请求转发给该服务器。后端服务器处理完请求后,将响应返回给负载均衡器,负载均衡器再将响应返回给客户端。

3. 常见算法

3.1 基于 URL 的路由

  • 原理:根据请求的 URL 路径将请求分发到不同的后端服务器。例如,可以将以 /api 开头的请求转发到专门处理 API 请求的服务器,将以 /static 开头的请求转发到静态资源服务器。
  • 示例:配置规则为 /api/* 转发到 Server1,/static/* 转发到 Server2。当客户端请求 /api/user 时,请求会被转发到 Server1;请求 /static/css/style.css 时,请求会被转发到 Server2。
  • 适用场景:适用于将不同功能模块的请求分发到不同服务器的场景,如 Web 应用中区分 API 服务和静态资源服务。

3.2 基于 HTTP 头的路由

  • 原理:根据 HTTP 头中的特定字段值进行路由决策。例如,根据 User - Agent 字段判断客户端类型(如手机、电脑),将不同类型客户端的请求分发到不同的服务器。
  • 示例:如果 User - Agent 中包含 Mobile 关键字,将请求转发到 Server1;否则转发到 Server2。
  • 适用场景:适用于需要根据客户端特征进行请求分发的场景,如为移动客户端和桌面客户端提供不同的服务。
  • 原理:当客户端第一次访问时,负载均衡器会为其分配一台后端服务器,并在响应中设置一个 Cookie。后续该客户端的请求都会携带这个 Cookie,负载均衡器根据 Cookie 的值将请求始终转发到同一台服务器,从而保持会话状态。
  • 示例:客户端 A 第一次请求被分配到 Server1,负载均衡器在响应中设置 Cookie session_id = 123。后续客户端 A 携带该 Cookie 的请求都会被转发到 Server1。
  • 适用场景:适用于需要保持用户会话状态的应用,如用户登录系统、购物车系统等。

4. 优缺点

4.1 优点

  • 灵活性高:可以根据应用层的各种信息进行复杂的路由决策,能够更好地满足不同业务场景的需求。
  • 应用层优化:可以对应用层数据进行优化,如压缩 HTTP 响应、缓存静态资源等,提高应用的性能和响应速度。
  • 会话保持方便:能够基于 Cookie 等机制轻松实现会话保持,确保用户在一次会话过程中始终与同一台服务器进行交互。

4.2 缺点

  • 性能开销大:由于需要解析应用层数据,处理过程相对复杂,会消耗更多的 CPU 和内存资源,性能开销比四层负载均衡大。
  • 配置复杂:需要对应用层协议有深入的了解,配置规则相对复杂,增加了管理和维护的难度。

5. 常见实现

  • Nginx:是一款高性能的 Web 服务器和反向代理服务器,也支持强大的七层负载均衡功能。可以通过配置 location 块实现基于 URL 的路由,通过 proxy_set_header 等指令处理 HTTP 头信息。
  • HAProxy:是一个开源的高性能负载均衡器,支持四层和七层负载均衡。在七层负载均衡方面,它可以根据 HTTP 协议的各种信息进行灵活的路由配置。
  • Apache HTTP Server:通过使用 mod_proxy 等模块可以实现七层负载均衡功能,能够根据 URL 等信息将请求转发到不同的后端服务器。

6. 应用场景

  • Web 应用:在 Web 应用中,七层负载均衡可以根据不同的 URL 路径将请求分发到不同的后端服务器,如将动态页面请求和静态资源请求分开处理,提高应用的性能和可维护性。
  • 微服务架构:在微服务架构中,每个微服务可能有不同的功能和访问需求。七层负载均衡可以根据请求的具体信息将请求准确地分发到对应的微服务实例,实现服务的高效调用。
  • 电子商务系统:对于电子商务系统,七层负载均衡可以根据用户的会话状态、购物车信息等将请求分发到合适的服务器,确保用户在购物过程中的体验流畅。
1.七层负载均衡是指OSI模型的应用层,也就是基于第七层的协议转发,如http,https协议;

2.因此内容更丰富,例如基于client的访问url区别、客户端的浏览器区别、客户端的ip地址区别,来决定不同的负载均衡动作。

3.当然OSI模型是自下而上的,nginx是在支持tcp/ip基础之上的,同时支持四层、与七层的转发设置。

4. http层的负载均衡主要指的是,通过http信息的改写,请求头的改写,url匹配规则,proxy_pass,以及rewrite等规则。


所以说为什么nginx使用的非常广泛,就是如此,因为互联网环境,绝大部分就完全是http协议的通信。

image-20220515124038286

3.3 大并发优化(lvs+nginx)

Nginx 大并发优化与多层架构概述

优化思路

Nginx 是一个高性能的 Web 服务器和反向代理服务器,在大并发场景下,需要从多个方面进行优化,包括操作系统层面、Nginx 配置层面等。多层架构则是通过合理地组织服务器层次,如前端负载均衡层、应用服务层、数据存储层等,来提高系统的整体性能和可扩展性。

多层架构

典型的多层架构一般包含以下几个层次:

  • 负载均衡层:负责接收客户端的请求,并将请求均匀地分发到多个应用服务器上,常用的负载均衡算法有轮询、IP 哈希等。
  • 应用服务层:处理具体的业务逻辑,如 Web 应用程序、API 服务等。
  • 数据存储层:存储应用程序所需的数据,如数据库、缓存等。

Mermaid 图解

graph LR
    classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
    classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px;

    subgraph 客户端
        style 客户端 fill:#ffffff,stroke:#000000,stroke-width:2px
        A([客户端1]):::startend
        B([客户端2]):::startend
        C([客户端N]):::startend
    end

    subgraph 负载均衡层
        style 负载均衡层 fill:#ffffff,stroke:#000000,stroke-width:2px
        D(Nginx 负载均衡器):::process
    end

    subgraph 应用服务层
        style 应用服务层 fill:#ffffff,stroke:#000000,stroke-width:2px
        E(应用服务器1):::process
        F(应用服务器2):::process
        G(应用服务器N):::process
    end

    subgraph 数据存储层
        style 数据存储层 fill:#ffffff,stroke:#000000,stroke-width:2px
        H(数据库服务器):::process
        I(缓存服务器):::process
    end

    A --> D
    B --> D
    C --> D
    D --> E
    D --> F
    D --> G
    E --> H
    E --> I
    F --> H
    F --> I
    G --> H
    G --> I
    H --> E
    H --> F
    H --> G
    I --> E
    I --> F
    I --> G
    E --> D
    F --> D
    G --> D
    D --> A
    D --> B
    D --> C

代码解释

  • 客户端:多个客户端发起请求,这些请求首先到达负载均衡层。
  • 负载均衡层:Nginx 负载均衡器接收客户端的请求,并根据负载均衡算法将请求分发到应用服务层的多个应用服务器上。
  • 应用服务层:应用服务器处理具体的业务逻辑,可能需要从数据存储层获取数据或向数据存储层写入数据。
  • 数据存储层:数据库服务器用于持久化存储数据,缓存服务器用于缓存经常访问的数据,以提高系统的响应速度。

Nginx 大并发优化配置要点

操作系统层面

  • 调整文件描述符限制:在大并发场景下,Nginx 会同时处理大量的连接,需要增加系统的文件描述符限制。可以通过修改 /etc/security/limits.conf 文件来实现:
    nginx soft nofile 65535
    nginx hard nofile 65535
    
  • 调整 TCP 参数:可以通过修改 /etc/sysctl.conf 文件来调整 TCP 参数,如增大 TCP 连接队列长度、调整 TCP 超时时间等。
    net.core.somaxconn = 65535
    net.ipv4.tcp_max_syn_backlog = 65535
    net.ipv4.tcp_tw_recycle = 1
    net.ipv4.tcp_tw_reuse = 1
    
    修改后执行 sysctl -p 使配置生效。

Nginx 配置层面

  • 调整 worker 进程数worker_processes 参数设置为服务器的 CPU 核心数,以充分利用 CPU 资源。
    worker_processes auto;
    
  • 调整连接数限制worker_connections 参数设置每个 worker 进程可以处理的最大连接数。
    events {
      worker_connections 65535;
    }
    
  • 启用 HTTP 缓存:可以通过配置 proxy_cache 来启用 HTTP 缓存,减少对后端服务器的请求。
    proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m inactive=60m;
    server {
      location / {
          proxy_cache my_cache;
          proxy_cache_valid 200 302 60m;
          proxy_cache_valid 404      1m;
          proxy_pass http://backend;
      }
    }
    

通过以上的多层架构和优化配置,可以提高 Nginx 在大并发场景下的性能和稳定性。

这种架构,就是充分发挥 四层lb 以及 七层lv 二者的优点

1. 让lvs 抗住外网的大流量,然后负载均衡的把流量分发给后端的多个nginx七层负载均衡

2. 后端的nginx再进行后续的用户请求转发,来实现丰富的七层反向代理。

image-20220515125127265

4.负载均衡实践配置(nginx)

以下为你详细介绍一个使用 Nginx 实现负载均衡的完整案例,涵盖环境准备、配置步骤、验证方式以及代码解释。

案例场景

假设我们有一个 Web 应用,为了提高其性能和可用性,我们使用 Nginx 作为负载均衡器,将客户端的请求分发到多个后端 Web 服务器上。这里我们假设有 3 台后端服务器,它们都运行着相同的 Web 应用。

环境准备

  • 负载均衡器:一台安装了 Nginx 的服务器,操作系统可以是 Linux(如 CentOS、Ubuntu 等)。
  • 后端服务器:三台运行 Web 服务的服务器,这里我们使用 Nginx 作为 Web 服务器,也可以使用 Apache 等其他 Web 服务器。

配置步骤

1. 后端服务器配置

在每台后端服务器上安装并启动 Nginx,并创建一个简单的测试页面。以下以 Ubuntu 系统为例:

# 安装 Nginx
sudo apt-get update
sudo apt-get install nginx

# 创建测试页面
echo "This is backend server [server number]" | sudo tee /var/www/html/index.html

分别在三台后端服务器上执行上述命令,并将 [server number] 替换为对应的服务器编号(如 1、2、3)。

2. 负载均衡器配置

在负载均衡器上编辑 Nginx 配置文件 /etc/nginx/nginx.conf/etc/nginx/sites - available/default,添加如下配置:

http {
    # 定义后端服务器组
    upstream backend_servers {
        # 轮询算法,也可根据需求更换为其他算法,如 ip_hash
        server 192.168.1.101;  # 后端服务器 1 的 IP 地址
        server 192.168.1.102;  # 后端服务器 2 的 IP 地址
        server 192.168.1.103;  # 后端服务器 3 的 IP 地址
    }

    server {
        listen 80;
        server_name your_domain_or_ip;  # 替换为负载均衡器的域名或 IP 地址

        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;
        }
    }
}

3. 重启 Nginx

在负载均衡器和后端服务器上分别重启 Nginx 使配置生效:

sudo systemctl restart nginx

验证负载均衡

打开浏览器,输入负载均衡器的域名或 IP 地址,多次刷新页面,观察页面显示的内容。如果负载均衡配置成功,每次刷新页面时,显示的服务器编号应该会交替出现,说明请求被成功分发到了不同的后端服务器上。

代码解释

  • upstream 块:定义了一个后端服务器组 backend_servers,其中列出了所有的后端服务器。默认使用轮询算法将请求依次分发到各个服务器。
  • server 块:配置了一个监听 80 端口的虚拟主机,将所有请求通过 proxy_pass 指令转发到 backend_servers 服务器组。
  • proxy_set_header 指令:设置代理请求的 HTTP 头信息,确保后端服务器能够获取到客户端的真实 IP 地址和域名信息。

其他注意事项

  • 负载均衡算法:除了轮询算法,Nginx 还支持多种负载均衡算法,如 ip_hash(根据客户端 IP 地址进行哈希,将同一客户端的请求始终分发到同一台服务器)、least_conn(将请求分发到当前连接数最少的服务器)等。可以根据实际需求进行配置。
  • 健康检查:Nginx 本身没有内置的健康检查机制,但可以通过第三方模块(如 nginx_upstream_check_module)来实现对后端服务器的健康检查,当发现某个服务器出现故障时,自动将其从负载均衡组中移除。
官网模块
https://nginx.org/en/docs/http/ngx_http_upstream_module.html

Nginx的负载均衡功能来自于其模块ngx_http_upstream_module模块,该模块支持的代理方式有:

  • uwsgi_pass
  • Fastcgi_pass
  • proxy_pass
  • Memcached_pass
  • ...

ngx_http_upstream_module模块允许Nginx定义一组或多组节点服务器,使用时可以通过proxy_pass代理方式,把用户请求发送到事先定于好的upstream组中。

具体写法就是

upstream backend {        # 定义后端服务器组列表

        # 具体的服务器地址形式,可以是ip,域名,以及port的结合。 
        # 以及填入负载均衡的 算法参数

    server backend1.example.com       weight=5;    
    server backend2.example.com:8080;
    server unix:/tmp/backend3;

    server backup1.example.com:8080   backup;
    server backup2.example.com:8080   backup;
}

server {
         # 七层负载均衡核心,基于location匹配url,决定后续动作
    location / {
          # 转发给地址池
        proxy_pass http://backend;
    }
}

upstream参数

# 参数解释
server是固定关键字,后面跟着服务器ip或是域名,默认是80端口,也可以指定端口
weight表示节点的权重,数字越大,分配的请求越多,注意nginx结尾的分号
max_fails Nginx尝试连接后端节点失败的次数,根据企业情况调整,默认是1
backup 其它所有的非backup机器down或者忙的时候,请求backup机器,实现热备效果。
fail_timeout 在max_fails定义的次数失败后,距离下次检查的间隔时间,默认10s
down 表示当前主机暂停,不参与负载均衡

upstream模块的内容应放于nginx.conf配置中的 http{}标签内
其默认调度算法是wrr(权重轮询,weighted round-robin)
http {
    # 定义后端服务器组
    upstream backend_servers {
        # 后端服务器 1
        server 192.168.1.101 weight=3 max_fails=2 fail_timeout=20s;
        # 后端服务器 2
        server 192.168.1.102 weight=2;
        # 后端服务器 3,作为热备服务器
        server 192.168.1.103 backup;
        # 后端服务器 4,暂时不参与负载均衡
        server 192.168.1.104 down;
    }

    server {
        listen 80;
        server_name your_domain_or_ip;  # 替换为负载均衡器的域名或 IP 地址

        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;
        }
    }
}

5. 实战七层负载均衡(nginx)

需求

1. 设置 lb服务器,绑定  wordpress.yuchaoit.cn

2. 默认轮询模式,转发给 web-7 web-8两个机器,分别提供web服务

5.1 机器准备

10.0.0.5   172.16.1.5   slb-5


10.0.0.7   172.16.1.7   web-7

10.0.0.8   172.16.1.8   web-8

5.2 web服务器组配置文件

Web-7

[root@web-7 ~]#cat  /etc/nginx/conf.d/wordpress.conf 
server{
    listen 8080;
    server_name wordpress.yuchaoit.cn;

    # 静态请求,资源存放路径
    root /code/wordpress;
    index index.php index.html;

    # 动态请求处理
    location ~ \.php$ {

        root /code/wordpress;
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}


[root@web-7 ~]#systemctl restart nginx

web-8机器

[root@web-8 ~]#cat /etc/nginx/conf.d/wordpress.conf 
server{
    listen 8080;
    server_name wordpress.yuchaoit.cn;

    # 静态请求,资源存放路径
    root /code/wordpress;
    index index.php index.html;

    # 动态请求处理
    location ~ \.php$ {

        root /code/wordpress;
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}


[root@web-8 ~]#systemctl restart nginx

5.3 lb机器配置文件

[root@lb-5 ~]#cat  /etc/nginx/conf.d/proxy.conf 
upstream  web-pools {
    server 172.16.1.7:8080;
    server 172.16.1.8:8080;
}

server {
    listen 80;
    server_name wordpress.yuchaoit.cn;
    location / {
        proxy_pass http://web-pools;
        include /etc/nginx/proxy_params.conf;
    }
}


[root@lb-5 ~]#nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@lb-5 ~]#
[root@lb-5 ~]#systemctl restart nginx

6.测试访问(图解)

image-20220515134846667

配置dns解析

10.0.0.5 www.yuchaoit.cn wecenter.yuchaoit.cn wordpress.yuchaoit.cn

全部做好日志检测

[root@web-7 ~]#tail -f /var/log/nginx/access.log


[root@web-8 ~]#tail -f /var/log/nginx/access.log


[root@lb-5 ~]#tail -f   /var/log/nginx/access.log

image-20220515140357291

这里的是完全基于域名实现的负载均衡

1. 用户在浏览器访问wordpress

2. lb-5接收到请求,保留用户的客户端信息,添加在反向代理参数里,再发出新请求,给后端节点

3.后端节点能够通过本次请求的请求头,获取到用户信息,具体要访问什么资源(url),然后进行解析,响应。

4.最终一步步返回,给用户浏览器结果。

6.1试试关闭后端一个节点

模拟单点故障,发现并没有问题,请求全部给了其他的机器。

[root@web-8 /etc/nginx]#systemctl stop nginx

全部故障呢?

[root@web-7 /etc/nginx/conf.d]#systemctl stop nginx

image-20220515141139399

7.实战四层负载均衡(nginx)

以下是在 Ubuntu 系统上进行 Nginx 四层负载均衡的实战步骤,以实现对 MySQL 服务的负载均衡为例。

环境准备

  • 负载均衡器:一台安装 Ubuntu 系统的服务器,并且需要安装 Nginx。
  • 后端服务器:至少两台运行 MySQL 服务的服务器。

步骤 1:安装 Nginx

在 Ubuntu 服务器上,使用以下命令安装 Nginx:

sudo apt update
sudo apt install nginx

步骤 2:检查 Nginx 是否支持 stream 模块

Nginx 的 stream 模块用于实现四层负载均衡。可以通过以下命令检查 Nginx 是否已经包含该模块:

nginx -V 2>&1 | grep stream

如果输出中有 --with-stream,则表示 Nginx 支持 stream 模块。如果不支持,需要重新编译 Nginx 并添加 --with-stream 选项。不过通常 Ubuntu 软件源中的 Nginx 版本默认是支持的。

步骤 3:配置 Nginx 进行四层负载均衡

编辑 Nginx 的主配置文件 /etc/nginx/nginx.conf,添加或修改以下内容:

# 全局配置
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
    worker_connections 768;
}

# 四层负载均衡配置
stream {
    # 定义后端 MySQL 服务器组
    upstream mysql_backend {
        # 后端服务器 1,可根据实际情况修改 IP 和端口
        server 192.168.1.100:3306;
        # 后端服务器 2
        server 192.168.1.101:3306;
    }

    # 监听端口并将流量转发到后端服务器组
    server {
        # 监听的端口,客户端将连接此端口
        listen 3307;
        # 将请求转发到后端服务器组
        proxy_pass mysql_backend;
    }
}

# HTTP 配置部分,如果不需要可保持默认或适当修改
http {
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

配置解释

  • stream:用于配置四层负载均衡,与 http 块是并列关系。
  • upstream 指令:定义了一个名为 mysql_backend 的后端服务器组,其中列出了参与负载均衡的 MySQL 服务器及其端口。
  • server 指令:在 stream 块内的 server 指令用于监听特定端口(这里是 3307),并将该端口接收到的流量通过 proxy_pass 指令转发到 mysql_backend 后端服务器组。

步骤 4:检查配置并重启 Nginx

# 检查配置文件语法是否正确
sudo nginx -t
# 如果语法正确,重启 Nginx 使配置生效
sudo systemctl restart nginx

步骤 5:测试四层负载均衡

在客户端使用 MySQL 客户端工具连接到负载均衡器的 3307 端口:

mysql -h <负载均衡器 IP 地址> -P 3307 -u <用户名> -p

多次执行连接操作,通过查看后端服务器的日志或者监控连接信息,可以验证请求是否被正确分发到不同的后端服务器上。

其他优化和扩展

负载均衡算法

默认情况下,Nginx 在 stream 模块中使用轮询算法。你可以通过添加 weight 参数来实现加权轮询,例如:

upstream mysql_backend {
    server 192.168.1.100:3306 weight=2;
    server 192.168.1.101:3306 weight=1;
}

健康检查

Nginx 本身在 stream 模块中没有内置的健康检查机制,但可以结合第三方模块(如 nginx_upstream_check_module)来实现对后端服务器的健康检查,当发现某个服务器出现故障时,自动将其从负载均衡组中移除。

注意事项

  • 确保后端服务器的防火墙允许来自负载均衡器的连接。
  • 若使用的是云服务器,需要配置相应的安全组规则。

四层负载均衡就是完全基于ip、port进行负载均衡。

使用stream{} 独立模块,与 http{} 模块平级,注意配置文件写法

https://nginx.org/en/docs/stream/ngx_stream_core_module.html

7.1 四层负载需求

注意这里不用去考虑关于数据的一致性问题,只是为了测试,查看四层的负载均衡转发情况。

image-20220515143513356

7.3 环境准备


172.16.1.5:3306 (nginx)

172.16.1.51:3306 (mysql)

172.16.1.52:3306 (mysql)

7.4 统一安装mysql(51,52)

yum install mariadb mariadb-server -y 

systemctl start mariadb

systemctl enable mariadb

mysqladmin password 'yuchaoit.cn'


配置权限,允许root远程连接
mysql -uroot  -p'yuchaoit.cn'

grant all privileges on *.* to 'root'@'%' identified by 'yuchaoit.cn';

7.5 负载均衡配置 lb-5

# nginx配置文件
# 无须关于http的请求参数了

[root@lb-5 /etc/nginx]#cat /etc/nginx/nginx.conf 

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}

stream {
    upstream mysql_pool {

      server 172.16.1.51:3306  max_fails=3 fail_timeout=30s;
      server 172.16.1.52:3306  max_fails=3 fail_timeout=30s;
    }

    server {
      listen 0.0.0.0:3306;
            proxy_pass mysql_pool;
    }


}



# 启动nginx
[root@lb-5 /etc/nginx]#nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@lb-5 /etc/nginx]#systemctl restart nginx

7.6 客户端测试四层转发

yum install mariadb -y

image-20220515165913066

Copyright © www.yuchaoit.cn 2025 all right reserved,powered by Gitbook作者:于超 2025-02-26 20:49:39

results matching ""

    No results matching ""