You are on page 1of 54

第一回 京都

Google App Engine for Java


勉強会
株式会社 SOBA プロジェクト 山下大

http://blog.daisukeyamashita.com/
はじめに
• 本日は、弊社までお越し下さいましてあ
りがとうございます。
私は誰?
• 本日の会場である、株式会社 SOBA プロジェクトの取締

• 会社では自社開発の P2P 通信による、 VoIP 技術の普及


に努めており、ここ数年は主にサーバサイド( J2EE )
周りの技術検証/実装をしています(ウェブ会議システムの SOBA CITY や
SOBA mieruka を開発しました)

• それ以前は、自社開発の P2P 通信ネットワークに携帯


電話/ PDA を接続するためのフレームワークを研究/
開発していました

• 基本的にネットワーク系のプログラマーです
ここで CM
  現在、 CodeZine という開発者向けの
情報サイトで「 Google App Engine for
Java を使ってみよう!」という連載をや
っています。

http://codezine.jp/author/592

よろしければブックマークにご登録を!
今日は何を知りたい?
• GAE for Java 全般の話
• Google Plugin for Eclipse
– インストール
– 使い方
• データストア
– データストア
– データセレクト
• Memcache
• URL Fetch
• Mail
• Images
• Google Accounts
• タスクのスケジュール
GAE 全般の話
Google App Engine とは
• 2008 年4月8日 Google Campfire One
でローンチされた Google のクラウドサー
ビスです。

• アプリケーション・サーバ、データベー
ス、データ・ストレージ・サービスから
構成されている。
Google App Engine for Java
• 2009 年 4 月 7 日  Google Campfire One
にて Java 版を発表!
– http://www.youtube.com/watch?v=P3GT4-m_6RQ
– http://www.youtube.com/view_play_list?p=DFDBB63922B90A70
メリット
• 最大のメリットは突発的なトラフィックに対応可能。サ
ービスが突然大人気になっても即座にスケールアウトで
きる。

• 各種 Google サービスとの親和性が高く、特に認証サー
ビスやメールサーバを自前で用意する必要がない。
– GAE の主要 API は、 Java の標準 API に準拠しており Google App
Engine 用にプログラムを書き直す必要がない。

• JNI(Java Native Interface) 経由のネイティブプログラム


の実行とファイルシステムへのアクセス以外は、ほぼ自
由にできる。
– これの意味するところは、 Google App Engine 固有の機能を使わずに
プログラムを書けば、囲い込まれないということ!
どんなテクノロジー(ライブラリ)が
利用できるのか?
• J2EE
– Java Servlet
– Java Server Pages
• Java Mail
• Java Persistence API
• Java Data Objects
• JCache
• その他、ファイルシステム / スレッドを使
わない PureJava なライブラリ
GAE のライブラリ
• GAE インフラにアクセスする各種ライブ
ラリも Java の一般的な API に準拠する形
で実装されています。

• App Engine データストア


– Java Data Objects (JDO)
– Java Persistence API (JPA)
• App Engine メールサービス
– JavaMail API
• App Engine URL フェッチサービス
– java.net HTTP API
Java Virtual Machine
• GAE for Java はもちろん、内部的に JVM
が動いています。
• → これは、 JVM で動くバイトコードを出
力するクロスコンパイラやインタープリ
タがあれば他の言語を動かせることを意
味しています。
( JavaScript 、 Ruby 、 Scala ・・・)
Java Virtual Machine
• GAE は、 Java 6 の JVM を使用していま
す。
• App Engine SDK は、 Java 5 以降をサポ
ートしています。
• Java 6 の JVM はどんなバージョンでコ
ンパイルされた class ファイルもロードで
きます。
ここだけの話。。。
servlet.ServletException: This is an exception
t com.acme.HelloWorld.doGet(HelloWorld.java:48)
t javax.servlet.http.HttpServlet.service(HttpServlet.java:689)
t javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
t org.mortbay.jetty.servlet.ServletHolder$SingleThreadedWrapper.service(ServletHolder.java:617)
t org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
t org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1093)
t com.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionFilter.java:35)
t org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084)
t com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
t org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084)
t org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:360)
t org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
t org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
t org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:712)
t org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
t com.google.apphosting.runtime.jetty.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:237)
t org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:139)
t org.mortbay.jetty.Server.handle(Server.java:313)
t org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:506)
t org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:830)
t com.google.apphosting.runtime.jetty.RpcRequestParser.parseAvailable(RpcRequestParser.java:63)
t org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:381)

