読者です 読者をやめる 読者になる 読者になる

文系プログラマによるTIPSブログ

文系プログラマ脳の私が開発現場で学んだ事やプログラミングのTIPSをまとめています。

GAE/JのFWの頂上決戦!slim3とPlay1.2のどちらを選ぶ?

java gae play slim3

私は現在GoogleAppEngine for javaで、2つのサイトを運営しています。
2サイトで異なるフレームワークを使用しているので、それぞれ小学生並の感想を書いてみたいと思います。

tree-tips

このサイトは、プログラミング情報サイトです。
Apache solrやMySQL等をメインにしたサイトとなっています。

使用したフレームワークなど

tree-maps

このサイトは、地図に関するWEB TOOLの専門サイトです。
ジオコーディングやDEG・DMS変換や、大量の緯度経度を色々な形式でプロットできるサイトです。

使用したフレームワークなど

slim3とplay1.2を使ってみて

モデル

slim3

slim3には強力なモデル管理機構があります。
簡単に手軽に高速にデータストアを操作する事もでき、当然ATOMICな処理も可能です。
標準のJDOよりも高速に動作し、ひがやすお氏の努力を垣間見ることができます。
GAEでこんなに真面目にRDBのような操作を実現しているのはslim3くらいじゃないでしょうか。

play

一方playですが・・・
すみませんtree-mapsではモデルに関する機能は全く使ってません。。。
sienaというモジュールを使ってデータストアに触れる事までは解っています。
パッと見た感じ、slim3に軍配が上がりそうに見えました。

playの方には致命的な欠点があります。それは、
http://localhost:8888/_ah/admin
Datastore Viewerを見るための機構が備わってない点があります。
私の調査不足の可能性がありますが、表示しようとするとそんなルーティング無いぜ!と怒られます。
StackOverflow等を見ても標準のDatastoreViewer動かないね、という話題が多いです。

ビュー

slim3

生のjspです。
tilesなんてありません。
JSTLとel式で頑張りましょう。

play

play2系のscalaのビューより解りやすく感じます。
全体的にslim3よりも機能豊富です。
最初からテンプレート機構があり、組み込みタグも豊富。

routesのルーティングが以下の設定の時、

POST    /ajax/dms-degree/to-degree              DmsDeg.ajaxConvertDmsToDeg

ビュー(html)に以下のように記述すると、

#{form @DmsDeg.ajaxConvertDmsToDeg()}
#{/form}

以下のようにレンダリングされます。

<form action="/ajax/dms-degree/to-degree" method="post" accept-charset="utf-8" enctype="application/x-www-form-urlencoded" ><input type="hidden" name="authenticityToken" value="c04af51957e63a637432adfc1cd16163a9172eea">
</form>

ビューにURLを直接かかなくてよくなるので、メンテが楽になります。
tokenも自動発行してくれます。
こんな感じのビューを汚さないためのヘルパーが沢山あります。

コントローラ

slim3

slim3はコントローラであるactionの規約によってルーティングが自動的に決まります。
潔いですが、変更に弱いです。Action名を変えた場合、ビュー側のフォルダ名も変わってしまう。
(変えなくてもできますが、action側が汚くなる)

play

一方playにはお馴染みroutes機能があります。
これは、slim3がパッケージとaction名によって決められてしまうルーティングを、routesファイルで一元管理するものです。このroutesにURLと呼び出すコントローラ名.action名を記述します。
このroutesは非常に良いと感じました。
GET/POST等のメソッドも定義でき、正規表現でパラメータの定義も可能。
何よりroutesがURL一覧代わりになる点が良いです。
slim3はコントローラのメソッドを全部見て、ようやくURL一覧が分かります。
それと比較してplayはroutesさえ見ればどのURLがどのメソッドで実行されるかも解ります。
このroutesはapacheのrewriteのような機能ですね。

スピンアップの速度

slim3

アプリケーションがアイドル状態になって少し時間がたつ(2、3分)と App Engine はそのアプリケーションをスピンダウンします。そして、そのアプリケーションに対する次のリクエストがやってきたときに、新しいインスタンスをスピンアップします。

Slim3 は、起動が遅いとして知られている PersistenceManagerFactory や EntityManagerFactory を使用していません。さらに、余分な初期化を注意深く避けています。そのため Slim3 はスピンアップが速いんです。だいたい 1100 cpu_ms 程度です。

https://sites.google.com/site/slim3documentja/

他のフレームワークと比較すると速いですが、GAE自体が死ぬほど遅いので、正直大したメリットではないかも・・

play

slim3より遅い???ですが、特に困りません。

