在App Engine上提供图像的问题(2种替代方案)

3

我计划推出一个漫画网站,提供漫画条(图像)。

我几乎没有提供/缓存图像的经验。

所以这是我正在考虑的两种方法:

1. 使用 LinkProperty

class Comic(db.Model)
  image_link = db.LinkProperty()
  timestamp = db.DateTimeProperty(auto_now=True)

优点: 图片是从磁盘空间中获取的(磁盘空间便宜,我理解吗?) 我可以轻松设置app.yaml的过期日期,以缓存内容到用户的浏览器中 我可以设置memcache以更快地检索实体(用于高流量)

2. 使用BlobProperty

我使用了这个教程,效果非常好。 http://code.google.com/appengine/articles/images.html

附带问题:我能否说使用BlobProperty有点像“保护”我的图片免受外部链接的影响?这意味着人们不能直接链接到漫画条

我对第二种方法有一些担忧。

  • 我显然可以将这些实体缓存在memcache中,以实现更快的读取。

但是:

  • 将图片存储在内存缓存(memcache)中是一个好的选择吗?我的图片很大(每张图片100-200kb)。我认为memcache只允许缓存4GB的数据?或者说每个memcached实体最多只能缓存1 MB,但是实体数量没有限制...

  • 如果appengine的内存缓存(memcache)失败了怎么办?-> 解决方案:我需要返回到数据存储(datastore)。

  • 如何在用户的浏览器中缓存这些图片?如果我使用方法1,我可以在app.yaml中轻松添加内容的过期日期,从而使图片在用户端被缓存。

想听听您的想法。 我应该使用方法1还是方法2?方法1听起来非常简单明了,我应该对它保持警惕吗?

[编辑] 如何解决这个两难问题?

两难问题:我最不想做的事情就是防止人们获取图片的直接链接并将其放在bit.ly上,因为用户将自动被重定向到我的服务器上的图片 (如果用户从主页面本身访问,则不会出现广告/内容等)。

3个回答

3
你将会使用大量带宽从服务器传输所有这些图像到客户端(浏览器)。请记住,appengine有一个最大的文件上传数量限制,我认为是1000,但最近可能已经增加。如果您想控制对文件的访问,我认为您不能使用选项#1。
选项#2很好,但如果您有大量内容,则带宽和存储成本将会很高。为了解决这个问题,人们通常转向内容分发网络(CDN)。Amazon S3和edgecast.com是支持基于令牌的访问URL的两个这样的CDN。也就是说,您可以在appengine应用程序中生成一个令牌,该令牌对IP地址、时间、地理位置和其他一些标准有效,并将带有此令牌的cdn url提供给请求者。CDN提供您的图像并根据令牌进行访问检查。这将帮助您控制访问,但请记住,如果有意愿,就会有方法,您无法100%地保护任何东西-但您可能会接近。
因此,您将不会将内容存储在appengine上,而是将其存储在cdn上,并使用appengine创建具有指向cdn上内容的令牌的url。
这里有一些关于已签名 URL 的链接。我使用了以下两个链接:

http://jets3t.s3.amazonaws.com/toolkit/code-samples.html#signed-urls

http://www.edgecast.com/edgecast_difference.htm - 看看“内容安全”


互联网带宽不是问题。在你的互联网带宽成本非常高之前,你的数据存储传输配额就会耗尽很多。 - JasonSmith
CDN并不会降低价格,但可以使网站加载更快,但成本更高。@jhs:如果需要,数据存储传输配额是不会用尽的,我们会作出相应调整。 - Nick Johnson
Nick,这取决于不同的情况。AppEngine大约是每GB $0.12,但我发现你可以与一些供应商进行议价以得到更少的费用。此外,为什么要使用DataStore和相关配额来存储静态图像块,当你可以将其放在CDN上并且不使用DataStore空间和API配额呢?在实践中,从金钱、开发时间和页面延迟方面考虑,这对我来说更为节省成本。 - dar

2
解决你的困境,我认为有几种选择:
1. 你可以使用 Flash 对象来渲染图片,并以某种加密格式从服务器下载图片。这需要大量的前期工作。
2. 你可以为每个图片创建一个一次性链接。每次生成网页时,都会随机生成一个链接。在允许一次访问后,图像服务代码将使该链接失效。如果你的网站流量很高,这将是一个非常资源密集型的方案。
然而,你需要考虑到,迫使人们看广告需要做多少工作,特别是当他们中的很多人将通过 Firefox 访问你的网站,而几乎没有什么办法可以规避 AdBlock。
在选择两种方法之间,有几件事情需要考虑。对于第一种选项,在存储图片作为静态文件的情况下,你只能通过进行 "appcfg.py update" 来添加新图片。由于 AppEngine 应用程序不允许你写入文件系统,因此你需要将新图片添加到开发代码中并进行代码部署。从网站管理的角度来看,这可能会很困难。此外,从 memcache 提供图像的服务可能不会比将它们作为静态文件提供服务更提高性能。
第二个选项,将图像放入数据存储区,确实保护了你的图像不被链接,只要你能通过逻辑控制它们是否被服务即可。然而,你将遇到的问题是做出这个决定很困难。请记住,HTTP 是无状态的,因此找到区分外部链接和内部链接的方法需要一些技巧。
我的个人感觉是,为了确保人们在看广告时不能看到你的漫画,跳过一个又一个的 hoops 并不是解决问题的正确方式。如果你发布的内容值得保护,人们会蜂拥而至,享受它。通过高流量,你将弥补绕过几个广告服务的任何人的损失。不要试图在消费者面前聪明,提供杰出的内容,你将赚取足够的钱。

0

你的第一种方法不太实用:每次添加新的漫画条目都需要上传一个新版本的应用程序。

你的第二种方法应该可以正常工作。它并不能自动“保护”你的图像免受热链接 - 它们仍然会在像其他图像一样的 URL 上提供 - 但是你可以在图像服务处理程序中编写任何代码来尝试防止滥用。

第三个选项,也是第二个选项的变体,是使用新 Blob API。你可以将图像本身存储在数据存储中,也可以存储 blob key,你的图像处理程序只需指示 blobstore 基础架构要提供哪个图像即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接