元COBOLerでJavaなんて知らない俺がGAE/jでアプリなんか組んじゃってるよ!

さすがに、Javaなんて初めて触るのでアレだったが、Eclipseプラグインで何となくできた。

基本的にGAE/jはQuotaがあるので、小さな処理を組んで、DataStoreやMemcacheで紐付けたほうがよさそうだ。(今は、大きなアプリになっちゃってる)
HTTPでGETするような処理をするとTimeOutしやすいので、本当に要注意。

チューニングでは、以下が参考になった。

処理が6000msを超えたので、このあたりを参考にprecompilationをEnableにしたらちょっと楽になった

precompilationはApp Engine Blogによると、App Engineにデプロイする前に(?)クラスローディングの一部の作業を事前に実行することで、クラスローディングの最適化を図るもののようです。現在はオプションのため、有効にするにはappengine-web.xmlに「<precompilation-enabled>true</precompilation-enabled>」と追加する必要があるとのことです。

GAE/J、SDK 1.2.8のprecompilationの効果 : CB NANASHI管理人ブログ

面倒だったので、Low Level APIでのDatastoreは止めたw

対策その1・DatastoreへのアクセスをJDOからLow Level APIにする
いままでJDOを使用していたDatastoreへのアクセスをLow Level APIに全面的に書き換えました。
しかしながら起動時間に関しては、数回の起動を試しましたがほとんど改善されませんでした。
Googleのドキュメントや各種ブログの情報によると、PersistenceManagerFactoryの初期化には時間が掛かるとのことでしたので、改善に期待していましたが当てが外れました。未確認ですが、precompilationをすでにtrueにしていたため効果が出なかったのかもしれません。
ただ、Low Level APIは思ったよりも使いやすいです。JDOに比べてエンティティの状態や、プロパティのlazy loadingなどを考慮しなくてもよい分、単純です。MemcacheにもDatastoreから取得したEntityオブジェクトをそのまま格納できます。反面、DatastoreのEntityとオブジェクト属性のマッピングを自前で行う必要がありますが、面倒くささとしてはJDBCを直接使うのと大差ありません。
ちなみに、JDOからの移行に当たってはデータの保存を忘れることがあり、そこだけ注意が必要でした(JDOは永続化済みのオブジェクトは属性を変更するだけで保存されるため)。

GAE/J、起動時間(spin up時間)短縮の試行錯誤 : CB NANASHI管理人ブログ

大きなテキストファイルをGETしてデータストアに入れようとしたら影響ありました・・・ってことで、今後これで更新する予定。

以下も参照

GAEjでは、エンティティのプロパティがString型だと、500文字までしか扱えないのですか、そうですか。

http://d.hatena.ne.jp/suzune64/20090625/1245910961

Stringの代わりにcom.google.appengine.api.datastore.Textを使えというのですね。わかりました。

http://d.hatena.ne.jp/suzune64/20090625/1245910961

じゃあ、

MyModelClass model = new MyModelClass(); 
BeanUtil.copy(request, model, new CopyOptions().exclude(&quot;content&quot;)); 
model.setContent(new Text(asString(&quot;content&quot;))); 
pm.makePersistent(model); 

これでいいのでしょうか。
・・・。
うん、良いようです。更新は、行えたみたいです。

http://d.hatena.ne.jp/suzune64/20090625/1245910961


あの、ひがやすおさんのところにも書いてあった。ってことでメモ。

Google App Engineでは、500バイト以上のバイトの配列や文字列を格納する型として、BlobやTextを用意しています。これらの型を使うときには、フィールドの型は、BlobやTextにし、getter, setterメソッドは、byteの配列やStringにしておくと、モデルを使う側は、500バイトの制限を気にせず、常にbyteの配列やStringでアクセスできるのでお勧めです。

GAEでBlobやTextを定義する方法 - yvsu pron. yas

なぜか、Firefoxで接続するとタイムアウトを起こさないのに、Cronだと10倍以上の時間がかかる・・・Cron-job.orgを使って様子見

Cron-job.org はドイツの方が提供している、特定の URL に定期的にアクセスしてくれるサービスで、完全に無料で提供(2008/10 現在)されています。
現在のところ、インターフェイスはドイツ語のみで提供されドイツ国内専用のサービスのように見えますが、筆者が運営者に問い合わせたところ『もちろん、日本の方々が利用することもできます。ただし、残念なことにサービスはドイツ語のみですので、利用にあたっては翻訳サービスを使ってください』とのありがたい回答をいただきました。

cron タスクの設定 【 Cron-job.org の利用】 | ≡ Drupal Japan ≡

キューというのも考えたほうが良いかもしれない。

処理をキューに積んで、アプリケーションとは非同期に処理させることが出来る。
キューはいくつか(?)用意できるので、仕事を分割して、キューに分散させて積んで並列に処理。
処理結果をMemCacheなりDatastoreなり保存して、最後にマージすることで、並列処理が出来るという寸法。
並列処理で力を発揮すると思われるTaskQueueは、排他がどうの、スケールがどうのと、
面倒なことを考えなければ簡単に使える。

http://pixiv.cc/mix3/archives/51343747.html


TaskQueueを使う上ではこれ要注意。

SDK 1.2.5からGoogle App EngineにTaskQueueが導入されましたが、ローカル(development server)でデバッグはできないと思っている人が結構いるようなので、やり方を書いておきます。
ローカルの環境では、Queueにaddしたタスクは、自動的には実行されず、Queueにたまっています。たまっているタスクを実行するには、http://localhost:8080/_ah/adminにアクセスし、左側のTask Queuesのリンクをクリックします。
すると、Queueの一覧が表示されるので、そこでQueueのリンクをクリックすると、タスクを実行する画面に遷移します。そこで、runのボタンを押すと、ローカルでQueueのタスクを実行できます。

TaskQueueをローカルでデバッグする方法 - yvsu pron. yas


GET でアクセスさせるには、
Queue queue = QueueFactory.getDefaultQueue();
queue.add(url("/path?a=b&c=d").method("GET"));
ってするようにドキュメントには書いてあるんだけれど、そのとおりにやってみると「com.google.appengine.api.labs.taskqueue.TaskOptions に method(String) なんてないぞ」と eclipse に怒られる…。ここは

GAE/J、TaskQueue 使ってみた | クリボウのプログラミングひとりごと


Java自体を良く知らなかったのでググりながら作ってますが、URLConnectionのDisconectが無いのは、

I have found that class "URLConnection" has methods to establish a connection, for example, method "openConnection" and method "connect". But I have not found any methods of this class which are dealing with disconnect. I am wondering if I use class "URLConnection" to establish an HTTP connection to a remote host, what is the correct, clean and efficient approach to disconnect from remote host or close the connection.

java - Question about URLConnection | DaniWeb

ストリームを全部閉じたら終わるって話。

3) if you close all streams you get from the URLConnection the connection is gone.

java - Question about URLConnection | DaniWeb