我们的webapp将执行API调用以检索图像。这些图片可以在合理的时间内缓存,如条款中所述,因此我们不必在每个页面请求中访问其他网站的服务器。
我不熟悉缓存,但我只是看了一些关于一些不同方法的Railscast。 page caching
,fragment caching
,dynamic page caching
。它们都有助于减少请求,从而降低我的应用程序的速度。
但我如何通过“缓存”#39;来自我服务器上其他网站的图片?这样做的正确方法是什么?是否有任何功能可以达到此目的?
将向我的cache_outdates_at
模型添加时间戳Image
,并将其设置为未来一个月。每当图像再次加载时,它都会更新时间戳。
然后我添加一个cronjob来检查过时的图像,然后删除它们。
答案 0 :(得分:3)
好问题。如果你在盒子外面看问题,那就相当容易了。
检索第三方服务器映像时,只需复制该映像并将其放入服务器或CDN中。并且,使用它。为此,你必须设置一些方法,如
# app/model/image.rb
def image_link(name_of_image)
if File.exist? "/some/#{name_of_image}.jpg"
path = "/some/#{name_of_image}.jpg"
else
external_image_link = external_api_call(name_of_image)
DownloadImageWorker.perform_async(external_image_link) // perform it asynchronously
external_image_link
end
答案 1 :(得分:1)
我建议您不要使用代码来混淆您的Rails应用程序以缓存异地资产。而是使用为作业构建的HTTP代理,例如Squid。看一下缓存场外视频的example Squid configuration。
因此,您的webapp只需要重写URL,例如,将cache.example.com
或者缓存服务器的主机名添加到其生成的URL中。设置通配符DNS条目,以便*.cache.example.com
都指向您的Squid服务器。 Squid可以配置为重写域,获取远程资产并提供服务。
Squid会自动为您完成所有缓存管理,包括弹出陈旧项目。作为奖励,性能可能比Rails更好。
答案 2 :(得分:0)
我可以与您分享我自己的方法来缓存外部图像。此外,当我解决此类任务时,我需要在更新基础外部图像时更新我身边的图像。
外部服务使用电子标签来签名图像,所以我下一步使用此功能。
我有Photo
模型,其中存储了external_url
和etag
,以及有关图像的一些信息(在我的情况下,载波的图像名称)。
所以,我从某些API收到了image_url
,我想在我的服务器上上传这张图片,并且不想加载外部服务器。
photo = Photo.find_or_initialize_by(external_url: image_url)
img_responce = Faraday.get do |req|
req.url image_url
if photo.etag
req.headers['If-None-Match'] = photo.etag
end
end
case img_responce.status
when 200
# This mean, image changes (or new)
photo.update external_url: image_url,
etag: img_responce.headers['etag'],
image: StringIO.new(img_responce.body)
when 304
# This mean, image doesn't change
end