Google App Engine - Кэширование сгенерированного HTML - PullRequest
21 голосов
/ 19 декабря 2009

Я написал приложение Google App Engine, которое программно генерирует кучу HTML-кода, который на самом деле является одинаковым выводом для каждого пользователя, который входит в мою систему, и я знаю, что это будет неэффективно, когда код будет запущен в производство. Итак, я пытаюсь найти лучший способ кеширования сгенерированных страниц.

Наиболее вероятный вариант - сгенерировать страницы и записать их в базу данных, а затем проверить время операции размещения базы данных для данной страницы и время последнего обновления кода. Затем, если код новее, чем последний, помещенный в базу данных (для определенного запроса HTML), новый HTML будет сгенерирован и обслужен, и кэширован в базу данных. Если код старше, чем последний, помещенный в базу данных, тогда я просто получу HTML-код непосредственно из базы данных и обработаю его (следовательно, избегая всех потерь процессора при создании HTML-кода). Я не только стремлюсь минимизировать время загрузки, но и минимизировать использование процессора.

Однако одна проблема, с которой я сталкиваюсь, заключается в том, что я не могу понять, как программно проверять, была ли обновлена ​​версия кода, загруженная в механизм приложений.

Я открыт для любых предложений по этому подходу или другим подходам для кеширования сгенерированного HTML.

Обратите внимание, что, хотя memcache может помочь в этой ситуации, я считаю, что это не окончательное решение, поскольку мне действительно нужно заново генерировать html только при обновлении кода (в отличие от каждого раза, когда истекает memcache).

Ответы [ 5 ]

6 голосов
/ 19 декабря 2009

В порядке скорости:

  1. Memcache
  2. кэшированный HTML в хранилище данных
  3. генерация полной страницы

Ваше решение для кэширования должно учитывать это. По сути, я бы рекомендовал использовать memcache в любом случае. В большинстве случаев это будет быстрее, чем доступ к хранилищу данных, и когда вы генерируете большой блок HTML, одним из основных преимуществ кэширования является то, что вам, возможно, не пришлось нести штраф за ввод-вывод в доступе к данным. хранить. Если вы кешируете, используя хранилище данных, у вас все еще есть штраф ввода / вывода. Разница между восстановлением всего и извлечением из кэшированного html в хранилище данных, вероятно, будет довольно небольшой, если у вас нет очень сложной страницы. Вероятно, лучше получить кучу очень быстрых попаданий в кеш от memcache и периодически выполнять полную регенерацию, чем каждый раз обращаться к хранилищу данных. Ничто не мешает вам сделать недействительным кэшированный HTML в memcache при обновлении, и если ваш трафик достаточно высок, чтобы гарантировать его, вы всегда можете использовать многоуровневую систему кэширования.

Однако моя главная проблема в том, что это преждевременная оптимизация. Если у вас еще нет трафика, сведите к минимуму кеширование. App Engine предоставляет набор действительно удобных инструментов анализа производительности, и вы должны использовать их для выявления узких мест после того, как у вас будет хотя бы несколько QPS трафика.

Каждый раз, когда вы проводите оптимизацию производительности, сначала измерьте! Многие «оптимизации» производительности оказываются либо медленнее, чем оригинал, либо совпадают, либо имеют отрицательные характеристики взаимодействия с пользователем (например, устаревшие данные). Не оптимизируйте, пока не убедитесь, что вам нужно.

5 голосов
/ 21 декабря 2009

Некоторое время назад я написал серию сообщений в блоге о написании системы ведения блогов в App Engine. Вы можете найти сообщение о статической генерации HTML-страниц особого интереса.

1 голос
/ 02 сентября 2015

Старая тема, но я все равно прокомментирую, так как технология немного продвинулась ... Еще одна идея, которая может или не может быть подходящей для вас, заключается в создании HTML-кода и его сохранении в облачном хранилище Google. Затем получите доступ к HTML через ссылку CDN, которую вам предоставляет облачное хранилище. Нет необходимости проверять memcache или ждать, пока хранилище данных не проснется при новых запросах. Я начал хранить весь мой JavaScript, CSS и другой статический контент (изображения, загрузки и т. Д.), Как это, для моих приложений appengine, и он хорошо работает для меня.

1 голос
/ 24 апреля 2012

Просто предоставьте статическую версию вашего сайта

На самом деле все намного проще, чем вы думаете.

Если у вас уже есть файл, содержащий все URL для вашего сайта (например, urls.py), половина работы уже выполнена.

Вот структура:

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

/ html - откуда будут доставляться статические файлы. urls.py содержит список всех URL для вашего сайта. Routers.py (если вы переместили маршруты из main.py) нужно будет изменить, чтобы вы могли видеть динамически генерируемую версию локально, но обслуживать статическую версию в производственном процессе. deploy.py - ваш универсальный генератор статических сайтов.

Зависит от того, как вы расположите свой модуль URL. Я лично использую его как универсальное средство для извлечения всех метаданных для страницы, кроме YMMV.

Пример:

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

Имея все URL-адреса сайта в структурированном формате, вы легко и просто сканируете свой сайт.

Конфигурация маршрута немного сложнее. Я не буду вдаваться в подробности, потому что есть слишком много разных способов, которыми это может быть достигнуто. Важной частью является код, необходимый для определения того, работаете ли вы на сервере разработки или производственного сервера.

Вот оно:

# 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 работает как любая другая статическая папка, поэтому она будет автоматически кэшироваться, а срок действия кэша будет таким же, как и у всех остальных ваших статических файлов.

Примечание. При этом обрабатывается сайт, на котором все страницы обслуживаются с уровня корневой папки. Если вам нужно более глубокое вложение папок, для этого потребуется небольшая модификация.

1 голос
/ 10 августа 2010

Это не полное решение, но может предложить несколько интересных опций для кэширования.

Кэширование внешнего интерфейса Google Appengine позволяет использовать способ кэширования без использования memcache.

...