14、NGINX 反向代理与负载均衡优化全解析

NGINX 反向代理与负载均衡优化全解析

1. NGINX 反向代理指令详解

在使用 NGINX 作为反向代理时,有众多指令可用于配置和优化代理行为。以下是一些关键指令的详细介绍:

指令 上下文 描述 语法 示例
proxy_next_upstream http, server, location 当 proxy_pass 连接到 upstream 块时,定义请求应放弃并重新发送到该块的下一个上游服务器的情况 接受以下值的组合:error, timeout, invalid_header, http_500, http_502, http_503, http_504, http_40, off proxy_next_upstream error timeout http_504;
proxy_next_upstream_timeout http, server, location 定义与 proxy_next_upstream 结合使用的超时时间,设置为 0 可禁用 时间值(秒)
proxy_next_upstream_tries http, server, location 定义在返回错误消息之前尝试的上游服务器的最大数量,与 proxy_next_upstream 结合使用 数值(默认:0)
2. 缓存、缓冲和临时文件相关指令

为了减少转发到后端服务器的请求数量,可以使用以下指令构建缓存系统,控制缓冲选项和 NGINX 处理临时文件的方式:

指令 上下文 描述 语法 示例
proxy_buffer_size http, server, location 设置用于读取后端服务器响应开头的缓冲区大小,通常包含简单的头部数据 数值(大小) proxy_buffer_size 4k;
proxy_buffering, proxy_request_buffering http, server, location 定义是否应缓冲后端服务器的响应(或客户端请求) on 或 off
proxy_buffers http, server, location 设置用于读取后端服务器响应数据的缓冲区的数量和大小 proxy_buffers 数量 大小; fastcgi_buffers 8 4k;
proxy_busy_buffers_size http, server, location 当缓冲区中累积的后端接收数据超过指定值时,刷新缓冲区并将数据发送到客户端 数值(大小)
proxy_cache http, server, location 定义一个缓存区域,该区域的标识符将在后续指令中重用 proxy_cache 区域名称; proxy_cache cache1;
proxy_cache_key http, server, location 定义缓存键,用于区分不同的缓存条目 proxy_cache_key 键; proxy_cache_key “$scheme$host$request_uri $cookie_user”;
proxy_cache_path http 指示存储缓存文件的目录以及其他参数 proxy_cache_path 路径 [use_temp_path=on off] [levels=数字 keys_zone=名称:大小 inactive=时间 max_size=大小];
proxy_cache_methods http, server, location 定义符合缓存条件的 HTTP 方法,GET 和 HEAD 默认包含且不能禁用 proxy_cache_methods 方法; proxy_cache_methods OPTIONS;
proxy_cache_min_uses http, server, location 定义请求符合缓存条件之前的最小命中次数 数值 proxy_cache_min_uses 1;
proxy_cache_valid http, server, location 允许为不同类型的响应代码自定义缓存时间 proxy_cache_valid 代码1 [代码2…] 时间; proxy_cache_valid 404 1m;
proxy_cache_use_stale http, server, location 定义在某些情况下(关于网关)NGINX 是否应提供陈旧的缓存数据 proxy_cache_use_stale [updating] [error] [timeout] [invalid_header] [http_500]; proxy_cache_use_stale error timeout;
proxy_max_temp_file_size http, server, location 设置该指令为 0 可禁用对符合代理转发条件的请求使用临时文件,或指定最大文件大小 大小值 proxy_max_temp_file_size 5m;
proxy_temp_file_write_size http, server, location 设置将临时文件保存到存储设备时的写入缓冲区大小 大小值
proxy_temp_path http, server, location 设置临时和缓存存储文件的路径 proxy_temp_path 路径 [级别1 [级别2…]] proxy_temp_path /tmp/nginx_proxy;
3. 限制、超时和错误相关指令

以下指令可用于定义超时行为以及与后端服务器通信的各种限制:

指令 上下文 描述 语法 示例
proxy_connect_timeout http, server, location 定义后端服务器连接超时时间,与读写超时不同 时间值(秒) proxy_connect_timeout 15;
proxy_read_timeout http, server, location 从后端服务器读取数据的超时时间,应用于两次读取操作之间 时间值(秒) proxy_read_timeout 60;
proxy_send_timeout http, server, location 向后端服务器发送数据的超时时间,应用于两次写入操作之间 时间值(秒) proxy_send_timeout 60;
proxy_ignore_client_abort http, server, location 如果设置为 on,即使客户端中止请求,NGINX 也将继续处理代理请求 on 或 off
proxy_intercept_errors http, server, location 默认情况下,NGINX 将后端服务器发送的所有错误页面(HTTP 状态代码 400 及以上)直接返回给客户端,设置为 on 可解析错误代码并与 error_page 指令中指定的值进行匹配 on 或 off
proxy_send_lowat http, server, location 仅在基于 BSD 的操作系统下允许对 TCP 套接字使用 SO_SNDLOWAT 标志,定义输出操作缓冲区中的最小字节数 数值(大小)
proxy_limit_rate http, server, location 允许限制 NGINX 从后端代理下载响应的速率 数值(字节/秒)
4. 其他未分类指令

