Обзор Google App Engine

Введение

В этой статье я постараюсь немножко рассказать про:

  • что можно разрабатывать на GAE
  • чем Google App Engine (GAE) отличается от обычных решений
  • философию разработки высоко-доступных сервисов
  • обзор некоторых компонентов
  • цикл разработки/обучения разработчика
  • подводные камни
  • куда смотреть дальше

Для того, чтобы вы понимали хорошо материал от вас требуется:

  • знание основ HTML
  • знание основ работы протокола HTTP
  • базовое знание архитектурного паттерна MVC

Что можно разрабатывать на GAE

Если коротко, GAE отлично подходит для почти любых веб приложений, сайтов, и мобильных бэкэндов. Когда я пишу мобильный бэкэнд, я подразумеваю сервер предоставляющий какой-то ваш API для приложения или приложений. GAE также подойдет для задач сбора и обработки данных, в данной статье это не покрывается. Также будет отличным решением в задачах взаимодействия типа сервер-сервер.

Чем Google App Engine отличается от обычных решений

Во-первых, если пойти на главный сайт GAE, то можно увидеть 3 слогана:

  • Zero to sixty
  • Supercharged APIs
  • You're in control

Каждый из этих слоганов характеризует основные отличия от стандартных решений. Возьмем к примеру первый «Zero to sixty», он означает, что можно совершенно не заботиться о горизонтальном масштабировании. Соответственно нет нужды в ручном контроле различных серверов. И действительно, GAE не предоставляет средств для ручной настройки серверов. Единственное, что вам доступно — только ваше приложение.

Второй слоган, «Supercharged APIs», описывает основной способ взаимодействия вашего приложения и инфраструктуры. Фактически ваше приложение будет жить в некой песочнице и пользоваться различными сервисами через их API. Это очень удобно, так как достигается очень строгое разделение обязанностей. Что в свою очередь минимизирует возможность ошибки со стороны программиста, например когда он делает какую-то фичу, и в попытке сделать быстро делает это через какой-то «хак», который может создать проблему. В GAE это будет почти не возможно.

Третий слоган, «You're in control», означает что вы будете все контролировать, потребление ресурсов, статистику и прочее через специальный веб сервис. Т.е. даже человек с минимальными знаниями может этим заниматься. На практике вам дается две важные настройки, это время отклика вашего приложения и сколько экземпляров приложения будут находиться в ожидании запросов. По умолчанию они стоят в авто и этого хватает. В будущем когда ваше приложение будет популярно эти настройки помогут либо добиться увеличения скорости, либо понизить затраты на оплату, но не вместе. Справедливости ради, нужно отметить, что это касается frontend экземпляров приложения, другие сервисы тоже можно настраивать в определенных пределах. Думаю основной смысл должен быть понятен.

В остальном вы также разрабатываете приложение в веб парадигме, т.е. «запрос-ответ». Причем используются стандартные компоненты из библиотек языка, на котором вы разрабатываете.

Отдельно стоит отметить форму оплаты. Во-первых вы платите, только за использованные ресурсы. Это удобно, особенно если вы можете предсказать свое потребление и с этим знанием можете оптимизировать ваши расходы. Во-вторых, есть бесплатная квота, т.е. платите только после её израсходования. Квота обнуляется каждые сутки. И у нее есть 2 параметра: кол-во чего-то и пропускная способность. В самом начале у вас будет бесплатный аккаунт, это значит, что у вас будут только бесплатная квота и при перерасходе будет блокироваться тот сервис, который израсходовал свою квоту. Когда вы поймете, что бесплатных квот недостаточно, вы просто переключаете приложение в платный режим. Нужно отметить, что бесплатные квоты в бесплатном и платном приложении отличаются в пользу второго. Дополнительные сведения вы сможете узнать в документации.

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

Вообще можно подвести маленький итог:

  • нет нужды в админах с бородой
  • нет нужды в переобучении программиста
  • оплата только за использованное
  • инфраструктура, инфраструктура, инфраструктура!

Как разрабатывать

Наверно многие слышали про «жуткие» ограничения платформы GAE. Лимит в 30 секунд на запрос, 32 мб на запрос и такой же объем на одну сущность хранения в datastore. И бог его знает сколько еще! Жутко звучит? На самом деле все эти ограничения проистекают из соображений: «Как нам разрабатывать по настоящему эффективные распределенные приложения?» И вправду, если ваши запросы будут выполнятся разное время, то будет трудно балансировать нагрузку, т.к. сложно будет её предсказать. Если ответ от запроса будет слишком большим, то это также увеличит время отклика. Список можно продолжать бесконечно.

Довольно забавным выглядит довод разработчиков, что в GAE нельзя писать в файловую систему frontend экземпляра приложения. И это при том, что эти же разработчики вряд ли будут поддерживать это состояние для других экземпляров приложения. По их мнению наверно GAE сама этим должна заниматься. Это типичный пример, когда разработчик хочет срезать углы и не читать документацию.

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

Так-же стоит придерживаться принципа минимизации побочных эффектов и отказа от состояния.

Отличным примером является протокол HTTP. Как известно он stateless. И если вы будете этого придерживаться, ваше приложение будет обходиться вам достаточно дешево, при существенной нагрузке. На практике это будет выглядеть так что вы большинство запросов будете делать безопасными и кэшируемыми, а деструктивные запросы будете выделять в специальную группу, т.е. они не будут зависеть от первых.

