代码之家  ›  专栏  ›  技术社区  ›  Gabor Csardi

使用Nginx和Etags对动态内容进行服务器端缓存

  •  5
  • Gabor Csardi  · 技术社区  · 10 年前

    我有一个CouchDB,前面有一个Nginx反向代理。CouchDB的一些响应需要很长时间才能生成(是的,这是一个糟糕的选择,但现在需要坚持使用),我想用Nginx缓存它们。(目前Nginx仅支持SSL。)

    CouchDB支持Etags,所以理想情况下,我希望Nginx也为哑客户端缓存Etags。客户端不使用Etag,它们只会查询Nginx,Nginx将其缓存的Etag返回CouchDB,然后将缓存的响应或新的响应发送回客户端。

    根据文档,我的理解是Nginx目前无法做到这一点。我错过了什么吗?是否有支持此设置的替代方案?或者唯一的解决方案是手动使Nginx缓存无效?

    1 回复  |  直到 10 年前
        1
  •  7
  •   Community CDub    4 年前

    我假设你已经看过 varnish 而且不适合你的情况。有两种方法可以实现你想要的。

    使用nginx

    Nginx具有默认值 caching mechanism 你能做到的 configure 供您使用。

    如果这没有帮助,您应该将与第三方编译的Nginx Ngx_Lua module 尝试一下。这也方便地与其他有用的模块和所需的Lua环境一起打包,如 Openresty .

    使用Ngx_Lua,可以使用 shared dictionary 缓存你的couchdb响应。顾名思义,共享字典在Ngx_Lua的执行环境中使用共享内存区域。这类似于proxy_cache在Nginx中的工作方式(它还定义了Nginx的执行环境中的共享内存区域),但具有可以编程的额外优势。

    构建couchdb缓存所需的步骤非常简单(使用这种方法,您不需要向客户端发送etag)

    1. 你向couchdb提出请求
    2. 您保存 {Url-Etag:response} 一对
    3. 下一次,请求使用HEAD请求返回到etag的同一url查询。
    4. 如果响应etag与 {Url Etag:响应} 然后pair发送缓存的响应,否则使用(get/post)方法再次查询couchdb并更新 {Url Etag:响应} 在向客户端发送响应之前。

    当然,如果您手动编程缓存,则必须定义最大缓存大小和从缓存中删除旧项的机制。这个 lua_shared_dict 指令可以帮助您定义缓存响应的内存大小。在共享字典中保存值时,您可以指定值保留在内存区域的时间,在该时间之后,值将自动过期。结合共享字典的最大缓存大小参数和缓存时间参数,您应该能够为用户编程相当复杂的缓存机制。

    使用erlang

    因为couchdb是用erlang编写的,所以您的机器上已经有了erlang env。所以如果你能在其中编程,你就可以用mnesia创建一个非常健壮的分布式缓存。步骤相同。Erlang计时器可以与 gen_* 行为让你的物品自动过期,而记忆具有监控其内存使用情况并通知你的功能。这两种方法几乎相同,唯一的区别是记忆可以被分发。

    使现代化

    正如@abyz所建议的 redis 在缓存方面也是一个不错的选择。