代理模块中还有一些未分类的指令:

指令 上下文 描述 语法 示例
proxy_headers_hash_max_size http, server, location 设置代理头哈希表的最大大小 数值
proxy_headers_hash_bucket_size http, server, location 设置代理头哈希表的桶大小 数值
proxy_force_ranges http, server, location 设置为 on 时,NGINX 将在后端代理的响应上启用字节范围支持 on 或 off
proxy_ignore_headers http, server, location 防止 NGINX 处理后端服务器响应中的以下四个头之一:X-Accel-Redirect, X-Accel-Expires, Expires, Cache-Control proxy_ignore_headers 头1 [头2…];
proxy_set_body http, server, location 允许为调试目的设置静态请求体,指令值中可使用变量 字符串值(任意值) proxy_set_body test;
proxy_set_header http, server, location 允许重新定义要传输到后端服务器的头值,可多次声明 proxy_set_header 头 值; proxy_set_header Host $host;
proxy_store http, server, location 指定后端服务器响应是否应存储为文件,存储的响应文件可用于为其他请求提供服务 on, off 或相对于文档根目录(或别名)的路径 proxy_store on;
proxy_store_access http, server, location 定义存储的响应文件的文件访问权限 proxy_store_access [user:[r w
proxy_http_version http, server, location 设置用于与代理后端通信的 HTTP 版本,默认值为 HTTP 1.0,如果要启用持久连接,可将此指令设置为 1.1 proxy_http_version 1.0 | 1.1;
proxy_cookie_domain, proxy_cookie_path http, server, location 对 cookie 的域或路径属性进行即时修改(不区分大小写) proxy_cookie_domain off | 域 替换; proxy_cookie_path off | 域 替换;
5. 变量介绍

代理模块提供了几个可插入到各种位置的变量,例如在 proxy_set_header 指令或与日志记录相关的指令(如 log_format)中。可用的变量如下:
- $proxy_host :包含当前请求使用的后端服务器的主机名。
- $proxy_port :包含当前请求使用的后端服务器的端口。
- $proxy_add_x_forwarded_for :该变量包含 X - Forwarded - For 请求头的值,后跟客户端的远程地址,两个值用逗号分隔。如果 X - Forwarded - For 请求头不可用,该变量仅包含客户端的远程地址。
- $proxy_internal_body_length :请求体的长度(使用 proxy_set_body 指令设置或为 0)。

6. NGINX 与微服务

对于应用程序的任何给定任务,有两种选择:可以代理到后端服务器(如 Node.js)来处理工作,也可以直接在 NGINX 中实现。选择哪种方式取决于很多因素,但主要考虑的两个因素是速度和复杂性。

代理到复杂的后端服务器有一定的开销成本,但通常允许代码重用并使用包管理器(如 Packagist 和 NPM)。相反,在 NGINX 中实现功能可以更接近用户,减少开销,但开发本身也会变得更加困难。大多数设置会选择代理到后端以简化操作。例如,Cloudflare 及其代理/CDN 服务,由于处理大量请求且响应时间至关重要,他们使用在 NGINX 配置文件中添加 Lua 支持的模块,直接在 NGINX 中实现了安全过滤(Web 应用防火墙)。

以下是一个简单的在 NGINX 中实现应用逻辑的示例,将缓存从后端服务器移到 NGINX 本身:

# Check cache and use PHP as a fallback.
location ~* \.php$ {
    default_type text/html;
    charset utf-8;
    if ($request_method = GET) {
        set $memcached_key $request_uri;
        memcached_pass memcached;
        error_page 404 502 = @nocache;
    }
    if ($request_method != GET) {
        fastcgi_pass backend;
    }
}
location @nocache {
    fastcgi_pass backend;
}
7. 负载均衡与线程池简介

随着网站越来越受欢迎,单台服务器可能会遇到处理瓶颈,如老化的硬盘或有限的带宽会导致请求处理时间变长,影响用户体验。虽然 NGINX 可以帮助服务器承受负载,但单台机器的处理能力总是有限的。单纯购买更大、更昂贵的服务器并非长期的成本有效方法,而且服务器承受的压力越大,硬件故障的可能性就越高。

接下来将探讨两个概念:
- 负载均衡 :将负载分布到多个服务器并有效管理这种分布的技术。
- 线程池 :一种新机制,通过以稍微不同的方式处理请求,缓解服务器在重负载(特别是由阻塞操作引起的负载)下的压力。

负载均衡的概念可以解决可扩展性、可用性和性能方面的问题,许多世界上访问量最大的网站都采用了精心规划的服务器架构,快速的页面加载和下载速度是长期流量增长的必要条件。下面将详细介绍如何使用 NGINX 实现负载均衡架构。

graph LR
    A[客户端请求] --> B[NGINX 反向代理]
    B --> C1[后端服务器 1]
    B --> C2[后端服务器 2]
    B --> C3[后端服务器 3]
    C1 --> D[响应客户端]
    C2 --> D
    C3 --> D

以上流程图展示了客户端请求通过 NGINX 反向代理分发到多个后端服务器的过程。

综上所述,NGINX 在反向代理、缓存、负载均衡等方面都有强大的功能,合理使用这些功能可以显著提升服务器的性能和可用性。在后续的内容中,将进一步深入探讨如何使用 NGINX 作为 TCP 负载均衡器以及线程池和 I/O 机制的相关内容。

8. 介绍负载均衡

负载均衡是一种将工作负载分布到多个服务器上的技术,它能有效管理负载分布,解决可扩展性、可用性和性能方面的问题。以下是使用 NGINX 进行负载均衡的优势和常见负载均衡算法:
| 优势 | 描述 |
| — | — |
| 提高可用性 | 当部分服务器出现故障时,负载均衡可以将请求自动转移到其他正常的服务器上,确保服务的连续性。 |
| 增强性能 | 通过将负载分散到多个服务器,减少单个服务器的压力,从而提高响应速度和吞吐量。 |
| 便于扩展 | 可以根据业务需求轻松添加或移除服务器,实现灵活的扩展。 |

常见的负载均衡算法如下:
| 算法 | 描述 |
| — | — |
| 轮询(Round Robin) | 按顺序依次将请求分配给服务器,每个服务器轮流处理请求。 |
| 加权轮询(Weighted Round Robin) | 根据服务器的性能差异,为每个服务器分配不同的权重,权重高的服务器处理更多的请求。 |
| IP 哈希(IP Hash) | 根据客户端的 IP 地址进行哈希计算,将相同 IP 地址的请求始终分配到同一台服务器。 |
| 最少连接(Least Connections) | 将请求分配给当前连接数最少的服务器,确保负载均匀分布。 |

9. 使用 NGINX 作为 TCP 负载均衡器

NGINX 可以作为 TCP 负载均衡器,将 TCP 流量分发到多个后端服务器。以下是一个简单的配置示例:

stream {
    upstream tcp_backend {
        server backend1.example.com:8080;
        server backend2.example.com:8080;
    }

    server {
        listen 80;
        proxy_pass tcp_backend;
    }
}

上述配置中, stream 块用于配置 TCP 负载均衡。 upstream 定义了后端服务器组, server 块监听 80 端口,并将流量转发到 tcp_backend 组中的服务器。

10. 探索线程池和 I/O 机制

线程池是一种新的机制,用于缓解服务器在重负载下的压力,特别是由阻塞操作引起的负载。线程池的工作原理如下:
1. 当有请求到达时,线程池中的空闲线程会被分配来处理该请求。
2. 如果线程池中的线程都在忙碌,新的请求会被放入队列中等待处理。
3. 当线程完成请求处理后,会返回到线程池中,等待下一个请求。

NGINX 中的 I/O 机制主要有以下几种:
| 机制 | 描述 |
| — | — |
| 阻塞 I/O(Blocking I/O) | 线程在进行 I/O 操作时会被阻塞,直到操作完成。 |
| 非阻塞 I/O(Non - Blocking I/O) | 线程在进行 I/O 操作时不会被阻塞,可以继续处理其他任务。 |
| 异步 I/O(Asynchronous I/O) | 线程发起 I/O 操作后,会继续执行其他任务,当 I/O 操作完成时,会通过回调函数通知线程。 |

11. 负载均衡和线程池的配置示例

以下是一个结合负载均衡和线程池的 NGINX 配置示例:

events {
    worker_connections 1024;
    use epoll;
}

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

    server {
        listen 80;

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

    thread_pool default threads=32 max_queue=65536;
}

在上述配置中, events 块配置了事件处理机制, http 块中定义了后端服务器组 backend ,并将请求代理到该组中的服务器。 thread_pool 指令配置了线程池, threads 指定了线程池中的线程数量, max_queue 指定了请求队列的最大长度。

12. 总结

本文详细介绍了 NGINX 作为反向代理的各种指令和变量,包括代理相关指令、缓存和临时文件指令、限制和超时指令等。同时,探讨了 NGINX 在微服务架构中的应用,以及负载均衡和线程池的概念和使用方法。

通过合理配置 NGINX 的反向代理和负载均衡功能,可以提高服务器的性能、可用性和可扩展性,为用户提供更好的服务体验。在实际应用中,需要根据具体的业务需求和服务器性能,选择合适的配置参数和负载均衡算法。

graph LR
    A[客户端请求] --> B[NGINX 负载均衡器]
    B --> C1[后端服务器 1]
    B --> C2[后端服务器 2]
    B --> C3[后端服务器 3]
    C1 --> D[响应客户端]
    C2 --> D
    C3 --> D
    E[线程池] --> F[处理请求]
    F --> G[返回响应]

以上流程图展示了客户端请求通过 NGINX 负载均衡器分发到多个后端服务器,以及线程池处理请求的过程。通过对 NGINX 的深入了解和合理配置,可以充分发挥其在复杂系统中的优势,实现高效的 IT 基础设施部署。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值