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 基础设施部署。
超级会员免费看
803

被折叠的 条评论
为什么被折叠?



