2014年4月20日日曜日

Google App Engine/JでBackendsをModulesに移行

2014年3月13日でBackends APIがdeprecatedになったので、Modulesに移行することにしました。

しかし情報がほとんどなくて苦労しました。
もし間違っている点があればご指摘ください。

BackendsをModulesに移行する手段は一応Googleの公式文書があります。
https://developers.google.com/appengine/docs/java/modules/converting

私の環境はこんな感じです
・Mac OS X 10.9.2
・Eclipse + Google App Engine plugin
・Backendsは3つ。cron + TaskQueueで定期的に稼働

■アプリのModule化
まずはアプリ自体を公式文書にしたがってModule化します。
1. Appのrootにある war フォルダを default にリネーム
2. rootに新しく META-INF フォルダを作成
3. 作成した META-INF フォルダの中に、appengine-application.xml と application.xml を作成

appengine-application.xml の例
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<appengine-application xmlns="http://appengine.google.com/ns/1.0">
<application>appname</application>
</appengine-application>

application.xml の例
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                      http://java.sun.com/xml/ns/javaee/application_5.xsd" version="1">
<description>App Description</description>
<display-name>App Display Name</display-name>
<module>
<web>
<web-uri>default</web-uri>
<context-root>default</context-root>
</web>
</module>
</application>

4. defaultフォルダ - WEB-INF - appengine-web.xml に以下を追加
<application>appname</application>
<version>2</version>
<module>default</module> ← 追加

5. AppEngineのDashboard - Application Settingsを開き、「Performance Settings Migration for Modules」のところにある appengine-web.xml のところからscallingに関する部分をコピーして、先ほどのappengine-web.xmlにペースト
<application>appname</application>
<version>2</version>
<module>default</module>
<automatic-scaling> ← ペースト
<max-idle-instances>10</max-idle-instances>
</automatic-scaling>
「Migrate Settings」ボタンはまだ押さないでください。

6. Eclipseの設定を変更
まずEclipseを開かずに、エディタでrootにある .classpath を開き、war を default に一括置換して閉じます。
その後Eclipseでプロジェクトを開きます。
プロジェクトのプロパティ Google - Web Application の WAR directory を default に変更します。
Java Build Path の一番下の Default output folder: の war を default に変更します。

以上でアプリ自体のModule化の準備ができました。

■BackendsのModule化
いよいよBackendsのModule化に入ります。
1. アプリのrootにBackendsと同じ名前のフォルダを作る。これがModuleフォルダになります。
2. それぞれのModuleフォルダに WEB-INF フォルダを作成。
3. WEB-INFフォルダの中に appengine-web.xml と web.xml を作成

appengine-web.xml の例
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<application>appname</application>
<module>mymodule</module>
<version>1</version>
<threadsafe>true</threadsafe>
<instance-class>B2</instance-class>
<basic-scaling>
<max-instances>5</max-instances>
<idle-timeout>10m</idle-timeout>
</basic-scaling>
</appengine-web-app>
web.xml の例
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.5"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>mymodule</servlet-name>
<servlet-class>jp.yourapp.MyModuleServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>mymodule</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>

4. root - META-INF - application.xml に Moduleに関する記述を追加
<module>
<web>
<web-uri>default</web-uri>
<context-root>default</context-root>
</web>
</module>
<module> ← 追加
<web>
<web-uri>mymodule</web-uri>
<context-root>mymodule</context-root>
</web>
</module>
設定が終了したら、これまでの backends.xml は削除してください。

5. queue.xml にModule用の設定を追加。TaskQueueからBackendsを起動していた場合は queue.xml にtargetを指定します。
<queue>
<name>myqueue</name>
<target>mymodule</target> ← 追加
<rate>5/s</rate>
<bucket-size>5</bucket-size>
<retry-parameters>
<task-retry-limit>1</task-retry-limit>
</retry-parameters>
</queue>

6. cron.xml の URLを変更。urlはモジュールのrootになるので、/ に変更しました。
<cron>
<url>/</url> ← 変更
<target>mymodule</target>
<description>update village</description>
<schedule>every 1 minutes</schedule>
<timezone>Asia/Tokyo</timezone>
</cron>

7. プログラム内からTaskQueueに追加していた場合はModuleを使うように変更
どのModuleでqueueを実行するかは、queue.xmlのtargetで指定します。
[変更前]
Queue queue = QueueFactory.getQueue("myqueue");
TaskOptions to = TaskOptions.Builder.withParam("param1", "aaa").param("param2", "bbb");
to.header("Host", BackendServiceFactory.getBackendService().getBackendAddress("mybackends"));
queue.add(to);
[変更後]
Queue queue = QueueFactory.getQueue("myqueue");
TaskOptions to = TaskOptions.Builder.withUrl("/").param("param1", "aaa").param("param2", "bbb").method(Method.POST);
queue.add(to);

8. ここまで設定できたらEclipseでプロジェクトを選択し、クリーン&ビルドします。
そしてこれはこの方法が正しいかわからないのですが、default - WEB-INF - classes フォルダのシンボリックリンクを、それぞれのModuleの WEB-INF フォルダに作成します。
(libも必要?)

ここまででModule化の作業は完了です。

■デプロイ
それでは完成したものをデプロイしましょう。

1. appengineのDashboard - Application Settings - Performance Settings Migration for Modulesで、「Migrate Settings」ボタンを押してアプリをModuleに移行します。
この作業は元に戻せないので注意してください。

2. 古いBackendsを削除
Migrateが終わると、Versions の中に古いBackendsがVersion化されてると思うので、これをDeleteしてください。

3. Eclipseからは正しくデプロイ出来ないので、アプリケーション - Eclipse - plugin - com.google.appengine.eclipse.sdkbundle_1.9.x - appengine-java-sdk-1.9.x - bin の中にある appcfg.sh を使います。
実行権限がない場合があるので、binの中のshにはすべて実行権限をつけてください。(できればPATH指定も)

ターミナルでアプリのrootの一つ上の階層に移動し、以下のようにしてデプロイします。(appnameはrootフォルダの名前)

appcfg.sh update appname


以上です。

0 件のコメント:

コメントを投稿