简体   繁体   English

如何使用Rails缓存API将外部API请求缓存到SQL数据库?

[英]How can I cache external API requests to the SQL database using Rails cache API?

I'm just wondering how I can cache slow requests to external APIs in the database, as I do not want to maintain a memcache service, but I do want a distributed system that will work across multiple dynos and workers on heroku. 我只是想知道如何将缓慢的请求缓存到数据库中的外部API,因为我不想维护内存缓存服务,但是我确实想要一个分布式系统,该系统可以在heroku上的多个dyno和worker上工作。

I can do it by building my own cache table, but I'm wondering if there's an easier way, especially one that works with the existing caching syntax. 我可以通过构建自己的缓存表来做到这一点,但我想知道是否有一种更简单的方法,尤其是一种与现有缓存语法一起使用的方法。

Thanks! 谢谢!

You can cache just about anything in Rails via a call to Rails.cache.fetch . 您可以通过调用Rails.cache.fetch在Rails中缓存几乎所有内容。 You pass in a key for the cache to look up, and if there's a value in the cache (a "cache hit") then it will get used instead of your slow code. 您传入一个密钥以供缓存查找,如果缓存中有一个值(“缓存命中”),它将被使用,而不是您的慢代码。

Let's say we've got an API that takes two airport codes and a date, and returns the best price it can find. 假设我们有一个API,该API包含两个机场代码和一个日期,并返回可以找到的最佳价格。 This can be a slow lookup, so it's a good candidate for caching: 这可能是一个缓慢的查找,因此它是缓存的不错选择:

def find_best_price(start_airport, end_airport, date)
  Rails.cache.fetch(cache_key_for(start_airport, end_airport, date)) do
    AirportPriceAPI.find_best_price(start_airport, end_airport, date)
  end
end

# Different routes & dates will have different prices, so we 
# need to have different cache keys for them.
def cache_key_for(start_airport, end_airport, date)
  "best_price:#{start_airport}:#{end_airport}:#{date}"
end

You can configure the data store for your cache in config/application.rb by setting config.cache_store . 您可以通过设置config.cache_storeconfig/application.rb为缓存配置数据存储。 Rails has several kinds built in, but not all are suitable for Heroku. Rails内置了几种,但并非所有都适合Heroku。 You can't use the FileStore because dynos don't have persistent storage and it's not shared between dynos. 您不能使用FileStore因为dynos没有持久存储,并且dynos之间没有共享。 MemoryStore isn't shared across dynos and will be wiped out if your dyno restarts. MemoryStore不是在dyno之间共享的,如果您的dyno重新启动,它将被清除。

Your best bet for Heroku is the MemCacheStore . 对于Heroku最好的选择是MemCacheStore It's supported out-of-the-box in Rails, and Heroku will give you 30Mb of memcache space for free . Rails提供了开箱即用的支持,Heroku 将免费为您提供30Mb的内存缓存空间 It's fast and perfect for use between multiple dynos. 快速,完美,可在多个测功机之间使用。

But, if you did want to cache values in a database, you can provide your app with a custom cache class . 但是,如果您确实想在数据库中缓存值,则可以为您的应用程序提供自定义缓存类 All you have to do is extend ActiveSupport::Cache::Store and be sure to implement read , write , exist? 您要做的就是扩展ActiveSupport::Cache::Store并确保实现readwriteexist? , delete , and fetch . deletefetch And someone's already packaged a DB-backed cache store as a gem , so you don't even have to implement the low-level details yourself. 而且已经有人将DB支持的缓存存储打包为gem ,因此您甚至不必自己实现低级细节。 :) :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM