使用Web服务时进行缓存

时间:2011-03-22 14:46:13

标签: ruby-on-rails ruby

假设我有一个天气网络服务,我正在点击(消费)每个页面加载。不是非常有效或聪明,可能会超出我的API限制或使网络服务所有者疯狂。因此,我没有直接从控制器操作中获取,而是有一个帮助器/作业/方法(某个层),它有机会稍微缓存数据。我们还要说,我不太关心数据的实时性。

现在我所做的只是将气象服务中的属性存储在表格中,并经常刷新数据。例如,气象服务可能如下所示:

Weather for 90210 (example primary key)
-----------------------------
Zip Name: Beverly Hills
Current Temperature: 90
Last Temp: 89
Humidity: 0
... etc.

所以在这种情况下,我会为每个属性创建列,并在从webservice中获取时存储它们。我可以有一个到期的rails动作(页面缓存)来进行刷新,或者我可以做一个后台工作。

这种简单的方法很有效,除非webservice有一个很大的属性列表(比如1000)。现在我花了很多时间创建和维护DB列,重复已经存在的其他人的属性。如果我可以简单地缓存整个响应并在需要时将其称为简单哈希,那将是多么伟大的事情。然后我将Web服务提供的所有属性缓存为“免费”,因为Web服务的所有功能都在我的Hash中,而不仅仅是缓存子集。

为此,我可以获取webservice响应,序列化它(可能是YAML),然后获取序列化对象(如果存在)。嗯,不是很好。序列化可能会因特殊字符而变得奇怪。如果我可以只遵循memcached类型模型,那真的很酷,但我认为你不能在memcached中存储复杂的对象吗?我还想限制引入的软件数量,因此一个独立的代理层可能不是最理想的。

任何人做过类似的事情或者有这个名字吗?

2 个答案:

答案 0 :(得分:4)

如果您正在使用的API是RESTful并且尊重缓存,请不要重新发明轮子。 HTTP内置了缓存(请参阅RFC 2616),因此请尽量使用它。您有两种选择:

  1. 只需在您的应用和API之间添加一个squid代理,就可以了。
  2. 使用Wrest - 我们编写它来支持HTTP 2616缓存,它是我所知道的唯一的Ruby HTTP包装器。
  3. 如果API不尊重缓存(大部分都是这样),那么您收到的其他建议是有道理的。你实际使用什么来保存你的缓存(mongodb / memcached /等等)取决于一系列其他因素,所以真的,这取决于你的情况。

答案 1 :(得分:1)

您可以使用MongoDB(或其他JSON数据存储区)并以JSON格式获取API的结果,将结果存储到您的mongo集合中。然后获取您关心的数据和属性,忽略其余部分。

对于您的天气API调用,您可以检查您的mongo集合中是否存在该城市,如果没有通过API获取(然后存储在mongo中)。

这将是对Rails.cache模式的修改。