Soumettre la recherche
Mettre en ligne
appengine java night #3
•
4 j'aime
•
1,056 vues
B
bluerabbit777jp
Suivre
実際に作ってわかったApp Engineの困ったところ
Lire moins
Lire la suite
Technologie
Signaler
Partager
Signaler
Partager
1 sur 57
Télécharger maintenant
Télécharger pour lire hors ligne
Recommandé
Ajax 応用
Ajax 応用
Katsuyuki Seino
traitを使って楽したい話
traitを使って楽したい話
infinite_loop
jQuery超入門編
jQuery超入門編
Yasuhito Yabe
HTMLの要素の選び方
HTMLの要素の選び方
TENTO_slide
PHP5.5新機能「ジェネレータ」初心者入門
PHP5.5新機能「ジェネレータ」初心者入門
kwatch
Android Lecture #03 @PRO&BSC Inc.
Android Lecture #03 @PRO&BSC Inc.
Yuki Higuchi
appengine ja night 16 BT Frontend cache control
appengine ja night 16 BT Frontend cache control
bluerabbit777jp
Programming in pain
Programming in pain
Enno Runne
Recommandé
Ajax 応用
Ajax 応用
Katsuyuki Seino
traitを使って楽したい話
traitを使って楽したい話
infinite_loop
jQuery超入門編
jQuery超入門編
Yasuhito Yabe
HTMLの要素の選び方
HTMLの要素の選び方
TENTO_slide
PHP5.5新機能「ジェネレータ」初心者入門
PHP5.5新機能「ジェネレータ」初心者入門
kwatch
Android Lecture #03 @PRO&BSC Inc.
Android Lecture #03 @PRO&BSC Inc.
Yuki Higuchi
appengine ja night 16 BT Frontend cache control
appengine ja night 16 BT Frontend cache control
bluerabbit777jp
Programming in pain
Programming in pain
Enno Runne
デブサミ2011 LT大会【17-E-7】appengine ja night
デブサミ2011 LT大会【17-E-7】appengine ja night
bluerabbit777jp
aspectos preliminares
aspectos preliminares
david
מצגת רצוי ומצוי קריית חיים
מצגת רצוי ומצוי קריית חיים
avi6680
Podcamp Philly Presentation Nota Pro Nota Problem
Podcamp Philly Presentation Nota Pro Nota Problem
ProducePicker
Aplicaciones de drones en el Perú, experiencias de la PUCP
Aplicaciones de drones en el Perú, experiencias de la PUCP
Andres Flores
Real generics
Real generics
Enno Runne
რიცხვითი მახასიათებლები
რიცხვითი მახასიათებლები
marina58
Scala For Java Programmers
Scala For Java Programmers
Enno Runne
Exposicinn resumen
Exposicinn resumen
david
aspectos
aspectos
david
Silabo evaluacion educativa pato tobar
Silabo evaluacion educativa pato tobar
david
Rm 01-last
Rm 01-last
tomkacy
Rm 02 v2
Rm 02 v2
tomkacy
Rm 06
Rm 06
tomkacy
Rm 06-v2
Rm 06-v2
tomkacy
Rm 07-v1
Rm 07-v1
tomkacy
Rm 01-last
Rm 01-last
tomkacy
Rm 05-v2
Rm 05-v2
tomkacy
Rm 10
Rm 10
tomkacy
Rm 12
Rm 12
tomkacy
Google App Engineでできる、あんなこと/こんなこと
Google App Engineでできる、あんなこと/こんなこと
a-know
MailFluteでメール送信を楽しもう!
MailFluteでメール送信を楽しもう!
p1us2er0
Contenu connexe
En vedette
デブサミ2011 LT大会【17-E-7】appengine ja night
デブサミ2011 LT大会【17-E-7】appengine ja night
bluerabbit777jp
aspectos preliminares
aspectos preliminares
david
מצגת רצוי ומצוי קריית חיים
מצגת רצוי ומצוי קריית חיים
avi6680
Podcamp Philly Presentation Nota Pro Nota Problem
Podcamp Philly Presentation Nota Pro Nota Problem
ProducePicker
Aplicaciones de drones en el Perú, experiencias de la PUCP
Aplicaciones de drones en el Perú, experiencias de la PUCP
Andres Flores
Real generics
Real generics
Enno Runne
რიცხვითი მახასიათებლები
რიცხვითი მახასიათებლები
marina58
Scala For Java Programmers
Scala For Java Programmers
Enno Runne
Exposicinn resumen
Exposicinn resumen
david
aspectos
aspectos
david
Silabo evaluacion educativa pato tobar
Silabo evaluacion educativa pato tobar
david
Rm 01-last
Rm 01-last
tomkacy
Rm 02 v2
Rm 02 v2
tomkacy
Rm 06
Rm 06
tomkacy
Rm 06-v2
Rm 06-v2
tomkacy
Rm 07-v1
Rm 07-v1
tomkacy
Rm 01-last
Rm 01-last
tomkacy
Rm 05-v2
Rm 05-v2
tomkacy
Rm 10
Rm 10
tomkacy
Rm 12
Rm 12
tomkacy
En vedette
(20)
デブサミ2011 LT大会【17-E-7】appengine ja night
デブサミ2011 LT大会【17-E-7】appengine ja night
aspectos preliminares
aspectos preliminares
מצגת רצוי ומצוי קריית חיים
מצגת רצוי ומצוי קריית חיים
Podcamp Philly Presentation Nota Pro Nota Problem
Podcamp Philly Presentation Nota Pro Nota Problem
Aplicaciones de drones en el Perú, experiencias de la PUCP
Aplicaciones de drones en el Perú, experiencias de la PUCP
Real generics
Real generics
რიცხვითი მახასიათებლები
რიცხვითი მახასიათებლები
Scala For Java Programmers
Scala For Java Programmers
Exposicinn resumen
Exposicinn resumen
aspectos
aspectos
Silabo evaluacion educativa pato tobar
Silabo evaluacion educativa pato tobar
Rm 01-last
Rm 01-last
Rm 02 v2
Rm 02 v2
Rm 06
Rm 06
Rm 06-v2
Rm 06-v2
Rm 07-v1
Rm 07-v1
Rm 01-last
Rm 01-last
Rm 05-v2
Rm 05-v2
Rm 10
Rm 10
Rm 12
Rm 12
Similaire à appengine java night #3
Google App Engineでできる、あんなこと/こんなこと
Google App Engineでできる、あんなこと/こんなこと
a-know
MailFluteでメール送信を楽しもう!
MailFluteでメール送信を楽しもう!
p1us2er0
jQuery勉強会#4
jQuery勉強会#4
Ryo Maruyama
Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例
Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例
Yoshifumi Kawai
20120405 setsunaセミナー
20120405 setsunaセミナー
Takahiro Iwase
認証機能で学ぶ Laravel 5 アプリケーション
認証機能で学ぶ Laravel 5 アプリケーション
Masashi Shinbara
データマイニング+WEB勉強会資料第6回
データマイニング+WEB勉強会資料第6回
Naoyuki Yamada
IoT時代におけるストリームデータ処理と急成長の Apache Flink
IoT時代におけるストリームデータ処理と急成長の Apache Flink
Takanori Suzuki
Let's build a simple app with .net 6 asp.net core web api, react, and elasti...
Let's build a simple app with .net 6 asp.net core web api, react, and elasti...
Shotaro Suzuki
ボット開発でも DevOps! BotBuilder のテスト手法
ボット開発でも DevOps! BotBuilder のテスト手法
Kenichiro Nakamura
Data apiで実現 進化するwebの世界
Data apiで実現 進化するwebの世界
Yuji Takayama
jQuery Validation x ASP.NET MVC で遭遇した不具合 & 対抗ハック
jQuery Validation x ASP.NET MVC で遭遇した不具合 & 対抗ハック
Jun-ichi Sakamoto
TotalViewを使った代表的なバグに対するアプローチ
TotalViewを使った代表的なバグに対するアプローチ
RWSJapan
Entity Framework 5.0 deep dive
Entity Framework 5.0 deep dive
Atsushi Fukui
Jhs team portfolio2
Jhs team portfolio2
ssuser25d7ff
Twitter連携chrome extension作り方
Twitter連携chrome extension作り方
Hiroshi Oyamada
★2章
★2章
啓行 主藤
Inside mobage platform
Inside mobage platform
Toru Yamaguchi
Apache Torqueについて
Apache Torqueについて
tako pons
【18-C-4】Google App Engine - 無限の彼方へ
【18-C-4】Google App Engine - 無限の彼方へ
Developers Summit
Similaire à appengine java night #3
(20)
Google App Engineでできる、あんなこと/こんなこと
Google App Engineでできる、あんなこと/こんなこと
MailFluteでメール送信を楽しもう!
MailFluteでメール送信を楽しもう!
jQuery勉強会#4
jQuery勉強会#4
Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例
Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例
20120405 setsunaセミナー
20120405 setsunaセミナー
認証機能で学ぶ Laravel 5 アプリケーション
認証機能で学ぶ Laravel 5 アプリケーション
データマイニング+WEB勉強会資料第6回
データマイニング+WEB勉強会資料第6回
IoT時代におけるストリームデータ処理と急成長の Apache Flink
IoT時代におけるストリームデータ処理と急成長の Apache Flink
Let's build a simple app with .net 6 asp.net core web api, react, and elasti...
Let's build a simple app with .net 6 asp.net core web api, react, and elasti...
ボット開発でも DevOps! BotBuilder のテスト手法
ボット開発でも DevOps! BotBuilder のテスト手法
Data apiで実現 進化するwebの世界
Data apiで実現 進化するwebの世界
jQuery Validation x ASP.NET MVC で遭遇した不具合 & 対抗ハック
jQuery Validation x ASP.NET MVC で遭遇した不具合 & 対抗ハック
TotalViewを使った代表的なバグに対するアプローチ
TotalViewを使った代表的なバグに対するアプローチ
Entity Framework 5.0 deep dive
Entity Framework 5.0 deep dive
Jhs team portfolio2
Jhs team portfolio2
Twitter連携chrome extension作り方
Twitter連携chrome extension作り方
★2章
★2章
Inside mobage platform
Inside mobage platform
Apache Torqueについて
Apache Torqueについて
【18-C-4】Google App Engine - 無限の彼方へ
【18-C-4】Google App Engine - 無限の彼方へ
appengine java night #3
1.
appengine java night #3
実際に作ってわかった App Engine の困ったところ source: http://www.flickr.com/photos/katemonkey/122489910/
2.
自己紹介 はてなID:bluerabbit twitterID:bluerabbit777jp
3.
内容 「雨の日め〜る」というサービスを作りま した。 実際にApp Engineで作るにあたって困っ たことをどのように回避したかをお話しま す。
4.
雨の日め〜るとは 会社帰りに・・・ 「あれっ。今日って雨だったの?」と 傘を忘れた経験がある。 そんなあなたのためのサービスです。 傘忘れを防止する為に作りました。
5.
仕組み 「雨の日め〜る」は天気が雨の場合に 天気予報メールを送信する。 実現するための機能は下記3つ。 天気予報を取得する 天気予報をメールする
ユーザ登録
6.
天気予報を取得する 天気予報をUrlFetch APIを用いて取得 天気予報は朝(6:00)に取得 利用者のお住まいの地域は142用意 142の地域の天気予報をDatastoreに保存 ユーザの指定した時間にメールする
これらをバッチ処理で行う。
7.
しかし
8.
立ちはだかる App Eengineの制約
9.
制約その1 1 リクエストは30秒以内に処理すべし
HardDeadlineExceededError http://code.google.com/intl/ja/appengine/docs/whatisgoogleappengine.html
10.
App Engineではバッチ
処理も30秒以内 天気予報を取得するために次のようにした。 Cronで1分毎に実行 各地域の天気予報を取得 取得済みの地域はスキップ 天気予報をDatastoreへ保存 ※当時はTaskQueueがリリースされていなかった。
11.
処理イメージ
12.
処理時間30分orz...
13.
TaskQueueで高速化 TaskQueueを使って並列処理
1地域毎に1タスク、142のTaskで実行する Cronは指定時間にQueueを追加するだけ for (Location location : Location.getAll()) { QueueFactory.getDefaultQueue(). add(TaskOptions.Builder .url("/crawler") .param("locationID",location.getId())); }
14.
処理イメージ
15.
処理時間3分
16.
App Engineでの
バッチ処理 バッチ処理でも30秒以内に処理 結果的にTaskQueueを使う必要あり キューを使うことで非同期、並列処理となる 非同期、並列処理の知識と経験が必要 既存プログラムをApp Engineに移行する場合 にバッチ処理は処理方式を変更する必要に迫 られる
17.
こんなバッチの場合は
どうする? 1Taskが30秒以内に終わらない バッチが終わったことを知りたい
18.
1Taskが30秒以内に
終わらない 機能を分割する。1機能を30秒以内に分割 当該アプリの例だと1Taskの機能は下記 Fetch Parse Insert 機能別にTaskを実行するようにする
19.
TaskQueueを
チェインする Fetch処理の最後にParseのキューを追加 Parse処理の最後にInsertのキューを追加 Insert処理を実行してDatastoreに登録する
20.
処理イメージ
21.
バッチが終わったことを
知りたい 処理件数で把握する 複数リクエスト(TaskQueue)間で連番を作 成する 連番の処理件数がキューを追加した件数 と同じだったらバッチ終了と判断する
22.
カウンター Sharding Counter
書き込みが集中しないように複数のエン ティティに分散して書き込みし集計する Memcache Counter Memcacheを用いた簡易カウンター Memcache Counterを紹介
23.
Memcache Counter MemcacheのLow Level
API MemcacheService#incrementはアトミックに 実行される TaskQueueなどで複数のスレッドが同時にア クセスしても連番が補償される MemcacheServiceのjava doc
24.
APIの使用例 MemcacheService s
= MemcacheServiceFactory.getMemcacheService(); if (!s.contains("MemcacheCounter")) { s.put("MemcacheCounter", 1); // 初期化は1 } else { // 2回目以降は値に+1する s.increment("MemcacheCounter", 1); } // 実行のたびに1,2,3,4,5になる System.out.println(s.get("MemcacheCounter")); http://d.hatena.ne.jp/bluerabbit/20091008/1255007854
25.
天気予報をメールする 天気予報が雨かを判断する。 特定の時間になったらメールする。
これらをバッチ処理で行う。 しかし、ここにも制約が存在する。
26.
制約その2 MailAPI の呼出回数は24時間あたり 7000件(1分間に32件)までにすべし
http://code.google.com/intl/ja/appengine/docs/quotas.html#Mail
27.
Mailの回数を制御する メール送信はDatastoreを用いた自作Queue を使用する。 メール送信する場合はMailQueueのKind (テーブル)にEntity(データ)を保存する。 MailQueueの送信はCronにて1分毎に MailQueueに未送信があればメールするよう にする。
28.
処理イメージ
29.
この処理には2つの 誤りがある 1.ユーザ数が増加した場合に _____しない。
スケール 2.エラーが発生した場合に ________の危険性がある メール二重送信
30.
制約その3 Datastore は定期的にエラーが出る
ことを許容すべし DatastoreTimeoutException ApiProxy$UnknownException CapabilityDisabledException
31.
ユーザ登録 下記のユーザ情報を登録する 受信するメールアドレス 受信する時間
受信する曜日 お住まいの地域 メールでユーザ登録の確認をする MailQueueを作成する 上記の2つのEntityを登録する
32.
制約その4 トランザクションは設計する必要がある RDB のように使えないことを許容すべし
33.
(案1) EntityGroup ユーザとメールキューをEntityGroup関係 にする
※説明のため、意図的にJDOのイメージで記載しています。 App Engine のEntityGroupを理解しよう
34.
(案2) 非正規化 1リクエストで複数のEntityを登録しない。 1つのEntityですべて処理する
35.
(案3) TaskQueue 1リクエストで複数のEntityを登録しない。 1リクエストは1Entityのみ登録する。 MailQueueはTaskQueueで登録する。
36.
(案4) 考慮しない エラーがたまに出ることを前提とする 一時的に不整合になることを許容する 偶発的に起こる事象に対して柔軟に対応で きるように備える エラー、不整合を早急に発見する方法を
作りこむ
37.
(案5) 補償トランザクション トランザクションをプログラムで補償する Insert時
Userの登録は正常終了 MailQueueが異常終了 異常を検知してUserをロールバックする (Userを削除する) Update時 Userを更新する前にバックアップを作成 する(Userをシリアライズして保存) 失敗した場合はバックアップから戻す ※30秒制限があるため実装は困難です。しかし、タスクキューを使えば出来なくもありません。
38.
どれが最適な案? 決め手はなに? 案1)EntityGroup 案2)非正規化 案3)TaskQueue 案4)考慮しない 案5)補償トランザクション
39.
Entity Groupって何? 全てのEntityはEntity Groupに所属 Entity
Group内ではトランザクションをサポート 全ての操作が成功か失敗かになる Entityを作成するときに、別のEntityを新しいEntity の「親」に指定することができる 新しいEntityに対して親を指定することで、その新し いEntityは親Entityと同じEntity Groupに入る 親を持たないEntityはルートエンティティとなる Entityの親はEntityの作成時に定義され、後で変更 することはできない Entity Group全体に対してトランザクションの排他処 理は実行される
40.
ルートエンティティ String kind =
"User"; Key userKey = KeyFactory.createKey(kind, 1); Entity user = new Entity(userKey); DatastoreService ds = DatastoreServiceFactory. getDatastoreService(); ds.put(user); KEY Kind User(1) User
41.
UserにMailQueueを追加 String kind =
"MailQueue"; Key mailKey = KeyFactory.createKey(userKey, kind, 1); Entity mail = new Entity(mailKey); DatastoreService.put(mail); KEY Kind User(1) User User(1)/MailQueue(1) MailQueue
42.
EntityGroupはKeyで構成
KEY Kind User(1) User User(1)/MailQueue(1) MailQueue User(1)/MailQueue(2) MailQueue User(1)/Book(8) Book ※ルートエンティティが子エンティティ を保持している訳ではない
43.
同一Kindでも構成可能
KEY Kind Bank(1) Bank Bank(1)/Bank(2) Bank Bank(1)/Bank(3) Bank Bank(1)/Bank(4) Bank ※注意:排他はEntityGroup全体
44.
EntityGroupの排他 tx = ds.beginTransaction()
; 口座A -1000円 口座B +1000円 tx = ds.beginTransaction() ; 口座C = ds.get(tx, keyC); tx.commit(); 口座C -2000 口座D +2000 // ConcurrentModificationException tx.commit(); ※口座A、B、C、DはEntityGroupです。
45.
トランザクション内の分離レベルは
SERIALIZABLE tx = ds.beginTransaction() ; 口座A = ds.get(tx, keyA); 口座A 残高照会 1000円 tx = ds.beginTransaction() ; 口座A -1000円 口座B +1000円 tx.commit(); 口座B = ds.get(tx, keyB); 口座B 残高照会 0円 ※リクエスト前は口座Bの残高は0円です。
46.
その他 困ったこと
47.
制約その5 App Engine
のDatastoreには ユニークキー制約がつけられない
48.
ユニークキー制約が ないのでこんなミス TaskQueueで以下の登録処理を実行した 1. パラメータでEntityの登録値を取得 2. Datastoreに新規登録 3.
終了処理 2.の処理後にエラーが出たら リトライされて2重登録された
49.
対応策 TaskQueueで登録処理する場合は事前にキー を作成する TaskQueueの追加処理
1. キューで登録するキーを作成する 2. キーをTaskのパラメータに設定する 登録処理 1. キーのパラメータを取得してキーが登録 されているかを確認する 2. 存在しない場合は登録処理をする
50.
処理イメージ(1) // キーを作成する。 DatastoreService service
= DatastoreServiceFactory.getDatastoreService(); KeyRange keys = service.allocateIds("Kind", 1); String key = KeyFactory.keyToString(keys.getStart()); ); // キューのパラメータにキーを設定する QueueFactory.getDefaultQueue(). add(TaskOptions.Builder.url("/insert"). param("key", key)); DatastoreServiceのjava doc
51.
処理イメージ(2) // DatastoreService#get(Key)で登録有無をチェック String keyString
= (String) request.getAttribute("key"); Key key = KeyFactory.stringToKey(keyString); try { DatastoreService service = DatastoreServiceFactory.getDatastoreService(); Entity e = service.get(key); // 登録済み } catch (EntityNotFoundException e) { // 未登録 // → 登録処理を行う }
52.
対応策(2) Keyにユニークな名前をつける TaskQueueの追加処理
特に処理なし 登録処理 1. ユニークになるようにcreateKeyする 例えば、当アプリはLocationIdと日付 2. キーが既に登録されているかを確認する 3. 存在しない場合は登録処理をする
53.
処理イメージ //
Keyを作成 String keyName = "001" + "20091204"; Key key = KeyFactory.createKey("Kind", keyName); DatastoreService ds = DatastoreServiceFactory.getDatastoreService(); try { ds.get(key); } catch (EntityNotFoundException e) { Entity entity = new Entity(key); // 作成キーで登録 ds.put(entity); // 存在しないときにのみ登録 } KeyFactoryのjava doc
54.
まとめ 制約,エラーを寛大な心で受け入れる 制約ではなくルール ルールを守りながらプログラムするゲーム このゲームは必ず開発者を成長させる
55.
Let's Enjoy Cloud
Programming!!
56.
ご清聴ありがとうございました
57.
Questions?
Télécharger maintenant