Небольшой пример, у вас есть некая страница и вы на ней показываете залогинен ли пользователь. Причем основной контент страницы статичен. И не плохо было бы его кэшировать. Сделать это можно через вынесения запроса о текущем состоянии пользователя в отдельный подзапрос к вашему API, и делать его через XMLHttpRequest например. Соответственно после того как вы это сделаете, первой странице можно выставлять http-заголовки на кэширование.

Обзор некоторых компонентов

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

datastore

В классической модели LAMP, оппонентом datastore был бы MySQL. В GAE тоже есть MySQL, но статья не про него.

Давайте сначала опишем наши действия, если бы мы разрабатывали на LAMP стеке:

  1. в начале мы бы взяли какой-то MVC-фреймворк
  2. потом написали бы контролеры
  3. для БД написали бы схему хранения записей
  4. взяли бы какой-нибудь ORM
  5. использовали бы шаблонизатор для отрисовки страниц

Для GAE всё было бы схоже за исключением пункта 3-4, и тут есть отличия:

  • для datastore не нужно писать схему данных, взамен вы задаете схему через код
  • нет нужды в ORM, так как сущности хранятся в виде сериализованных объектов
  • предпочтительнее получать сущности по ключу, а не через запросы

Отсюда некоторые выводы:

  • ваши данные хранятся в datastore как есть, и чтобы просто добавить одно поле в сущность, вы это делаете через код и всё
  • вы в ручную должны делать трансформации данных, если это необходимо и за это нужно платить
  • довольно таки трудно выражать отношения между объектами
  • перчику еще добавляет, что необходимо в ручную контролировать консистентность
  • по этому компоненту просто обязательно нужно читать документацию!
Но в целом, если вам нужно хранить объекты в плоском виде без зависимостей, то это делается очень просто. Типичный паттерн — список статей, список комментариев, список «чего-то»…

Отдельно стоит отметить одну особенность под GAE для python. Для datastore в sdk есть две библиотеки, db и ndb. Я рекомендую сразу использовать ndb. Она отличается от первой автоматическим кэшированием в memcache и более эффективным механизмом запросов. Но конечно авто кэширование — просто киллер-фича!

users

Этот компонент отвечает за аутентификацию, но не за авторизацию. Вам предоставляется простой API:

  • выдать URL для логина
  • выдать URL для разлогинивания
  • получить текущего пользователя, если он залогинен
  • проверить является ли текущий пользователь админом

При этом вы используете google аккаунты для пользователей. И вам не нужно заботиться о том как это работает!

В общем-то и всё, этих компонентов должно хватить на обычные сайты и приложения.

Цикл разработки/обучения разработчика

Какая обычная последовательность действий разработчика для GAE? Я думаю это очень важный вопрос.

Я выделяю следующее:

  • генерация нового приложения
  • поскольку я использую фреймворк webapp2, то я открываю документацию к нему в браузере и постоянно к ней обращаюсь
  • когда я собираюсь использовать тот или иной сервис GAE, я открываю по нему документацию
  • поскольку я использую python, я также открываю время от времени документацию на стандартную библиотеку
  • если мне нужна та или иная функциональность, мало просто прикинуть, необходимо изучить не будет ли это узким местом в системе
  • и разделяй и властвуй, деление приложения на модули сильно помогает
  • чем проще, тем лучше!

Как учиться:

  • во первых лучше приступать к практике как можно скорее, читаем что написано выше
  • очень помогают видео из презентаций google io
  • опять же чтение документации

Подводные камни

Обычно, если что-то что вы делаете либо не получается, либо требует много ресурсов, либо слишком сложное, то это можно смело назвать анти-паттерном. Но все же возможно для вашей проблемы есть решения. Их можно найти на stackoverflow или в презентациях google io.

Я просто уверен, что большинство проблем все же будет с datastore. Так как довольно трудно сразу понять его и не использовать как MySQL. Особенно, если вам вдруг понадобилась strong consistency для определенных данных. В этом случае в документации описанные примеры могут вас запутать. Поэтому если ваши объекты не зависимы друг от друга, значит вам не нужна strong consistency. Типичным примером является список статей с счетчиком всех ваших статей. Это и есть анти-паттерн! Конечно эту проблему можно решить и есть workaround, но лучше просто не делать так.

Если всё же вы задались вопросом почему. То давайте приглядимся подробнее к проблеме. Задача хранить счетчик. Звучит безобидно. По сути это простая агрегация. Но как только вы вводите эту сущность, вы тут же создаете зависимость между сущностями, которые хотите посчитать. А это значит нужна strong consistency. Что в свою очередь создает bottleneck для записи этих сущностей, 1 сущность ~ 1 сек. А теперь представьте, если несколько пользователей одновременной попробуют выполнить запись, а если 1000? Надеюсь комментарии излишни.

Куда смотреть дальше

Я рекомендую посматривать документацию по различным сервисам. Некоторые сервисы находятся в тестовом режиме. Это значит, что после их обновления у вас может все сломаться. Будьте осторожны используя их и обязательно делайте обходные пути в случае их отказа.

Также рекомендую канал Google Developers на youtube. На нем есть видео о том как работает datastore, очень познавательное.

Отдельно отмечу сервис Google Cloud Endpoints, этот сервис позволяет быстро и декларативно разрабатывать API для вашего веб или мобильного приложения с автоматической генерацией клиентской библиотеки. Сервис тестовый.

Счастливой разработки!

0 комментариев

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.