http://blogs.webtide.com/gregw/entry/google_appengine_uses_jetty
ここだけの話。。。
com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:125)
com.google.apphosting.runtime.JavaRuntime.handleRequest(JavaRuntime.java:235)
com.google.apphosting.base.RuntimePb$EvaluationRuntime$6.handleBlockingRequest(RuntimePb.java:4547)
com.google.apphosting.base.RuntimePb$EvaluationRuntime$6.handleBlockingRequest(RuntimePb.java:4545)
com.google.net.rpc.impl.BlockingApplicationHandler.handleRequest(BlockingApplicationHandler.java:24)
com.google.net.rpc.impl.RpcUtil.runRpcInApplication(RpcUtil.java:359)
com.google.net.rpc.impl.Server$2.run(Server.java:792)
com.google.tracing.LocalTraceSpanRunnable.run(LocalTraceSpanRunnable.java:56)
com.google.tracing.LocalTraceSpanBuilder.internalContinueSpan(LocalTraceSpanBuilder.java:489)
com.google.net.rpc.impl.Server.startRpc(Server.java:748)
com.google.net.rpc.impl.Server.processRequest(Server.java:340)
com.google.net.rpc.impl.ServerConnection.messageReceived(ServerConnection.java:422)
com.google.net.rpc.impl.RpcConnection.parseMessages(RpcConnection.java:319)
com.google.net.rpc.impl.RpcConnection.dataReceived(RpcConnection.java:290)
com.google.net.async.Connection.handleReadEvent(Connection.java:419)
com.google.net.async.EventDispatcher.processNetworkEvents(EventDispatcher.java:733)
com.google.net.async.EventDispatcher.internalLoop(EventDispatcher.java:207)
com.google.net.async.EventDispatcher.loop(EventDispatcher.java:101)
com.google.net.rpc.RpcService.runUntilServerShutdown(RpcService.java:249)
com.google.apphosting.runtime.JavaRuntime$RpcRunnable.run(JavaRuntime.java:373)
java.lang.Thread.run(Unknown Source)

http://blogs.webtide.com/gregw/entry/google_appengine_uses_jetty
JVM サンドボックス
• JVM は、セキュアなサンドボックス内で
動作しており、他人のアプリと分離され
た状態で実行されます。
• さらに、他のアプリによって、あなたの
アプリのパフォーマンスやスケーラビリ
ティに影響が出ることがありません。
制限
• スレッドの生成ができません。
• ファイルシステムにファイルの書き出し
ができません。
• 自由なネットワーク接続ができません。
• JNI を含むネイティブコードの実行ができ
ません。
利用料金
リソース 単位 単位当たりの費用
レスポンス 1ギガバイト $0.12
リクエスト 1ギガバイト $0.10
CPU 利用時間 1CPU 時間 $0.10
ストレージ ギガバイト/日 $0.005
電子メール 1通 $0.0001
無料の範囲(1日)
リソース 単位
レスポンス 10 ギガバイト
リクエスト 10 ギガバイト
CPU 利用時間 46.3 CPU 時間
ストレージ 1 ギガバイト/日
電子メール 2000 通
* 月間 500 万アクセス相当
使いすぎないか心配。。。
• Google App Engine には新たに Billing と
いう機能が搭載され、利用料の上限を設
定できるようになりました。
標準的な設定
Total
Paid Free Daily
Resource
(% of Budget) Budget Unit Cost Quota Quota Quota
58.29 CPU
CPU Time 60% $1.20 $0.10 11.99 46.30 hours
Bandwidth
Out 16% $0.32 $0.12 2.66 10.00 12.66 GBytes

Bandwidth In 4% $0.08 $0.10 0.79 10.00 10.79 GBytes

Stored Data 20% $0.40 $0.005 80.00 1.00 81.00 GBytes*


Recipients
Emailed 0% $0.00 $0.0001 0.00 2000.00 2000.00 Emails

*1 日 $2 上限で、 Budget Preset に Standard を選択した場合


GAE の機能と使い方
GAE の機能
• Datastore
• Memcache
• URL Fetch
• Mail サービス
• Images
• Google Accounts
• タスクのスケジュール
Datastore
• 永続的なデータ保持
• Google で実運用されている高信頼性
• スケーラビリティ
• 世界中からのアクセス
• 標準の API に準拠したアクセス用 API
– Java Data Object (JDO)
– Java Persistence API (JPA) 1.0
• これらのインターフェイスは Data Nucleus
Access Platform を利用して実装されています。
Memcache
• 非常に高速
• 一時的な分散ストレージ
– データストア・クエリーの結果のキャッシュ
– 計算結果のキャッシュ
• JCache (JSR 107)
URL Fetch
• ウェブを超えて、リソースにアクセスす
る仕組み
• HTTP/HTTPS プロトコルが利用できる
• java.net.URLConnection
– と、関係するクラス
Mail サービス
• アプリケーションまたは、現在サインイ
ンしているユーザの代わりにメールを送
れます
• 添付メール
– JavaMail
Images
• フォーマットの変更
– JPEG, PNG, GIF, アニメーション GIF, BMP, TIFF,
ICO
• 切り出し
• 回転
• リサイズ
• 色調変更
• サーバーリソースが空いているいる時には CPU
パワーを全開にして処理する
– サンドボックス制限内で動作するなら、他の画像処
理ソフトを利用できます。
Google Accounts
• アカウント作成
• サインイン
• シングルサインオン
– すでに GMail のようなサービスにサインインしていると、新た
にサインインせずにあなたのサービスで認証できる
• ユーザのメールアドレスへのアクセス
• アクセス制御
– getUserPrincipal() メソッドを利用する
• 低レベルの Google Accounts API
– サインイン / サインアウト用の URL 生成
– データストアに適した形のユーザデータ・オブジェクトの取得
タスクのスケジュール
• 指定した感覚でアプリケーション URL を
実行
• Unix の Cron ライクな制御
– CronJobs
SDK を使ってみよう!
インストール 前提条件
• Java SE Development Kit(JDK) 6 以上
– java –version
– javac –version
App Engine Java SDK
• http://googleappengine.googlecode.com/files/appe
ngine-java-sdk-1.2.0.zip

