引言

Nginx 作为一个高性能的反向代理服务器,经常用于负载均衡、HTTP 缓存等场景。在某些情况下,我们希望 Nginx 将多个请求合并为一个回源请求,以减少对后端服务器的压力,提高系统的性能。这种技术称为“合并回源”。

合并回源的原理

合并回源的基本思想是将多个相同的请求合并为一个请求,发送到后端服务器,然后将后端响应结果返回给所有请求。这可以显著减少后端服务器的负载,特别是在高并发、缓存失效的情况下。

在 Nginx 中,合并回源依赖于 proxy_cache_lockproxy_cache_use_stale 等配置指令。以下是其工作原理:

  1. 请求到来:当 Nginx 接收到一个请求时,会首先检查缓存。
  2. 缓存命中:如果缓存命中,直接返回缓存内容。
  3. 缓存未命中:如果缓存未命中,Nginx 会检查 proxy_cache_lock 配置。
  4. 锁定缓存:如果 proxy_cache_lock 启用,Nginx 会锁定该缓存键,阻止其他相同的请求直接回源。
  5. 等待缓存更新:其他相同的请求将等待第一个请求从后端获取数据并更新缓存。
  6. 缓存更新:第一个请求获取数据并更新缓存后,其他等待的请求会从缓存中获取数据并返回给客户端。

Nginx 合并回源配置

以下是一个典型的 Nginx 合并回源的配置示例:

http {
    proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m use_temp_path=off;

    server {
        listen 80;

        location / {
            proxy_cache my_cache;
            proxy_cache_valid 200 302 10m;
            proxy_cache_valid 404 1m;
            proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
            proxy_cache_lock on;
            proxy_cache_lock_timeout 5s;
            proxy_pass http://backend_server;
        }
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.

配置详解

  1. proxy_cache_path:定义缓存存储路径和缓存区域。
  • /var/cache/nginx:缓存文件的存储路径。
  • levels=1:2:缓存文件目录的层次。
  • keys_zone=my_cache:10m:定义缓存区域 my_cache,大小为 10MB。
  • max_size=1g:最大缓存空间为 1GB。
  • inactive=60m:超过 60 分钟未访问的缓存将被自动删除。
  • use_temp_path=off:禁用临时路径,提高性能。
  1. proxy_cache:启用缓存,指定缓存区域为 my_cache
  2. proxy_cache_valid:设置缓存的有效期。
  • 200 302 10m:对于 HTTP 200 和 302 响应,缓存 10 分钟。
  • 404 1m:对于 HTTP 404 响应,缓存 1 分钟。
  1. proxy_cache_use_stale:当后端服务器返回错误时,使用过期的缓存数据。
  • error timeout updating http_500 http_502 http_503 http_504:包括这些错误状态码。
  1. proxy_cache_lock:启用缓存锁定,以实现合并回源。
  2. proxy_cache_lock_timeout:设置缓存锁定的超时时间。
  3. proxy_pass:将请求代理到后端服务器 http://backend_server

合并回源的详细例子

假设我们有两个用户几乎同时访问同一个 URL /data,但此时缓存中没有对应的数据,Nginx 将如何处理?

  1. 用户 A 访问/data
  • Nginx 检查缓存,发现没有缓存数据。
  • Nginx 锁定 /data 的缓存键。
  • Nginx 向后端服务器发送请求以获取 /data 的数据。
  1. 用户 B 访问/data
  • Nginx 检查缓存,发现没有缓存数据。
  • 由于 /data 的缓存键已被锁定,用户 B 的请求将等待。
  1. 后端服务器响应
  • 后端服务器返回 /data 的数据。
  • Nginx 将数据缓存,并解锁 /data 的缓存键。
  • 用户 A 接收到数据。
  1. 用户 B 接收到缓存数据
  • Nginx 将缓存的数据返回给用户 B。

此时,后端服务器仅接收了一次请求,但 Nginx 处理了两个用户的请求,通过这种方式,合并回源显著减少了后端服务器的负载。

结论

通过合理配置 Nginx 的缓存机制和合并回源功能,我们可以显著提升系统的性能,减少对后端服务器的压力。在高并发和缓存失效的场景下,这种技术尤为重要。希望这篇文章能对你理解和配置 Nginx 的合并回源有所帮助。