2

使用 Nginx 缓存代理使您的后端更可靠

 1 year ago
source link: https://www.jdon.com/61475
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

使用 Nginx 缓存代理使您的后端更可靠
我们大多数人都熟悉 Nginx——它是一个非常流行的 Web 服务器和反向代理。但是您知道您也可以将它用作缓存代理吗?
现在,您可能想知道为什么有人想做这样的事情——您不能更新您的服务以在 Redis 或 Memcached 中缓存数据吗?将缓存外部化到服务之外的单独层有什么好处?
以下是一些可能有用的场景:

  • 即使您的服务出现故障,您也希望提供缓存数据
  • 当您的服务响应时间过长时,您希望提供缓存数据
  • 当负载很大时,您想保护您的服务
  • 您有一个遗留系统,您希望使其更加可靠和高性能,但您无法更改代码
  • 您想让外部 3rd 方服务更可靠、更高效
  • 您正在使用多语言微服务架构并想要一种缓存请求的标准方式

现在您已经感兴趣了,让我们一步一步地完成实现。

简单实现

events {
    worker_connections 1024;
}

http {
+   proxy_cache_path /var/cache/nginx keys_zone=my_cache:10m;

    server {
        listen 3000;
+       proxy_cache my_cache;

        location / {
            proxy_set_header Host $host;
            proxy_pass http://my-backend-service/;
+           proxy_cache_key $scheme://$host$uri$is_args$query_string;
+           proxy_cache_valid 200 10m;
        }
    }
}

增加了一些新的指令,让我们逐一来看看。
Nginx将响应缓存在磁盘中,proxy_cache_path指定了存储响应的路径。
proxy_cache定义了用于存储缓存密钥和其他元数据的共享内存区。
proxy_cache_key定义了缓存密钥。
proxy_cache_valid指定了缓存过期,这也可以通过从后端服务发送缓存头信息来动态配置。一旦缓存过期,响应就不再被认为是 "新鲜的",而成为 "陈旧的stale"。

Nginx并没有立即删除陈旧的响应,而是将它们保留在磁盘中。为什么不删除它们的原因将在接下来的几节中变得更加明显。我们可以使用proxy_cache_path指令中的参数inactive来控制在删除陈旧的响应之前在磁盘中保留多长时间。起初可能会对proxy_cache_valid和inactive配置如何协同工作感到困惑,因为它们似乎在做类似的事情,让我们用下面的例子来清楚地了解。

如果proxy_cache_valid被设置为5m,inactive被设置为10m。如果第一个请求是在T0分钟时提出的,下一个请求是在T6分钟时提出的,那么第二个请求就需要从后端服务中获取,尽管数据仍然在磁盘中,因为缓存已经过期。相反,如果proxy_cache_valid被设置为10分钟,inactive被设置为5分钟,并且第一个请求在T0分钟到来,下一个请求在T6分钟到来,即使缓存没有过期,数据也会从磁盘中删除,所以需要再次从后端服务获取。

当后端关闭或缓慢时提供缓存数据
这是使用单独缓存代理的杀手级应用程序。当后端服务关闭或响应时间过长时,我们可以将 Nginx 配置为提供陈旧的响应。

events {
    worker_connections 1024;
}

http {
-   proxy_cache_path /var/cache/nginx keys_zone=my_cache:10m;
+   proxy_cache_path /var/cache/nginx keys_zone=my_cache:10m inactive=1w;

    server {
        listen 3000;
        proxy_cache my_cache;

        location / {
            proxy_set_header Host $host;
            proxy_pass http://my-backend-service/;
            proxy_cache_key $scheme://$host$uri$is_args$query_string;
            proxy_cache_valid 200 10m;
            proxy_cache_bypass $arg_should_bypass_cache;
+           proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504 http_429;
        }
    }
}

我们更新了proxy_cache_path,加入了之前提到的非活动参数,并加入了proxy_cache_use_stale指令,参数如下。

error - 如果后端无法到达,则使用stale。

timeout - 如果后端响应时间过长,则使用stale。

http_xxx - 如果后端返回这些状态代码,则使用stale。

默认情况下,超时被设置为60秒,可以使用proxy_connect_timeout指令进行配置。

正如你所看到的,只需几行代码,我们就可以很容易地将缓存添加到你的服务中。虽然缓存只在公共端点层面上起作用,但它应该是一个很好的起点,以后可以添加Redis等来缓存你服务中的中间计算。由于它是一个独立的代理,它也可以被添加到你的后端和传统的或外部服务之间。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK