nginx proxy_cache:限制同一 URL 的并行请求

Ger*_*ert 5 nginx reverse-proxy load-balancing

我们使用 nginx 作为反向代理从上游服务器获取文件。\n这些文件不是动态的 \xe2\x80\x93 至少不是基于每个请求 \xe2\x80\x93 并且(有时)落后于高潜伏。

\n\n

我想将对相同 URL 的请求限制为 1。

\n\n

我想避免的行为示例:

\n\n
127.0.0.1 - - [03/Jan/2013:16:08:15 +0100] "GET /part-00132.ts HTTP/1.0" 200 1506068 "-" "Prefetch" "-"\n127.0.0.1 - - [03/Jan/2013:16:08:28 +0100] "GET /part-00133.ts HTTP/1.0" 200 1189476 "-" "Prefetch" "-"\n127.0.0.1 - - [03/Jan/2013:16:08:29 +0100] "GET /part-00133.ts HTTP/1.0" 200 1189476 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/536.26.17 (KHTML, like Gecko) Version/6.0.2 Safari/536.26.17" "-"\n127.0.0.1 - - [03/Jan/2013:16:08:34 +0100] "GET /part-00133.ts HTTP/1.0" 200 1189476 "-" "Prefetch" "-"\n127.0.0.1 - - [03/Jan/2013:16:08:44 +0100] "GET /part-00134.ts HTTP/1.0" 200 1762876 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/536.26.17 (KHTML, like Gecko) Version/6.0.2 Safari/536.26.17" "-"\n127.0.0.1 - - [03/Jan/2013:16:08:53 +0100] "GET /part-00135.ts HTTP/1.0" 200 1627704 "-" "Prefetch" "-"\n127.0.0.1 - - [03/Jan/2013:16:08:59 +0100] "GET /part-00136.ts HTTP/1.0" 200 1252456 "-" "Prefetch" "-"\n127.0.0.1 - - [03/Jan/2013:16:09:03 +0100] "GET /part-00134.ts HTTP/1.0" 200 1762876 "-" "Prefetch" "-"\n127.0.0.1 - - [03/Jan/2013:16:09:04 +0100] "GET /part-00137.ts HTTP/1.0" 200 1120292 "-" "Prefetch" "-"\n127.0.0.1 - - [03/Jan/2013:16:09:07 +0100] "GET /part-00135.ts HTTP/1.0" 200 1627704 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/536.26.17 (KHTML, like Gecko) Version/6.0.2 Safari/536.26.17" "-"\n127.0.0.1 - - [03/Jan/2013:16:09:12 +0100] "GET /part-00134.ts HTTP/1.0" 200 1762876 "-" "Prefetch" "-"\n127.0.0.1 - - [03/Jan/2013:16:09:14 +0100] "GET /part-00136.ts HTTP/1.0" 200 1252456 "-" "Prefetch" "-"\n127.0.0.1 - - [03/Jan/2013:16:09:17 +0100] "GET /part-00135.ts HTTP/1.0" 200 1627704 "-" "Prefetch" "-"\n127.0.0.1 - - [03/Jan/2013:16:09:17 +0100] "GET /part-00138.ts HTTP/1.0" 200 1248884 "-" "Prefetch" "-"\n
Run Code Online (Sandbox Code Playgroud)\n\n

应该是这样的:

\n\n
127.0.0.1 - - [03/Jan/2013:16:08:15 +0100] "GET /part-00132.ts HTTP/1.0" 200 1506068 "-" "Prefetch" "-"\n127.0.0.1 - - [03/Jan/2013:16:08:28 +0100] "GET /part-00133.ts HTTP/1.0" 200 1189476 "-" "Prefetch" "-"\n127.0.0.1 - - [03/Jan/2013:16:08:44 +0100] "GET /part-00134.ts HTTP/1.0" 200 1762876 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/536.26.17 (KHTML, like Gecko) Version/6.0.2 Safari/536.26.17" "-"\n127.0.0.1 - - [03/Jan/2013:16:08:53 +0100] "GET /part-00135.ts HTTP/1.0" 200 1627704 "-" "Prefetch" "-"\n127.0.0.1 - - [03/Jan/2013:16:08:59 +0100] "GET /part-00136.ts HTTP/1.0" 200 1252456 "-" "Prefetch" "-"\n127.0.0.1 - - [03/Jan/2013:16:09:04 +0100] "GET /part-00137.ts HTTP/1.0" 200 1120292 "-" "Prefetch" "-"\n127.0.0.1 - - [03/Jan/2013:16:09:17 +0100] "GET /part-00138.ts HTTP/1.0" 200 1248884 "-" "Prefetch" "-"\n
Run Code Online (Sandbox Code Playgroud)\n\n

更新:

\n\n

稍微描述一下问题的图:

\n\n
            nginx              upstream\n           +-----+            +--------+\n           |     |            |        |\n   A +----->     +-----------------+   |\n           |     |            |    |   |\n   B +----->     +--------------+  |   |\n           |     |            | |  |   |\n     <-----+     <--------------|--+   |\n           |     |            | |      |\n     <-----+     <--------------+      |\n           |     |            |        |\n   C +----->     +---+        |        |\n           |     |   |        |        |\n     <-----+     <---+        |        |\n           |     |            |        |\n           +-----+            +--------+\n
Run Code Online (Sandbox Code Playgroud)\n\n

所以我希望客户B等待回复A

\n

Gru*_*mpy 0

对您来说一种潜在的解决方案是缓存。当将 proxy pass 或 fcgi pass 与 nginx 一起使用时,您可以选择将返回数据缓存一段时间。您可以在文档中阅读更多相关信息:proxy passfcgi version。两者的工作方式几乎完全相同。

我还建议查找一些有关它的教程,因为缓存操作的各部分如何协同工作对于文档来说并不完全是微不足道的。

但主要思想是从您的 URL(在您的情况下)创建一个代理“密钥”。然后你可以将其设置为缓存 10 分钟或其他时间。因此后续调用将从本地缓存提供服务,而不是再次获取。

然后,您可以通过设置来阻止更新期间的后续请求:

proxy_cache_use_stale updating;
Run Code Online (Sandbox Code Playgroud)