9 янв. 2011 г.

Play Framework + Scala + GAE

Облака... Облачные вычисления... Данные в облаке. Все чаще мы слышим эти высказывания. Кому-то это кажется в новинку, кто-то активно использует, а кто-то панически боится. Если вам близко последнее, то я вас поздравляю, вы параноик. Шучу) Конечно в наше время информация это все. Кто владеет самой свежей и ценной информацией, тот владеет миром. Как же выглядит это "облако" ? Ну для начала давайте будем называть вещи своими именами, а именно Cloud Computing. Говоря простым языком вы "покупаете" вычислительные ресурсы. Причем в отличии от обычного хостинга вы платите только за использованные ресурсы. Более точнее за меня сможет об этом рассказать wikipedia. Заманчиво правда ? А игроков на рынке облачных вычислений не так уж и мало, самые видные: Amazon Web Services, Google App Engine, Windows Azure, Stax.Net Многие из них предоставляют ограниченное кол-во своих мощностей совершенно бесплатно! Я выбрал Google App Engine.

Отлично, с хостингом определились, нужно создавать приложение. И так, что мы там имеем на App Engine. Ага, Python и Java. С первым я знаком плохо, а вот последний знаю довольно хорошо. Приступим, но стоп! Как мы будем писать наше приложение, все с нуля ? Хм... Пожалуй нет. Давайте посмотрим. Для того же Ruby есть Ruby On Rails, для Python - Django, TurboGears, а для Java целый вагон разных фреймворков. Но все ли они подойдут ? Нет. Дело в том что Google App Engine не использует привычные всем РСУБД, а в основе хранения данных царит BigTable. Большинство Java-фреймворков сразу отпадают. Но не стоит отчаиваться! Комьюнити пользователей App Engine ведет и периодически обновляет замечательный перечень поддерживаемых технологий в GAE.

Приступим к выбору удобного нам MVC-фреймворка. Я выбрал Play Framework. Хотя на момент написания статьи его не было в перечне поддерживаемых технологий, но работает с GAE он уже сейчас довольно неплохо. Почему выбрал именно его ? Он предельно прост, лаконичен, не тянет за собой привычные для Java-фреймворков портянки XML-файлов. Кому-то он кажется похожим на Ruby On Rails, кому-то на Django. Как бы там не было Play! предоставляет весь необходимый функционал, а так же неплохую библиотеку плагинов. Устанавливается предельно просто и работает сразу "без бубна".

Отлично, выбрали фреймворк. Как всегда нам хочется писать как можно меньше кода. Возможно с Ruby / Python это бы получилось, т.к. эти языки более "заточены" под веб. У нас Java. Не хочу обидеть фанатов этого языка, но в плане нового функционала "из коробки" Java давно уже не развивается. Возможно Oracle исправит это положение, но вот выход Java 7 опять отложили. И тут у нас есть выход. На горизонте уже давно видны две красавицы: Scala и Clojure. Эти языки базируются на JVM, а значит могут поддерживать весь багаж библиотек java-сообщества. Языки появились неспроста. Как вы наверное заметили сейчас идет тенденция на функциональное программирование. Чем это обусловлено ? Закон Мура изменился. Ранее Мур высказал предположение, что число транзисторов на кристале будет удваиваться каждые 24 месяца. До недавного времени это работало, частота процессоров увеличивалась с заявленной очередностью.
Однако в 2007 году Мур заявил, что закон, очевидно, скоро перестанет действовать из-за атомарной природы вещества и ограничения скорости света
(см. wikipedia)
Так и произошло. Увеличивать тактовую частоту процессоров больше не было возможности и производители компьютерного "железа" начали выпускать многоядерные процессоры. Ранее все программы писались под одноядерные архитектуры и, для того, чтобы использовать всю мощность многоядерных систем программу необходимо переписать. К чем это я ? Несмотря на то что Scala как и Java императивный язык, он поддерживает написание программ в функциональном стиле. А Clojure полностью функциональный язык, основная идея которого взята с языка Lisp. Посмотрим на список плагинов нашего любимого Play! и с радостью находим там поддержку Scala.

И так, хватит уже заниматься болтавней давайте приступим к установке фреймворка!
Моя рабочая система Ubuntu, все примеры я буду показывать на ней. Я всегда люблю использовать самые последние версии программного обеспечения, поэтому ставить Play! мы будем из исходников. Более простая установка описана на офф.сайте фреймворка, но мы пойдем другим путем и чуть ниже я объясню почему.

