Google App Engine - 缓存生成的HTML

时间:2009-12-18 22:08:33

标签: html google-app-engine caching

我编写了一个Google App Engine应用程序,以编程方式生成一堆HTML代码,这些代码对于登录我系统的每个用户来说实际上是相同的输出,我知道当代码进入时,这将是无效的投入生产。所以,我试图找出缓存生成的页面的最佳方法。

最可能的选择是生成页面并将它们写入数据库,然后检查给定页面的数据库放置操作的时间与上次更新代码的时间。然后,如果代码比最后一次放入数据库(对于特定的HTML请求)更新,则将生成并提供新的HTML,并将其缓存到数据库。如果代码比上次放入数据库的时间要早​​,那么我将直接从数据库中获取HTML并为其提供服务(因此避免了生成HTML的所有CPU浪费)。我不仅希望最大限度地减少加载时间,还要尽量减少CPU使用率。

然而,我遇到的一个问题是,我无法弄清楚如何以编程方式检查上传到应用引擎的代码版本何时更新。

我愿意接受有关此方法的任何建议,或其他用于缓存生成的html的方法。

请注意,虽然memcache可以在这种情况下提供帮助,但我认为它不是最终的解决方案,因为我真的只需要在代码更新时重新生成html(而不是每次memcache到期时)。

5 个答案:

答案 0 :(得分:6)

按速度顺序:

  1. 内存缓存
  2. 在数据存储中缓存HTML
  3. 整页生成
  4. 您的缓存解决方案应考虑到这一点。基本上,我可能会建议使用memcache。在大多数情况下,它比访问数据存储更快,当您生成大块HTML时,缓存的主要好处之一是您可能不必因访问数据而导致I / O损失商店。如果使用数据存储进行缓存,则仍会产生I / O损失。除非你有一个非常复杂的页面,否则重新生成所有内容和从数据存储中的缓存html拉取之间的区别可能相当小。从memcache中获取一堆非常快的缓存命中并且每隔一段时间进行一次完全重新生成可能比每次调用数据存储更好。在更新时,没有什么可以阻止你在memcache中使缓存的HTML失效,如果你的流量足够高,可以保证它,你总是可以做一个多级缓存系统。

    然而,我主要担心的是这是不成熟的优化。如果您还没有流量,请将缓存保持在最低限度。 App Engine提供了一组非常方便的性能分析工具,在您获得至少几个QPS流量后,您应该使用它们来识别瓶颈。

    无论何时进行性能优化,请先测量!许多性能“优化”要么比原来慢,要么完全相同,要么具有负面的用户体验特征(如陈旧数据)。在你必须确定之前不要进行优化。

答案 1 :(得分:5)

不久前我写了关于在App Engine上编写博客系统的a series of blog posts。您可能会发现特别感兴趣的static generation of HTML pages帖子。

答案 2 :(得分:1)

这不是一个完整的解决方案,但可能会提供一些有趣的缓存选项。

Google Appengine Frontend Caching允许您在不使用memcache的情况下进行缓存。

答案 3 :(得分:1)

只需投放您网站的静态版本

实际上比你想象的容易得多。

如果您的文件已包含您网站的所有网址(ex urls.py),则已完成一半的工作。

这是结构:

+-/website
+--/static
+---/html
+--/app/urls.py
+--/app/routes.py
+-/deploy.py

/ html是从中提供静态文件的位置。 urls.py包含您网站的所有网址列表。 routes.py(如果您将路由移出main.py)将需要进行修改,以便您可以在本地查看动态生成的版本,但在生产中提供静态版本。 deploy.py是您的一站式静态站点生成器。

如何布局您的网址模块取决于。我个人使用它作为一站式商店来获取页面的所有元数据,但YMMV。

示例:

main = [
  { 'uri':'about-us', 'url':'/', 'template':'about-us.html', 'title':'About Us' }
]

网站的所有网址都采用结构化格式,因此可以轻松抓取您自己的网站。

路线配置稍微复杂一些。我不会详细说明,因为有太多不同的方法可以实现。重要的部分是检测您是否在开发或生产服务器上运行所需的代码。

这是:

# Detect whether this the 'Development' server
DEV = os.environ['SERVER_SOFTWARE'].startswith('Dev')

我更喜欢将它放在main.py中并将其全局公开,因为我使用它来打开/关闭其他内容,例如日志记录,但是,再一次,YMMV。

最后,您需要爬虫/编译器:

import os
import sys
import urllib2
from app.urls import main

port = '8080'
local_folder = os.getcwd() + os.sep + 'static' + os.sep + 'html' + os.sep
print 'Outputting to: ' + local_folder

print '\nCompiling:'
for page in main:
  http = urllib2.urlopen('http://localhost:' + port + page['url'])
  file_name = page['template']
  path = local_folder + file_name
  local_file = open(path, 'w')
  local_file.write(http.read())
  local_file.close()
  print ' - ' + file_name + ' compiled successfully...'

这是非常基本的东西。实际上,当我创建它时,我感到非常震惊。这实际上相当于在浏览器中逐页打开您的网站,保存为html,并将该文件复制到/ static / html文件夹中。

最好的部分是,/ html文件夹的工作方式与任何其他静态文件夹一样,因此它将自动缓存,缓存过期将与所有其他静态文件相同。

注意:这会处理从根文件夹级别提供所有页面的网站。如果您需要更深层次的文件夹嵌套,则需要稍作修改才能处理。

答案 4 :(得分:1)

旧线程,但我会评论,因为技术进步了一点...... 另一个可能适合或不适合您的想法是生成HTML并将其存储在Google云端存储上。 然后通过云存储为您提供的CDN链接访问HTML。 无需检查内存缓存或等待数据存储区唤醒新请求。 我已经开始将我的所有JavaScript,CSS和其他静态内容(图像,下载等)存储到我的appengine应用程序中,并且对我来说效果很好。