• zip を展開して、中の bin ディレクトリにパスを通


すだけ!

• この勉強会ではもっと便利な、「 Google Plugin


for Eclipse 」を利用します。

• 注意:次の Google Plugin for Eclipse を利用する


場合、この SDK のインストールは必要ありませ
ん。
Google Plugin のインストール
Google Plugin for Eclipse
The Google Plugin for Eclipse, for Eclipse 3.3 (Europa)
http://dl.google.com/eclipse/plugin/3.3/

The Google Plugin for Eclipse, for Eclipse 3.4 (Ganymede)


http://dl.google.com/eclipse/plugin/3.4/

インストール方法は、「 http://codezine.jp/article/detail/3835 」をご覧下さい。


Google Plugin for Eclipse
• App Engine を利用した開発プロジェクト
のために Eclipse プラグインが用意されて
います。
• このプラグインでは、新規プロジェクト
の作成やデバッグができます。
• また、 Eclipse プラグインは App Engine
SDK と GWT SDK を一緒に提供しており
、 GWT を使用することで国際的なウェブ
アプリケーションを開発して配布するの
を簡単にしています。
プロジェクトの作成

デモ
GAE へのデプロイ

デモ
アプリの公開
• アプリは appspot.com ドメイン上の予約
したサブドメインから使用するか、
Google Apps を使用して、独自ドメイン
から行うことができます。
GAE コントロールパネルの
使い方
デモ
Images Java API
URL Fetch Java API
Memcache Java API
Datastore Java API
データストア
• データストアを扱う API は3種類
– Java Data Objects (JDO)
– Java Persistence API (JPA)
– low-level datastore API
• JDO が一番使いやすい。
• Google Plugin では標準で Enhancer 用の
設定ファイルが含まれている。
• Google Plugin では、自動的に Enhancer
を実行してくれる。
Enhancer
• クラスファイルを XML で記述したメタデ
ータを元に、 PersistenceCapable を実装
したクラスに改変するものです。
• PersistenceCapable を実装したクラスの
場合はエンハンサを通す必要はありませ
んが、毎回同じインターフェイスを実装
するのは面倒ですのでエンハンサを利用
します。
@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Employee {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Long id;

@Persistent
private String firstName;

@Persistent
private String lastName;

@Persistent
private Date hireDate;
Employee employee = new Employee("Alfred", "Smith", new Date());

PersistenceManager pm = PMF.get().getPersistenceManager();

try {
pm.makePersistent(employee);
} finally {
pm.close();
}
型 Java class ソートオーダー note

500 バイト以下のテキ java.lang.String Unicode JDOFatalUserExcepti


スト on
500 バイト以下の com.google.appengi byte オーダー JDOFatalUserExcepti
byte 列 ne.api.datastore.Sho on
rtBlob
boolean 型 boolean or false < true
java.lang.Boolean
integer 型 short, 数字 long integer のサイズ
java.lang.Short, int, を超えるとオーバーフ
java.lang.Integer, ローする
long, java.lang.Long
浮動小数点型 float, 数字 double 幅を超えると
java.lang.Float, オーバーフローする
double,
date time 型 java.util.Date 日付順
java.lang.Double

Google アカウント型 com.google.appengi メールアドレス


ne.api.users.User (Unicode) 順
長いテキスト型 com.google.appengi (オーダー不能) インデックスされない
ne.api.datastore.Tex
t
長い byte 列型 com.google.appengi (オーダー不能) インデックスされない
ne.api.datastore.Blo
b
エンティティキー型 com.google.appengi パス順
ne.api.datastore.Key
, 参照オブジェクト
URL com.google.appengi Unicode
ne.api.datastore.Lin
Java ではサポートされていない

• Category
• Email
• IM
• PhoneNumber
• PostalAddress
• Rating
• GeoPt
シリアライズされたクラスのデータス
トア
( Blob 型)
public class DownloadableFile implements Serializable {
private byte[] content;
private String filename;
private String mimeType;

// ... accessors ...


}

@Persistent(serialized = "true")
private DownloadableFile file;
Google Accounts Java API
最後に
• 「京都 IT エンジニア飲み会」というグル
ープをやっているので、ぜひご参加くだ
さい。
– http://groups.google.co.jp/group/kyoto-it

スパム対策のために承認制になっておりま
すが、オープンなグループですので、おき
がるにご参加いただけます。

ネットでこの資料をごらんになった方も、
関西圏・京都近郊の IT エンジニアの方はぜ
ひご参加ください。
Photo by (c)Tomo.Yun http://www.yunphoto.net

You might also like