Нам нужен установленный git. В ubuntu это просто:
$ sudo apt-get install git
Создадим директорию для наших экспериментов, пусть это будет ~/dev
$ mkdir ~/dev
$ cd ~/dev
Получим последнюю версию исходников Play! с GitHub:
$ git clone https://github.com/playframework/play.git
Соберем Play! Для этого нам будет нужна утилита для сборки java-проектов, ant.
Установим:
$ sudo apt-get install ant
Хочу заметить, что я не использую для работы OpenJDK. Поэтому смотрите внимательно на зависимости, которые будет тянуть за собой пакет. Если у вас корректно в системе установлена Sun/Oracle Java SDK, то проблем не будет.
Переходим в директорию для сборки Play!
$ cd play/framework
Запускаем сборку проекта
$ ant

Отлично, теперь поставим недостающие плагины из исходников)
Переходим в директорию с плагинами Play!:
$ cd ~/dev/play/modules
Скачиваем исходный код Scala плагина:
$ git clone https://github.com/guillaumebort/play-scala.git
Скачиваем исходный код Google App Engine плагина:
$ git clone https://github.com/guillaumebort/play-gae.git
Скачиваем исходный код Siena плагина:
$ git clone https://github.com/vijaykiran/play-siena.git

Теперь приступим к сборке. Для начала создадим символические ссылки для удобства:
$ ln -s play-scala scala
$ ln -s play-gae gae
$ ln -s play-siena siena

Собираем Scala плагин:
$ cd scala
$ ant -Dplay.path=~/dev/play

Собираем GAE плагин:
$ cd ../gae
$ ant -Dplay.path=~/dev/play

Собираем Siena плагин:
$ cd ../siena
$ ant -Dplay.path=~/dev/play

Ура! Уже теперь Play! самый свежий и готов к работе. Создадим директорию для наших Play! проектов:
$ mkdir ~/src
$ cd ~/src

Создадим Play! проект с поддержкой Scala, назовем его TestApp
$ ~/dev/play/play new TestApp --with scala

И сразу его запустим)
$ ~/dev/play/play run TestApp

А теперь про модули. Для чего мы ставили Siena ? Прежде всего для удобства разработки, т.к. Siena предоставляет одинаковый интерфейс для работы с хранилищами данных SQL, NoSQL, etc. Т.е. нам не нужно будет переписывать слой работы с данными если мы вдруг захотим сменить хранилище.

Теперь давайте укажем Play! использовать наши плагины, для этого отредактируем application.conf файл нашего проекта:
$ vim TestApp/conf/application.conf

В секции "Additional modules" допишем 3 строчки:
module.scala=${play.path}/modules/scala
module.siena=${play.path}/modules/siena
module.gae=${play.path}/modules/gae

Это пожалуй все по настройке приложения для работы связки Play! + GAE + Siena.

P.S. я обещал написать почему все ставим из исходников. Во время разработки я сталкивался с некоторыми проблемами работы плагинов. К примеру ScalaCache в production на GAE использовал Cache на Actors, вместо GAE Cache. По этой причине приложение "кушало" много ресурсов и вылетало с ошибкой за все бесплатные ограничения App Engine. Проблема была оперативно решена разработчиком плагина, но в офф.репозитарии Play! эта версия плагина еще не появилась. Или вот еще. Siena не могла корректно сохранять Blob поля в GAE. Разработчик "пофиксил" плагин, но в офф.репозитарии Play! свежей версии не было. Время шло, проект надо сдавать. Сборка всего из исходников решила проблему. В следующей статье опишу приёмы разработки на Play! + Scala.

Удачи!



6 комментариев:

Linegreu74 комментирует...

Привет, знакомый из скалашной джабберконфы! И я тоже скоро буду писать про Play у себя.
stream.

Unknown комментирует...

Сделал то, что ты тут написал. Пока не знаю зачем :)

в моменте:
ant -Dplay.path=~/dev/play

потребовалось писать home/_user_/вместо ~

Anton комментирует...

смотрели в сторону Lift/Scalatra?

не смущает "не обычность" Play (в честности очень много переписано из стандартного сервелеты и тд)?

webus комментирует...

Lift не понравился. А вот Scalatra подробно не смотрел. А что может смущать, если благодаря этому Play такой какой есть, легкий и быстрый.

Anton комментирует...

Быстрый это спорный вопрос, на отдачи контента без бизнес логики примерно в 3 раза медленнее спринга (хотя надо самому померить).

webus комментирует...

может забывали ставить application.mode=prod ?