从GAE数据存储区快速提供多个图像

时间:2012-02-24 11:48:29

标签: python http google-app-engine http-headers

我正在使用jinja使用格式

呈现填充了可变数量图像的页面
<img src="/image?id=x" />

图片网址指向从数据存储中检索相关图片并将其作为回复返回的处理程序,如下所述:http://code.google.com/appengine/articles/python/serving_dynamic_images.html

我遇到的问题是每个正在加载的图像之间有一个小的延迟,并且每个图像都是按顺序加载的,这意味着一个包含50个图像的页面需要花费不可接受的时间来加载。

有没有人知道解决这个问题的方法?感觉我应该以某种方式设置服务器以在多个线程上运行图像服务处理程序。

5 个答案:

答案 0 :(得分:1)

这可能不是AppEngine的限制。 AppEngine将自动扩展以满足请求。但是,浏览器仅限于对同一主机名的一定数量的同时请求 - 这取决于浏览器,有些允许用户配置,但在最近的浏览器中,限制似乎是6.请参阅this chart更多。

现在,限制是每个主机名,而不是每个域。因此,您实际上可以利用AppEngine将使用FOO-dot-APPNAME语法在任何子域上为您的应用提供服务的事实。例如,如果您的应用是myblog,则可以在img1-dot-myblog.appspot.comimg2-dot-myblog.appspot.com等服务,并且从浏览器的角度来看,这些并不算作同时连接

答案 1 :(得分:1)

就像Wobble指出的那样,dev_appserver.py服务器是单线程的。生产服务器可以在任何给定时间轻松地为多个图像提供服务,直至达到浏览器的限制。

但还有一些建议:你应该使用像/image_xxx.jpg或/images/xxx.jpg这样的URL并发送一个过期的标题。这应该可以防止重复下载您的图像。它还可以更轻松地将缓存指向后端,并从那里提供图像的缓存版本,而不是App Engine和您的应用程序。

这些想法应该会带你走得很远。如果达到此限制,您可以租用CDN服务并将其放在可缓存图像前面。

答案 2 :(得分:0)

首先阅读@Daniel Roseman的答案。他是正确的,注意到限制是在浏览器方面。现代桌面浏览器将并行请求限制为每个域6个或总共35-40个。

解决这个问题:

  1. 尝试将图片请求分散到多个主机名。您可以通过上传到不同的版本,例如,在GAE上执行此操作,例如img1.yourapp.appspot.comimg2.yourapp.appspot.com等。然后您可以通过将随机范围编号附加到img来生成版本前缀。

  2. 如果你有一个有点固定的图像超集,你可以将它们组合在一个图像中,并通过image sprites引用特定的图像。这样,您只需在一个请求中下载一个大图像。您可以通过创建合成ImagesServiceFactory.makeComposite(image, ...),然后将合成内容与ImagesService.composite(composites, ...)合并为一个图像,在App Engine上合并图像。

答案 3 :(得分:0)

你应该考虑在制作中使用serving_urls,所以如果你预设那些你不需要处理你身边的图像的网址,它们会加载更快。

图像上传后,创建一个serve_url并将其设置在您的实体上,这样您就可以直接将网址放入模板中而无需访问处理程序。

这不会使用sdk更改本地计算机上的任何内容。

答案 4 :(得分:0)

你提到的文章很老。使用梦幻般的高速图像API: get_serving_url(blob_key,size = None,crop = False) 这些图片将由Google以无负载为您的应用和高速提供服务。

我使用Jinja函数加载器生成服务URL。给你一个想法: 此模板行:

<img  {% include "front=698.jpg" %} /> 

将被翻译为:

<img   alt="front=698.jpg" src="http://lh3.ggpht.com/-obCxGmlnWZFU-UGRTA6juHNpNPJ90-XafQsYdCW_53ANDlzA4l33n-DBvevcI4urHu9Qa205ZOx5YBg3IU=s698" />

您甚至可以在运行时调整图像大小。顺便说一句:您必须将图像上传到应用程序blobstore。但服务是由谷歌完成的。 NO LOAD