• Google App Engine ~ Cronでメール配信

    このエントリーを含むはてなブックマークはてなブックマーク - Google App Engine ~ Cronでメール配信 この記事をクリップ!Livedoorクリップ - Google App Engine ~ Cronでメール配信 Yahoo!ブックマークに登録 @niftyクリップに追加 Share on Tumblr FC2ブックマークへ追加 newsing it! Googleブックマークに追加 Bookmark this on Delicious FriendFeedで共有 このエントリをつぶやくこのWebページのtweets

    ご無沙汰してましたm(_ _)m

    先月1児のパパになったシステム部の佐々木です。

    本日はGoogle App EngineのCronサービスとメール配信についてつらつらと書いていきたいと思います。

    Unix/Linuxをご存じの方には説明不要かと思われますが、そうです。あのCronです。

    データベースの定期監視を行う場合など、非クラウド環境のJavaアプリケーションでは非同期スレッドを生成してsleepしながらデータベースを監視するというのが定石だったかと思いますが、GAEではそもそもスレッドの生成ができません。

    これの代わりにGoogle App EngineではCronサービスを使用します。

    それではCronサービスを使用して、定期的にメールを送信する方法を説明していきます。

    1.ジョブの作成

    まずは定時実行されるジョブを作ります。とはいっても作るのは単なるサーブレットです。
    Google App EngineのCronサービスはURLに対してHttpGETリクエストを放ることでジョブの実行を行っているので「ジョブ=サーブレット」ということになります。

    Pureサーブレットでもよいのですが、筆者がSlim3を使用しているので、build.xmlの”gen-controller-without-view”からコントローラを生成します。
    ここではURL”/cron/cronTest”としてCronTestController.javaを生成しました。

    package com.sample.controller.cron;

    import java.util.Date;
    import java.util.Enumeration;
    import java.util.logging.Logger;
     
    import org.slim3.controller.Controller;
    import org.slim3.controller.Navigation;
     
    import com.google.appengine.api.mail.MailService;
    import com.google.appengine.api.mail.MailServiceFactory;
    import com.google.appengine.api.mail.MailService.Message;
     
    public class CronTestController extends Controller {
     
        @Override
        public Navigation run() throws Exception {
     
            // MailService
            MailService service = MailServiceFactory.getMailService();
            // Message
            Message message = new Message();
            // 送信者は必ずアプリケーション管理者
            message.setSender("rl.ysasaki@gmail.com");
            // to
            message.setTo("y-sasaki@r-learning.co.jp");
            // タイトル
            message.setSubject("Cronテスト");
            // 本文
            message.setTextBody("メール送信テスト:" + new Date().toString());
            // 送信
            service.send(message);
            return null;
        }
    }

    処理中では低レベルのメールAPIを使用してメール送信を行っています。
    ネット上で公開されているサンプルはjavax.mailを使用したサンプルが多いですが、低レベルAPIの方が簡単なのでこっちで書いてます。
    http://code.google.com/intl/ja/appengine/docs/java/javadoc/com/google/appengine/api/mail/package-summary.html

    2.ジョブのテスト

    まずは作ったジョブが動くかどうかですね。メール送信はローカルでは確認できないのでGoogle App Engineにアプリケーションをデプロイします。
    デプロイ後、ブラウザからhttp://アプリケーションホスト/cron/cronTestにアクセスし、メールが送信されればテストは完了・・・・・
    とはいかないのです。
    このままでは一般ユーザがURLにアクセスした場合に、不正なジョブの実行になってしまいます。
    これを回避するために、adminユーザ以外のアクセスを禁止する必要があります。
    一般ユーザのアクセスを禁止するにはwar/WEB-INF/web.xmlに以下の記述を追加します。

        <security-constraint>
            <web-resource-collection>
                <url-pattern>/cron/*</url-pattern>
            </web-resource-collection>
            <auth-constraint>
                <role-name>admin</role-name>
            </auth-constraint>
        </security-constraint>

    これで管理者以外は”/cron/*”のURLにアクセスできなくなりました。

    3.ジョブの登録

    ジョブの登録はwar/WEB-INF/cron.xmlに以下の内容を記述し、デプロイしたら完了です。

    <?xml version="1.0" encoding="UTF-8"?>
    <cronentries>
    	<cron>
    		<url>/cron/cronTest</url>
    		<description>CronTest And MailService</description>
    		<schedule>every 1 minutes</schedule>
    		<timezone>Asia/Tokyo</timezone>
    	</cron>
    </cronentries>
    • url・・・実行するジョブのURL
    • schedule・・・ジョブの起動タイミング(例は毎分)
    • timezone・・・デフォルトはUTCなので日本時間でジョブ実行する場合は”Asia/Tokyo”を指定

    Scheduleの書き方
    http://code.google.com/intl/ja/appengine/docs/java/config/cron.html#The_Schedule_Format

    Timezone
    http://en.wikipedia.org/wiki/List_of_zoneinfo_time_zones

    4.ジョブの解除

    cron.xmlの<cron>要素を消してデプロイし直せばジョブは解除されます。
    また、Google App Engineの管理コンソールから、登録されているCronの状態(Cron Jobs)を確認することもできます。

    次回はTaskQueueについて書きます。

    佐々木 康幸

    ・所属 システム部 ・役職 マネージャ ・関心事 Scala,Groovy,Java, Slim3,Wicket,Google App Engine,Gaelyk ・主な仕事 市場系金融システム開発

     
  • GAE用フルスタック・フレームワーク ~ Slim3のご紹介

    このエントリーを含むはてなブックマークはてなブックマーク - GAE用フルスタック・フレームワーク ~ Slim3のご紹介 この記事をクリップ!Livedoorクリップ - GAE用フルスタック・フレームワーク ~ Slim3のご紹介 Yahoo!ブックマークに登録 @niftyクリップに追加 Share on Tumblr FC2ブックマークへ追加 newsing it! Googleブックマークに追加 Bookmark this on Delicious FriendFeedで共有 このエントリをつぶやくこのWebページのtweets

    こんばんは。システムの佐々木です。

    本日はGoogle App Engine用フルスタックフレームワークである「Slim3」についてご紹介します。

    Slim3とは…

    Slim3はGAE用に作成された非常に軽量なWEBフレームワークです。
    元々はSeasar2の後継として立ち上がったのですが、途中からGAE用に特化し、今の形になります。
    名前の由来はSimple And “Less is more”でとにかくシンプルなのがコンセプト。

    特筆すべき機能は下記の4点。

    • HotReloading
    • Global Transactions
    • Fast Spin-up
    • Faster than JDO/JPA
    • Type Safe Query

    HotReloading

    わかる人にいうとSAStrutsのホットデプロイ。
    わからない人にいうと、APサーバーの再起動なしにモジュールの修正を即座に反映してくれる機能です。
    コード修正してすぐさまブラウザで確認できるのでスクリプトによるWEB開発のようにサクサク開発を行うことができます。

    Global Transactions

    過去に掲載した記事にて、データストアのトランザクション範囲は「単一のエンティティグループ」に限定されると書きましたが、Slim3のデータストア機能を使用すると複数エンティティグループ間もトランザクション制御をすることが可能になります。

    Fast Spin-up

    通常のWEBアプリケーションはサーバを起動したり、デプロイしたらアプリケーションは立ちあがったままですね。
    GAEでは初めてアクセスがあった時に、アプリケーションのインスタンスが起動します(Spin-up)。
    そしてアプリケーションに対して一定期間(2,3分?)アクセスがなくなるとインスタンスが停止します(Spin-down)。

    また、GAEには30秒制限(リクエストタイムアウト)があります。これにはSpin-upしている時間も含まれています。
    クライアントからアクセスした際にSpin-upで30秒かかってしまったらもうそのアプリケーションは動きません(笑)
    仮にSpin-upを10秒にしたところで立ち上がるのに10秒かかるWEBアプリケーションなんて誰が好き好んで使うでしょう。
    Spin-upは3秒以内に!

    Slim3はそのあたりが考慮をされていて、フルスタックなのに稀にみる軽量さです。
    http://shin1o.blogspot.com/2010/02/slim3java-appengine-spinup.html

    また、Spin-up問題を解決するには軽量なフレームワークを使用する他、ServletContextInitializerなどの処理は行わないなどできるだけ早くインスタンスが立ち上がるような考慮が必要です。

    Faster than JDO/JPA

    GAEでデータストアにアクセスする際の標準的な方法としてLowLevelAPIの他、ORMであるJDO,JPAがあります。
    しかし、JDO/JPAは遅いんです。(下記のオンラインデモから確認できます)
    http://slim3demo.appspot.com/performance/

    LowLevelAPIは段違いで速いのですが、以前の記事で紹介したとおり、コードがやや冗長になります。
    生産性をあげるにはORMという選択肢があるのですが、JDO/JPAは遅いんです。
    理由としてJDO/JPAは実行時リフレクションでデータとオブジェクトのマッピングを行いますが、Slim3ではこのマッピング手続きをオブジェクトのコンパイル時にコード生成という形で行います。
    Javaのリフレクションは遅いということが明白なのでリフレクションしないSlim3の方が早いってわけです。

    Type Safe Query

    SQLとか手書きするとよくタイプミスしますよね?LowLevelAPIであっても、プロパティ名やカインド名はタイプセーフではありません。
    Slim3ではEclipseのサジェスト(CTRL+Space)を駆使してクエリを作成するのでクエリのタイプミスなんてことは起こらなくなります。

    その他

    その他に、URLからビューとコントローラ、モデルのひな形を作成してくれるAntスクリプトがあったり、GAE上でテストできるktrwjr(Kotori Web Junit Runner)、 Railsのrouter.rbのようなURLルーティングも可能です。

    Eclipse plugin

    本家から正式にpluginも出てます。GWTやScenicにも対応していますよー

    書籍

    Slim3の書籍は2冊ほどあります。
    オープンソース徹底活用 Slim3 on Google App Engine for Java
    オープンソース徹底活用 Slim3によるWebアプリケーション開発

    が、本家のサイトもかなりの充実っぷりなので個人的にはいらないかも 。
    (機能も多くないので覚えることも少ないし)
    http://sites.google.com/site/slim3documentja/

    佐々木 康幸

    ・所属 システム部 ・役職 マネージャ ・関心事 Scala,Groovy,Java, Slim3,Wicket,Google App Engine,Gaelyk ・主な仕事 市場系金融システム開発