5

一直在考虑在 Amazon Cloudfront 上缓存我的 JSON。

问题是在更新 JSON 时手动清除缓存可能需要 15 分钟。

有没有办法在类似 CDN 的 http 缓存中存储一​​个简单的 JSON 值 -

  • 初始生成后不接触应用程序服务器(heroku)
  • 允许我立即使缓存过期

更新

回应 AdamKG 的观点:

如果它正在“更新”,它不是静态的:D 编写一个新版本并告诉您的服务器使用新 URL。

我的实际想法是每次 html 页面更改时缓存一个新的 CloudFront url。那是我最初的关注点。

我想要 JSON 的原因是存储最新 CloudFront url 的版本号。这样我就可以进行 AJAX 调用以发现要加载的版本,然后再进行第二次 AJAX 调用以实际加载内容。这样我就不需要让 CloudFront 内容过期,我只需重定向 ajax 加载它。

但是后来我遇到了需要缓存 JSON 的问题。我不希望人们每次想要查看单个 JSON 版本号时都使用 Heroku 发电机。我知道 memcache 和 rack 可以帮助我加快速度,但这是我不想遇到的问题。

我的一些想法:

  • 也许有一个第三方服务,类似于 Memcache 数据库,它允许我在 JSON url 中公开一个值?这样我的发电机就永远不会被触及。
  • 也许有替代 Cloudfront 的方法可以更快地手动到期?我知道这有点违背缓存的本质,但也许还有更多的中介服务,比如清漆层或其他东西。
4

1 回答 1

4

一种方法是使用类似于 Rails 静态资产过期方式的资产过期。Rails 为文件名添加了一个哈希签名,所以像application.jsbecome application-abcdef1234567890.js. 然后,每次用户请求您的页面时,如果 application.js 已更新,则 script 标签具有新地址。

这是我设想你这样做的方式:

User → CloudFront (CDN) → Your App (Origin)

用户请求http://www.example.com/。该页面具有元标记

<meta content="1231231230" name="data-timestamp" />

基于您上次更新 JSON 资源的时间。<%= Widget.order(updated_at: :desc).pluck(:updated_at).first.to_i %>如果您使用的是 Rails ,这可能是由类似的东西生成的。

然后,在您的应用程序的 JavaScript 中,获取时间戳并将其用于您的 JSON url。

var timestamp = $('meta[name=data-timestamp]').attr('content');
$.get('http://cdn.example.com/data-' + timestamp + '.json', function(data, textStatus, jqXHR) {
  blah(data);
});

对 CloudFront 的第一个请求将到达您的源服务器/data/data-1231231230.json,可以永久生成和缓存。每次更新 JSON 时,用户都会获得一个新的 URL 来查询 CDN。

更新

由于您提到实际页面是您想要大量缓存的内容,因此您有几个选择。如果您真的希望 CloudFront 在您的服务器前面,那么您唯一真正的选择是在每次主页更新时发送一个失效请求。您可以每月免费失效 1,000 次,之后每 1,000 次失效 5 美元。此外,CloudFront 失效并不快,在页面更新之前您仍然会有延迟。

另一种选择是将您的内容缓存在 Memcached 中并从您的 dynos 中提供它。根据您的询问历史,我将假设您正在使用 Ruby on Rails 或其他 Ruby 框架(但请说明您是否不是)。这需要安装Rack::Cache。Heroku 上的说明用于缓存资产,但这也适用于动态内容。invalidate接下来,您将在每次更新页面时使用 Rack::Cache 的方法。是的,您的测功机将处理一些负载,但这将是一个简单的 Memcached 查找和响应。

您的服务器布局如下所示:

用户 → CloudFront (CDN) → Rack::Cache → 您在 cdn.example.com 上的应用程序 (Origin) User → Rack::Cache → 您在 www.example.com 上的应用程序 (Origin)

当您提供图片、CSS 和 JavaScript 等静态资产时,请使用 cdn.example.com 域。这将通过 CloudFront 路由请求,并且它们将被缓存很长时间。对您的应用程序的请求将直接发送到您的 Heroku 测功机,可缓存的部分将由 Rack::Cache 存储和检索。

于 2013-09-01T00:14:22.620 回答