第一回京都Google App Engine for Java勉強会

Preview:

Citation preview

第一回 京都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 ファイルもロードできます。

ここだけの話。。。

http://blogs.webtide.com/gregw/entry/google_appengine_uses_jetty

javax.servlet.ServletException: This is an exception

at com.acme.HelloWorld.doGet(HelloWorld.java:48)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:689)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)

at org.mortbay.jetty.servlet.ServletHolder$SingleThreadedWrapper.service(ServletHolder.java:617)

at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)

at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1093)

at com.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionFilter.java:35)

at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084)

at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)

at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084)

at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:360)

at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)

at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)

at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:712)

at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)

at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:237)

at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:139)

at org.mortbay.jetty.Server.handle(Server.java:313)

at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:506)

at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:830)

at com.google.apphosting.runtime.jetty.RpcRequestParser.parseAvailable(RpcRequestParser.java:63)

at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:381)

ここだけの話。。。at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:125)

at com.google.apphosting.runtime.JavaRuntime.handleRequest(JavaRuntime.java:235)

at com.google.apphosting.base.RuntimePb$EvaluationRuntime$6.handleBlockingRequest(RuntimePb.java:4547)

at com.google.apphosting.base.RuntimePb$EvaluationRuntime$6.handleBlockingRequest(RuntimePb.java:4545)

at com.google.net.rpc.impl.BlockingApplicationHandler.handleRequest(BlockingApplicationHandler.java:24)

at com.google.net.rpc.impl.RpcUtil.runRpcInApplication(RpcUtil.java:359)

at com.google.net.rpc.impl.Server$2.run(Server.java:792)

at com.google.tracing.LocalTraceSpanRunnable.run(LocalTraceSpanRunnable.java:56)

at com.google.tracing.LocalTraceSpanBuilder.internalContinueSpan(LocalTraceSpanBuilder.java:489)

at com.google.net.rpc.impl.Server.startRpc(Server.java:748)

at com.google.net.rpc.impl.Server.processRequest(Server.java:340)

at com.google.net.rpc.impl.ServerConnection.messageReceived(ServerConnection.java:422)

at com.google.net.rpc.impl.RpcConnection.parseMessages(RpcConnection.java:319)

at com.google.net.rpc.impl.RpcConnection.dataReceived(RpcConnection.java:290)

at com.google.net.async.Connection.handleReadEvent(Connection.java:419)

at com.google.net.async.EventDispatcher.processNetworkEvents(EventDispatcher.java:733)

at com.google.net.async.EventDispatcher.internalLoop(EventDispatcher.java:207)

at com.google.net.async.EventDispatcher.loop(EventDispatcher.java:101)

at com.google.net.rpc.RpcService.runUntilServerShutdown(RpcService.java:249)

at com.google.apphosting.runtime.JavaRuntime$RpcRunnable.run(JavaRuntime.java:373)

at 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 という機能が搭載され、利用料の上限を設定できるようになりました。

標準的な設定Resource(% of Budget) Budget Unit Cost Paid Quota Free Quota

Total Daily Quota

CPU Time 60% $1.20 $0.10 11.99 46.30 58.29 CPU 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, I

CO

• 切り出し• 回転• リサイズ• 色調変更• サーバーリソースが空いているいる時には 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/appengine-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 JDOFatalUserException

500 バイト以下の byte列

com.google.appengine.api.datastore.ShortBlob

byteオーダー JDOFatalUserException

boolean型 boolean or java.lang.Boolean

false < true

integer型 short, java.lang.Short, int, java.lang.Integer, long, java.lang.Long

数字 long integer のサイズを超えるとオーバーフローする

浮動小数点型 float, java.lang.Float, double, java.lang.Double

数字 double幅を超えるとオーバーフローする

date time型 java.util.Date 日付順

Google アカウント型 com.google.appengine.api.users.User

メールアドレス (Unicode)順

長いテキスト型 com.google.appengine.api.datastore.Text

(オーダー不能) インデックスされない

長い byte列型 com.google.appengine.api.datastore.Blob

(オーダー不能) インデックスされない

エンティティキー型 com.google.appengine.api.datastore.Key, 参照オブジェクト

パス順

URL com.google.appengine.api.datastore.Link

Unicode

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