首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Rails 3-缓存web服务调用

Rails 3-缓存web服务调用
EN

Stack Overflow用户
提问于 2011-08-30 12:35:42
回答 3查看 1.7K关注 0票数 6

在我的应用程序中,在homepage操作中,我调用了一个返回JSON的特定web服务。

代码语言:javascript
复制
parsed = JSON.parse(open("http://myservice").read)
@history = parsed['DATA']

此数据不会每60秒更改一次,并且不会针对每个访问者进行更改,因此,理想情况下,我希望缓存@history变量本身(因为解析不会产生新的结果),如果它超过一分钟,则自动使其无效。

我不确定做这件事的最好方法。默认的Rails缓存方法似乎都更倾向于需要手动过期的内容。我相信有一个快速而简单的方法可以做到这一点,我只是不知道它是什么!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-08-30 16:36:35

您可以使用内置的Rails缓存来执行以下操作:

代码语言:javascript
复制
@history = Rails.cache.fetch('parsed_myservice_data', :expires_in => 1.minute) do
  JSON.parse connector.get_response("http://myservice")
end

这种方法的一个问题是,重建要缓存的数据需要相当长的时间。如果您在这段时间内收到许多客户端请求,每个请求都将获得缓存未命中并调用您的块,导致大量重复工作,更不用说响应时间较慢了。

编辑:在Rails 3.x中,您可以将选项:race_condition_ttl传递给fetch方法以避免此问题。有关它的更多信息,请阅读here

在以前的Rails版本中,一个很好的解决方案是设置一个定期运行的后台/cron作业,该作业将获取和解析数据并更新缓存。

在您的控制器或模型中:

代码语言:javascript
复制
@history = Rails.cache.fetch('parsed_myservice_data') do
  JSON.parse connector.get_response("http://myservice")
end

在您的后台/cron作业中:

代码语言:javascript
复制
Rails.cache.write('parsed_myservice_data',
  JSON.parse connector.get_response("http://myservice"))

这样,您的客户端请求将始终获得最新的缓存数据(如果后台/cron作业尚未运行,则第一个请求除外)。

票数 6
EN

Stack Overflow用户

发布于 2011-08-30 13:00:30

我不知道有什么简单易懂的方法可以做到这一点。你可能会考虑使用redis。Redis允许您设置存储在其中的数据的过期时间。根据你使用的redis gem,它看起来像这样:

代码语言:javascript
复制
@history = $redis.get('history')

if not @history
  @history = JSON.parse(open("http://myservice").read)['DATA']
  $redis.set('history', @history)
  $redis.expire('history', 60)
end

因为只有一个redis服务,所以这将适用于所有的rails进程。

票数 1
EN

Stack Overflow用户

发布于 2011-08-30 13:21:52

我们有一个类似的需求,我们最终使用Squid作为来自rails服务器的所有webservice调用的转发代理。Squid配置为缓存过期时间为60秒。

http_connection_factory.rb:

代码语言:javascript
复制
class HttpConnectionFactory
  def self.connection
    AppConfig.use_forward_proxy ? Net::HTTP::Proxy(AppConfig.forward_proxy_host, AppConfig.forward_proxy_port) : Net::HTTP
  end
end

在应用程序的主页操作中,您可以使用代理而不是直接进行调用。

代码语言:javascript
复制
connector = HttpConnectionFactory.connection 
parsed = JSON.parse(connector.get_response("http://myservice"))
@history = parsed['DATA']

对于使用RedisMemcache,我们有了另一种想法。但是,我们有几个服务调用,希望避免生成密钥并在适当的时候清除它们的所有麻烦。

因此,在我们的案例中,转发代理处理了所有这些细节。必要的配置参数请参考Squid Wiki

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7238753

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档