slim3だろうがplayだろうが、スピンアップ+起動時のメモリキャッシュの処理に10秒くらいかかるので、1〜3秒の差はどうでもよくなります。大体起動時にEHCacheでメモリキャッシュしたりするので、スピンアップ+起動時のキャッシュをトータルすると遅いこと遅いこと・・・

リソースの管理方法の違い

slim3

そんなものありません。
普通にjs・cssをincludeするのみです。

play
/public/javascripts/common.js

というファイルがあるとき、

#{script 'common.js' /}

こう書くと、

<script type="text/javascript" language="javascript"  src="/public/javascripts/common.js"></script>

と変換されます。
cssも同様です。
playの場合は最初から静的フォルダの場所が明確に決められていて、そこを使うという規約を守る代わりに、こういった便利なヘルパーを使う事ができます。

ホットデプロイ

slim3

ホットデプロイ機能があります。
が、web.xmlstruts-config.xml等はホットデプロイできません。
私の環境だけかもしれませんが、コントローラのファイルをコピペして新規コントローラを作成した際もホットデプロイは効きません。

play

ホットデプロイ機能があります。
(私が気づいてないだけかもしれませんが)全てホットデプロイが効いているようにみえます。

jarの管理

slim3

mavenやgradleのような便利な機構はありません。
通常通り手動でビルドパスの管理をします。

play

dependencies.ymlに以下のような形式で記述して管理します。

# Application dependencies

#require:
#    - play

require:
    - play -> play 1.2.5.3
    - play -> siena 2.0.7
    - play -> gae 1.6.0
    - play -> crud
    - play -> secure
    - com.google.guava -> guava 16.0.1

書式の違うmaven・gradleのような感じになっています。
但し、jarの追加・更新は自動ですが、削除は手動なので注意。

その他

playは他にも多くの機能を有しています。具体的には以下をご覧下さい。
home
中にはGAEのホワイトリストに入らない機能があってGAEで動作しないものもあると思いますが、非常に多機能ですね。

雑感

slim3のコンセプトがフレームワークの依存度の低い薄く高速なラッパー的な感じなので、色々手動管理する部分が多いす。そこがslim3のいいところで、FWの強制力が少ないから自分好みにカスタマイズできる(しないと生産性が悪い)。が、自由が故にカスタマイズ部分の品質が人によってバラつきます。更に、カスタマイズしないと他のFWと比較すると生産性は低いです。(ライブラリを用意組み込んだり便利なしくみを自作したり)

一方Playは最初から仕組みを用意してる系のFWで、開発者を迷わせず、リファレンス通りに使うと一定の品質が保たれます。生産性のバラつきも少なくなります。そこがPlayのいい点だと思います。

tree-mapsが個人サイトだからというのもありますが、生産性を高くして、FW側に時間を割くのではなくアプリケーション側の作成(新機能とか仕様追加とか)に時間を割きたい派なので、Play frameworkを選びたいですね。

ただ、datastore周りslim3は頑張っているので(そこしか頑張っていないようにも見えますが)、Play frameworkをメインに使い、datastore部分だけslim3を使う等、両立させるといいかもしれません。

小技

gae play1.2のrollbackの注意点

GAEはデプロイ時にエラーが発生すると、手動でrollbackする必要がありますが、どうもplayの方がおかしい。

$GAE_SDK_HOME/bin/appcfg.sh rollback $WAR_DIR

こんな感じでrollbackできる訳ですが、playには「web.xml」が存在しない。従ってrollback時にweb.xmlが無いエラーが発生し、途方に暮れました。調査してみると、「/war/WEB-INF/appengine-web.xml」がweb.xmlの事で、appengine-web.xmlをweb.xmlという名前でコピーしてからrollbackすると、正常にrollbackできました。

まだ一件落着ではありません。このappengine-web.xmlとweb.xmlが同時にある状態でデプロイすると、アプリが全く動かなくなります。なので、web.xmlを削除してからデプロイする必要があります。

rollbackスクリプトを用意して、

  • appengine-web.xmlをweb.xmlという名前でコピー
  • rollback実行
  • 成功したらweb.xml削除
  • 再デプロイ

とすると楽かと思います。

今回使用したplayのバージョンはGAEの関係上1.2ですが、2系もなかなかいいですね。
初期の2系と違い、今の2系には「Typesafe Activator」というものが備わり、
webのUIでほとんどの作業が行えるようになってました。
実際使ってみたんですが、中々凄いです。
2系はAPサーバがNettyになっており、負荷に強くなり、デプロイもsbtを内蔵する事で強化されています。
(gradleでなくscalaベースのsbtなのはtypesafe社がscala言語の開発者がいるからでしょう)
ビューもデプロイもscala化しているのがちょっと不安ですが、非常に素晴らしいフレームワークだと思います。

作ればわかる!Google App Engine for Javaプログラミング

作ればわかる!Google App Engine for Javaプログラミング