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

时间:2015-02-25 16:48:16

标签: caching nginx couchdb server-side

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

CouchDB支持Etags,理想情况下我想要的是Nginx缓存Etags以及哑客户端。客户端不使用Etags,他们只会查询Nginx,后者使用其缓存的Etag进入CouchDB,然后将缓存的响应或新的响应发送回客户端。

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

1 个答案:

答案 0 :(得分:6)

我假设您已经查看varnish并且没有找到适合您的情况。有两种方法可以达到你想要的效果。

使用nginx

Nginx有一个默认caching mechanism,您可以configure供您使用。

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

使用Ngx_Lua,您可以使用shared dictionary缓存您的couchdb响应。顾名思义,共享字典在Ngx_Lua的执行环境中使用共享内存区域。这类似于proxy_cache在Nginx中的工作方式(它还在Nginx的执行环境中定义了一个共享内存区域),但附带的优点是可以对其进行编程。

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

  1. 您向couchdb提出请求
  2. 您保存{Url-Etag:response}
  3. 下次请求使用HEAD请求进入etags的相同url查询。
  4. 如果响应etag与{Url-Etag:response}对匹配,则发送缓存响应,否则使用(get / post)方法再次查询couchdb,并在将响应发送给客户端之前更新{Url-Etag:response}对。
  5. 当然,如果您手动编写缓存,则必须定义最大缓存大小和从缓存中删除旧项的机制。 lua_shared_dict指令可以帮助您定义缓存响应的内存大小。在共享字典中保存值时,您可以指定值将保留在内存区域的时间,之后它将自动过期。结合共享字典的max cache size参数和cache time参数,您应该能够为用户编写相当复杂的缓存机制。

    使用erlang

    由于couchdb是用erlang编写的,你的机器上已经有了erlang env。因此,如果您可以在其中进行编程,则可以使用mnesia创建非常强大的分布式缓存。步骤是一样的。 Erlang计时器可以与gen_*行为结合使用,以便您自动使用项目到期,而mnesia具有监视其内存使用情况的功能并通知您。这两种方法几乎相同,唯一的区别是可以分配mnesia。

    更新

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