約 5,554,189 件
https://w.atwiki.jp/appengine/pages/16.html
原文 id hamatsu1974 さんの 翻訳エントリ ※このページは翻訳の途中です。 Google App Engineってなに? Google App EngineはGoogleのインフラストラクチャを使用して、あなたのWebアプリケーションを走らせることができます。 App Engineアプリケーションはビルド、メンテナンス、データやトラフィックの増大に対するスケーリングが超簡単にできてしまいます。 App Engineを使えば、メンテナンスするべきサーバーはもうどこにもありません。 あなたのアプリケーションをアップロードして、ユーザーにサービスを提供するだけです。 あなたはappspot.com上にアプリケーションが使うドメイン名を自由につけて使用するか、 Google Apps に独自のドメインを割り当てることができます。 あなたはアプリケーションを全世界に公開するか、あなたの活動のメンバーにアクセスを制限することができます。 App Engineをはじめるのにお金はかかりません。 フリーのアカウントにサインアップしさえすれば、何のチャージも義務もなく、アプリケーションを開発して世界にパブリッシュできます。 フリーのアカウントでは500MBのストレージ、十分なCPU、月に500万ページビューまで使用することが出来ます。 Google App Engineがプレビューリリースの間はフリーのアカウントだけが利用可能です。 近いうちに追加のリソースを購入することが出来るようになるでしょう。 アプリケーション開発環境 Google App Engineは、大量のデータやトラフィックを扱うことになるような場合でも、安定して稼動するアプリケーションを簡単に構築することが出来ます。 開発環境には以下の機能があります。 ダイナミックなWebを提供し、一般的なWebテクノロジーをフルサポート クエリ、ソート、トランザクションによる永続的なストレージ 自動的なスケーリングとロードバランシング Googleアカウントを使ったユーザー認証とメール送信のAPI群 Google App EngineをローカルPC上でシミュレートするフル機能のローカル開発環境 Google App Engineアプリケーションは Python言語 を使うように実装されています。 ランタイム環境はPython言語をフルサポートし、Pythonのほとんどの標準ライブラリを含んでいます。 現在、PythonはGoogle App Engineでサポートされている唯一の言語ですが、 将来たくさんの言語をサポートすることを楽しみにしています。 サンドボックス アプリケーションはOSへの限られたアクセスを提供されたセキュアな環境で実行されます。 これらの制限があることでApp Engineに、いろいろなサーバーをまたがったアプリケーションへのWebリクエストを処理することを可能にし、トラフィックに合わせて、サーバーを起動させたり停止させたりすることが出来るようになります。 サンドボックスはあなたのアプリケーションを、ハードウェア、OS、Webサーバーの物理的な場所からも独立した、信頼できるセキュアな環境に分離させます。 例えば、セキュアなサンドボックス環境で制限されていることは アプリケーションはインターネット上にある他のコンピュータにアクセスするには、提供されたURLのフェッチ、Eメール、API群を使用するしかありません。他のコンピュータからアプリケーションにアクセスするにはHTTPかHTTPSを標準ポートでアクセスすることしか出来ません。 アプリケーションはファイルシステムに書き込みが出来ません。アプリケーションはアプリケーションのコードによってアップロードされたファイルしか読むことしか出来ません。アプリケーションはリクエストの間保持するすべてのデータにApp Engine datastoreを使用しなければいけません。 アプリケーションコードはWebリクエストのレスポンスとしてのみ動作し、数秒以内にレスポンスを返さなければいけません。リクエストハンドラからサブプロセスを生成したり、レスポンスを返した後にコードを実行することは出来ません。 Pythonランタイム環境 App EngineはPython言語を使ったランタイム環境を提供します。 他のプログラミング言語とランタイム環境設定は将来的にリリースされるでしょう。 Pythonランタイム環境はPythonのヴァージョン 2.5.2を使用しています。 環境には Pythonの標準ライブラリ を含んでいます。もちろんサンドボックスを壊すようなライブラリメソッドは制限されています。 ソケットをオープンしたりファイルに書き込んだりするようなことをしても失敗します。 利便性のために標準ライブラリのうちのいくつかのモジュールのコアな機能はランタイム環境でサポートされておらず、それらをインポートしようとした時にエラーになるでしょう。 アプリケーションコードは全てPythonで書かれていなければいけません。 C言語による拡張はサポートされていません。 Python環境は datastore 、 Googleアカウント 、 URLフェッチ や Eメール サービスのリッチなPython APIを提供します。 App Engineはまた、webappと呼ばれる簡単にアプリケーションの構築を開始するためのシンプルなPython Webアプリケーションフレームワークを提供します。 利便性のためにApp Engineには DjangoというWebアプリケーションフレームワーク のヴァージョン0.96.1を含んでいます。 気をつけるのはApp EngineのdatastoreはDjangoのいくつかのコンポーネントが必要とするリレーショナルデータベースではないということです。 いくつかのコンポーネントのひとつのDjangoテンプレートエンジンを使うには他にもう少し努力が必要です。 App EngineでDjangoを使う際のTipsの 記事 を見てください。 あなたはPure Pythonで書かれていてサポートされていないライブラリを必要としないサードパーティのライブラリをあなたのアプリケーションと一緒にアップロードすることが出来ます。 これ以上のPythonランタイムに関する情報はPythonランタイム環境?を見てください。 データストア App Engineはクエリエンジンとトランザクション機能を持つ、パワフルな分散データベースストレージを提供します。 分散Webサーバーがトラフィックに合わせて成長するように、分散データベースもデータ量によって成長します。 App Engineのデータストアは従来のリレーショナルデータベースとは違います。データオブジェクト(または「エンティティ」)には、種類とプロパティのセットがあります。クエリを使って、指定した種類のエンティティをプロパティの値によってフィルターにかけ、ソートした状態で取得することができます。 プロパティの値は サポートされた値 ならばどれでも指定することが出来ます。 The Python API for the datastore includes a data modeling interface that can define a structure for datastore entities. A data model can indicate that a property must have a value within a given range, or provide a default value if none is given. Your application can provide as much or as little structure to the data as it needs. The datastore uses optimistic locking for concurrency control. An update of a entity occurs in a transaction that is retried a fixed number of times if other processes are trying to update the same entity simultaneously. Your application can execute multiple datastore operations in a single transaction which either all succeed or all fail, ensuring the integrity of your data. The datastore implements transactions across its distributed network using "entity groups." A transaction manipulates entities within a single group. Entities of the same group are stored together for efficient execution of transactions. Your application can assign entities to groups when the entities are created. For more information about the datastore, see the Datastore API reference.
https://w.atwiki.jp/cappu/pages/42.html
リンク Google App Engine Google App Engine for Java Eclipse Plugin アップデートサイト http //dl.google.com/eclipse/plugin/3.4 サンプルページを作った http //javaagogo.appspot.com/ SSL対応方法 appengine-web.xmlに以下を追加するだけ ssl-enabled true /ssl-enabled https //javaagogo.appspot.com/
https://w.atwiki.jp/memo77/pages/62.html
Google App Engine についてcomment Google App Engine について 2008/10/24 http //code.google.com/intl/ja/appengine/docs/whatisgoogleappengine.html Google App Engine 修行開始。python覚える。 comment このページの記述で聞きたいこととか間違ってることとかありましたらコメントを。 名前 コメント すべてのコメントを見る
https://w.atwiki.jp/appengine/pages/17.html
なんでもかんでもGoogle App Engine情報検索してみたYahoo pipes rss RSSへのリンク showrss プラグインエラー RSSが見つからないか、接続エラーです。
https://w.atwiki.jp/vsync/pages/21.html
Google App Engine とは? Google App Engine を使用すると、Google のインフラ上で自作の Web アプリケーションを実行できる。 トラフィックやデータ ストレージの増大に合わせて容易なスケーリングが可能。 作成したアプリケーションは、Google Apps を使用して任意のドメイン(たとえばhttp //www.example.com/)から提供できる。 Google App Engine では、さまざまなプログラミング言語で記述したアプリケーションがサポートされるjava Python等。 App Engine は無料で始めることができます。最大 500 MB の永続性ストレージに加え、月間約 500 万ページ ビューに対応できる十分な CPU と帯域幅をもつ。 Javaで作るGoogle App Engineの解説本↓ すっきりわかるGoogle App Engine for Javaクラウドプログラミング Google App Engine for Java [実践]クラウドシステム構築 (WEB+DB PRESS plus) (WEB+DB PRESSプラスシリーズ) (WEB+DB PRESS plusシリーズ) PythonとJavaにも対応のGoogle App Engineの解説本↓ 新人プログラマのためのGoogle App Engineクラウド・アプリケーション開発講座―JAVA PYTHON対応
https://w.atwiki.jp/mekagazira/pages/37.html
Google App Engine Google App Engine Strutsの利用 Strutsの利用 Struts 1.3.10のダウンロード Examples struts-1.3.10-apps.zipをダウロンドーする。 http //struts.apache.org/download.cgi#struts1310 struts-examples-1.3.10.warを取り出す。 struts-examples-1.3.10.warを解凍し、struts-examples-1.3.10\WEB-INF\srcを別の場所に一時移動しておく。 EclipseでGAEJのプロジェクトを作成する。 GoogleWebツールキットを使用のチェックを外して完了ボタン war\WEB-INF\lib配下のjarファイルを確認する。 このjarファイルは、ビルド・パスを通すときに対象外となるjarのライブラリになる。 解凍したstruts-examples-1.3.10のwarの中身を、eclipseのwarフォルダの中に上書きする。 strutsのライブラリにビルド・パスを通す。 strutsのsrcフォルダの中身をプロジェクトのsrcフォルダへコピーする。 strutsのソースはjavaというフォルダの中にあるので、その中身をsrcフォルダ直下にコピーすればおk ※デフォルトでsrcフォルダ直下に作成されていたパッケージ(?)だかフォルダは削除してもおk コンパイルエラーをちょちょいと直す。 GAEで利用不可の処理を行っているためエラーが発生している。 プロジェクトルート\src\org\apache\struts\webapp\upload\UploadAction.javaの120行~127行をコメントアウトすればおkだった。 //write the file to the file specified // // int bytesRead = 0; // byte[] buffer = new byte[8192]; // while ((bytesRead = stream.read(buffer, 0, 8192)) != -1) { // bos.write(buffer, 0, bytesRead); // } // bos.close(); // data = "The file has been written to \"" + theForm.getFilePath() + "\""; 動作確認する。 エラー発生(;・∀・) HTTP ERROR 500 Problem accessing /welcome.do. Reason Session support is not enabled in appengine-web.xml. To enable sessions, put sessions-enabled true /sessions-enabled in that file. Without it, getSession() is allowed, but manipulation of sessionattributes is not. Caused by java.lang.RuntimeException Session support is not enabled in appengine-web.xml. To enable sessions, put sessions-enabled true /sessions-enabled in that file. Without it, getSession() is allowed, but manipulation of sessionattributes is not. at com.google.apphosting.utils.jetty.StubSessionManager$StubSession.throwException(StubSessionManager.java 67) at com.google.apphosting.utils.jetty.StubSessionManager$StubSession.setAttribute(StubSessionManager.java 63) at org.apache.struts.chain.commands.servlet.SelectLocale.getLocale(SelectLocale.java 68) at org.apache.struts.chain.commands.AbstractSelectLocale.execute(AbstractSelectLocale.java 71) at org.apache.struts.chain.commands.ActionCommandBase.execute(ActionCommandBase.java 51) at org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java 191) at org.apache.commons.chain.generic.LookupCommand.execute(LookupCommand.java 305) at org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java 191) at org.apache.struts.chain.ComposableRequestProcessor.process(ComposableRequestProcessor.java 283) at org.apache.struts.action.ActionServlet.process(ActionServlet.java 1913) at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java 449) at javax.servlet.http.HttpServlet.service(HttpServlet.java 693) at javax.servlet.http.HttpServlet.service(HttpServlet.java 806) at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java 511) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java 1166) at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java 58) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java 1157) at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java 43) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java 1157) at com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java 122) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java 1157) at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java 388) at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java 216) at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java 182) at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java 765) at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java 418) at com.google.apphosting.utils.jetty.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java 70) at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java 152) at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java 349) at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java 152) at org.mortbay.jetty.Server.handle(Server.java 326) at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java 542) at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java 923) at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java 547) at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java 212) at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java 404) at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java 409) at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java 582) war\WEB-INF\appengine-web.xmlへセッションを有効にする記述を追加する。 ?xml version="1.0" encoding="utf-8"? appengine-web-app xmlns="http //appengine.google.com/ns/1.0" application /application version 1 /version !-- Configure java.util.logging -- system-properties property name="java.util.logging.config.file" value="WEB-INF/logging.properties" / /system-properties !--追加-- sessions-enabled true /sessions-enabled /appengine-web-app 再度、ブラウジング確認 http //localhost 8888/welcome.do Struts Examplesのページが表示されればおk
https://w.atwiki.jp/taichik15/pages/40.html
Google App Engine アップロード appcfg update war サーバ起動 dev_appserver.cmd war
https://w.atwiki.jp/fujiyan/pages/15.html
WebコミックLibraryhttp //web-comi.appspot.com/GAE/JとSlim3で作成してみた、各出版社から配信されているWebコミックをまとめて閲覧できるサイトです。只今、実験運用中… 参考サイト 公式サイト(Java) Slim3 Slim3へ appcfg My Applicationsに作成した、GAEアプリケーションの管理を行うコマンドラインツールです。 Google Plugin for Eclipseの場合、SDKがplugins/com.google.appengine.eclipse.sdkbundle_x.x.x.../appengine-java-sdk-x.x.xに存在するので、そのbinフォルダ内にappcfg.cmdがあります。 通常は、環境変数GAE_HOMEに上記のplugins/com.google.appengine.eclipse.sdkbundle_x.x.x.../appengine-java-sdk-x.x.xを設定し、%GAE_HOME%\binをPATHに追加します。 Datastore ~ Operations Quotaの中でも、世の中の頭を悩ませる最大の壁Datastore Read Operations Datastore Write Operations Datastore Small Operations 結論から言えば、Memcacheでキャッシュしまくるしかないです。 とりあえず、キャッシュについて、適当に考察してみました →キャッシュの計画 インスタンス 参考 GAE/PでのBackendsの使い方 - Tari Lari Run GAEでいう「インスタンス」とは、計算リソースのことです。「仮想的なCPU」と考えてもいいでしょう。Javaクラスのインスタンスとは全然別の概念なので、そこを取り違えないように。 GAEのインスタンスの属性としてclassという用語が出てくるけど、やっぱりJavaクラスとは何にも関係ないので注意。 何かしらのJavaクラスのコードを実行する際には、(GAEの)インスタンスが割り当てられて実行します。このとき、コードの起動方法と設定によって、割り当てられるインスタンスが決定されます。 Frontend InstanceとBackend Instance 参考 Properties of Backends(公式サイトのBackends Java API Overviewより) ※Default(Frontend) InstanceとBackend Instanceの比較表です。 通常の、ブラウザからのHTTPリクエストによってアクセスされるServletは、Frontend Instanceが割り当てられます。 CronやTask QueueからアクセスされるServletは、FrontendかBackendが選択できる? 多分、publicのBackendにすれば、ブラウザからのHTTPリクエストに、Backend Instanceを割り当てることができるのかな? Cron 参考 Scheduled Tasks With Cron for Java 定期的に、Servletを自動実行する仕組みです。主に、Webクローラー等の、UIを伴わないバックグラウンド処理に利用されます。 具体的には、定期実行したい処理を記述したServletに対応するURLに対して、設定ファイル(cron.xml)に設定されたタイミングでリクエストを送出します。 例外発生時にcatchしなかった場合でも、リトライは発生しません。 Cronから呼び出されることを想定しているURLは、外部から勝手に呼び出されないように、admin以外はアクセスできないようにしておきましょう(後述の「認証」を参照)。逆に言えば、管理者の場合は、ブラウザからURLを指定してリクエストを送出すれば、Cronからの起動を待たずに強制起動が可能です。 まぁ、結局は単なるServletなのですから、当たり前ですが… スケジュールの指定 参考 The Schedule Format - Scheduled Tasks With Cron for Java 指定可能なのは、下記2パターン。混在は出来ないようです。間隔を指定して実行例 1時間毎に実行 指定日の特定の時刻に実行例 毎日12 00に実行 間隔を指定して実行 下記の形式で指定 every N (hours|mins|minutes) ["from" (time) "to" (time)] 2時間毎に実行の場合 every 2 hours 10 00~14 00の間に、30分毎に実行の場合 every 30 minutes from 10 00 to 14 00 指定日の特定の時刻に実行 下記の形式で指定 ("every"|ordinal) (days) ["of" (monthspec)] (time) 毎日10 00に実行の場合 every day 10 00 Task Queue 参考 Java Task Queue Configuration Servletを非同期実行する仕組みです。主に、UIを伴わないバックグラウンド処理に利用されます。処理を非同期実行可能な単位に分割し、その単位をTaskとして実行させます。 具体的には、非同期実行したい処理を記述したServletに対応するURLを、設定ファイル(queue.xml)で定義したqueueにキューイングします。 キューイングされたURLは、とあるタイミングで取り出されて、リクエストが送出されます。キューからの取り出しをApp Engineに任せるのがPush Queue キューからの取り出しをアプリで指定(Task Queue APIまたはTask Queue REST API)するのがPull Queue 例外発生時にcatchしなかった場合、リトライされます。とは言え、無限にリトライすると、一気にインスタンス時間を消費するので、必ずqueue.xmlの retry-parameters でリトライの上限設定を行いましょう。 Task Queueから呼び出されることを想定しているURLは、外部から勝手に呼び出されないように、admin以外はアクセスできないようにしておきましょう(後述の「認証」を参照)。逆に言えば、管理者の場合は、ブラウザからURLを指定してリクエストを送出すれば、強制起動が可能です。 まぁ、これも結局は単なるServletなのですから、当たり前ですが… リトライ queue.xmlの retry-parameters でリトライの設定 queue-entries queue name testQueue /name retry-parameters task-retry-limit 5 /task-retry-limit /retry-parameters rate 1/s /rate /queue /queue-entries 上記のtestQueueでは、タスクで例外が発生した場合、最大5回のリトライが実施されます。 最大で、最初の1回+リトライ5回=6回実行されます。 task-retry-limit リトライ回数を設定します。5と指定すると、5回のリトライを試みます。 task-age-limit リトライ期間を設定します。例えば、"5d"と指定すると、最初のタスク起動から5日間、リトライを試みます。 task-retry-limit と task-age-limit を同時に指定した場合、両方のリミットに達しするまでリトライする、とありますが、実質 task-retry-limit が優先ですね。例え5日間経過しても、5回に達していなければリトライし続けるので。 min-backoff-seconds と max-backoff-seconds と max-doublings 次のリトライまでのインターバルを決定します。 インターバルは、リトライの度に増加します。1回目は10秒、2回目は20秒、3回目は40秒…、という感じです。 イマイチ、インターバルの計算方法がわかりません。実際に動かすと、予想通りの時間にならない…。 CronとTask Queueの使い分け サンプルとして、Webクローラを想定します。 Webクローラは、サイトA、サイトB、サイトCを巡回します。 サイトA、サイトB、サイトCは、それぞれ独立に巡回することが可能とします。 サイトA、サイトB、サイトCの巡回処理をタスクとして、それぞれの巡回処理を行うServletのURLを/crawlSiteA、/crawlSiteB、/crawlSiteCとします。 各巡回処理のタスクをキューイングする処理を行うServletのURLを/execCrawlersとします。具体的な/execCrawlersの処理は、/crawlSiteA、/crawlSiteB、/crawlSiteCをTask Queueにキューイングします。 Cronで、/execCrawlersを定期起動するようにします。 説明 もし、上記のような構成ではなく、全処理を/execCrawlersのみで構成した場合サイトAでエラーが発生した場合、サイトBやサイトCの巡回が実行されません。 Cronではリトライが無いので、エラーが発生しても、そのままです。 上記構成の場合は、/crawlSiteAでエラーが発生しても、/crawlSiteBや/crawlSiteCは独立して実行されます。 さらに、エラー発生したタスクについては、リトライが実施されます。 とはいえ、クローリングの無制限のリトライは、DoS攻撃に等しいので、リトライの上限を設けておきましょう。 Backends Backend Instanceを用いて、コードを実行させます。 backends.xml Java Backends Configuration Backendsの設定をbackends.xmlに記述します。 backends.xmlはWEB-INF直下に配置します。 backends backend name="test-instance" class B1 /class options dynamic true /dynamic /options /backend /backends 上記の場合、test-instanceというnameのBackend Instanceを定義します。インスタンスの名前は全て小文字じゃないと、deploy時に怒られます。 複数のBackend Instanceを定義したい場合は、 backend を並べていきます。 インスタンスのclassとしてB1を指定してます。classの種類についてはInstance Classesを参照 まぁ、課金しなければ、ほぼB1ですね。 インスタンスのタイプとしてDynamicを指定しています。インスタンスには、Resident(常駐型)とDynamic(動的起動型)の2種類があります。 詳しくはTypes of Backendsを参照 これもまぁ、課金しなければ、ほぼDynamicですね。 ようするに、上の設定は、一番ケチな設定です。 もうすこし詳しく Backendsの無料枠は9インスタンス時間B1を1時間稼動させる単位を1インスタンス時間とします。 classが1つあがる毎に、消費単位が2倍となります。 B2で1時間稼動させれば2インスタンス時間、B4の場合は4インスタンス時間となります。 Residentの場合、一度起動すると、手動でシャットダウンさせるまでずっと常駐しますそのため、リクエストに対してすぐに応答することができます。 そのため、インスタンス時間をどんどん消費していきます。無料枠でB1の場合、初期化される日本時間16 00から、9インスタンス時間後の25 00の間しか稼動しません。その後、再び初期化される16 00までは、そのインスタンスを利用することができません。 Dynamicの場合、リクエストがあったときに起動され、しばらくして不要になれば除去されます。そのため、リクエストがあったときにインスタンスが起動されていなければ、起動に時間がかかってしまいます。 そのため、インスタンス時間の消費量は必要な分だけになります。 試してみる Backendsだろうが、実行するコードはServlet(或いは、Servletベースのフレームワーク)です。今回はSlim3のControllerでサンプルを作ってみます。 今回は、/testInstanceというパスで作ってみました。 package jp.fujiyan.test.controller; import org.slim3.controller.Controller; import org.slim3.controller.Navigation; import com.google.appengine.api.backends.BackendService; import com.google.appengine.api.backends.BackendServiceFactory; public class TestInstanceController extends Controller { private BackendService service = BackendServiceFactory.getBackendService(); @Override public Navigation run() throws Exception { System.out.println(service.getCurrentBackend()); return null; } } 今回は、Cronで実行させるのが目的で、レスポンスを返す必要が無いので、run()の戻り値は不要です。Slim3 Plug-inの、build.xmlのgen-controller-without-viewで作れば手っ取り早いです。 BackendService#getCurrentBackend()は、コードを実行しているBackendsのインスタンスの名前を返します。コードがFrontendで実行されている場合はnullを返します。 ブラウザから、/testInstanceでアクセスした場合、Frontendsで上記Controllerが実行されます。Logには、下記の様に出力されます。 Frontendsなので、nullが出力されています。 2012-01-01 01 23 45.678 [xxxxx/1.358322054626724163]. stdout null Cronを使って、Backendsで実行 Cronで、Backendsで実行させる場合は、 target で実行させるBackendsのインスタンス名を指定します。 ?xml version="1.0" encoding="UTF-8"? cronentries cron url /testInstance /url description Backends Instance Test /description schedule every day 18 00 /schedule timezone Asia/Tokyo /timezone target test-instance /target /cron /cronentries 上記の場合、日本時間18 00に、test-instanceで/testInstanceに対応するControllerが実行されます。Logには、下記の様に出力されます。 今度は、Backend Instanceの名前である、test-instanceが出力されています。 2012-01-01 18 00 07.752 [xxxxx/test-instance.358322297746672704]. stdout test-instance Backend Instance実行のCronからのTask Queue呼び出し Task Queue呼び出しの際のInstanceは、キューイング元のInstanceになるっぽいです。なので、targetを指定せずに、Backend Instance実行のCronからTask Queueを呼び出した場合は、同じBackend Instanceでタスクが実行されます。 明示的にBackend Instanceそ指定して、Task Queue呼び出し 例えば、通常のWebブラウザからのリクエスト(Frontend Instance)から、Backend InstanceでTask Queueを実行したい場合は、URLのホスト名で、Backend Instanceを指定します。 通常、リクエストの際のURLは、http //[アプリ名].appspot.com/~ですが、これをhttp //[Backend Instance名].[アプリ名].appspot.com/~とすれば、指定したBackend Instanceでリクエストを処理します。例えば、http //test-instance.appname.appspot.com/testInstanceとすれば、test-instanceで/testInstanceに対応するControllerが実行されます。 つまり、通常のリクエストにおける、http //[アプリ名].appspot.com/~の形式は、インスタンスを指定しない→Default(Frontend) Instanceということですね。 LocaleとTimeZone GAEのデフォルトでは、Localeはen_US、TimeZoneはUTCです。但し、ローカルの開発環境では、LocaleはOSの設定のようです。日本ならja_JP。でも、TimeZoneはUTCです。 Locale.setDafault()は、アクセス制御により使用が禁止されていますが、TimeZone.setDefault()は利用可能なようです。 ということで、TimeZoneはFilterでsetDefault()でJSTにしておいたほうが、何かとシアワセかもしれません。 URL Fetch APIでキャッシュされてしまう 参考 Disable URLFetchService cache - Google App Engine for Java | Google グループ 下記のように、Cache-ControlとPragmaを設定して、キャッシュを無効にしてしまう String url = …; URLConnection connection = new URL(url).openConnection(); connection.addRequestProperty("Cache-Control", "no-cache,max-age=0"); connection.addRequestProperty("Pragma", "no-cache"); BufferedInputStream in = new BufferedInputStream(openConnection().getInputStream()); try { … } finally { in.close(); } 認証 参考 北海道を愛するプログラマの覚書 認証については、Googleアカウントを利用する。 よって、基本的にアプリ側で認証を実装する必要は無い。但し、後述の3種類の権限よりも細かく制御したい場合には実装が必要。 アクセス権限については、次の3種類A)Googleアカウントへのログイン不要(全公開) B)Googleアカウントへのログイン必要(一般権限) C)Googleアカウントへのログイン必要(管理者権限) 上記A)については、特に設定は不要。 上記B)またはC)については、web.xmlの security-constraint に記述を行う。 B)またはC)でアクセス制限したいURLパターンを url-pattern に記述する。 B)に対して許可する場合は role-name * /role-name と記述する。 C)に対して許可する場合は role-name admin /role-name と記述する。Googleアカウントに対して管理者権限を与えるには、アプリの管理メニューで指定する。 下記は、URLが/member/で始まるコンテンツは、Googleアカウントにログインした人のみアクセス可能で、/admin/で始まるコンテンツは、Googleアカウントにログインした人の内、管理者権限を持っている人のみがアクセス可能となる。 security-constraint web-resource-collection url-pattern /member/* /url-pattern /web-resource-collection auth-constraint role-name * /role-name /auth-constraint /security-constraint security-constraint web-resource-collection url-pattern /admin/* /url-pattern /web-resource-collection auth-constraint role-name admin /role-name /auth-constraint /security-constraint OpenIDによる認証 参考 xfanの日記 hidemonの日記 OpenIDを使えば、Googleアカウント以外のOpenIDプロバイダを利用できます。 mixi Yahoo! はてな 等々 アプリケーションの設定 AdminConsoleにて、アプリケーションの作成時、作成後ならばApplication Settingsにて、 [Authentication Options]を"Federated Login"に設定しておきます。 /_ah/login_required 認証がされていない状態で、前述の security-constraint で保護されたURLにアクセスすると、 /_ah/login_requiredへリダイレクトされます。この動作はAppEngineで用意されているものなのですが、 肝心の/_ah/login_requiredのリクエストを処理するサーブレットは自前で用意する必要があります。 通常は、この/_ah/login_requiredのリクエストを処理するサーブレットで、OpenIDプロバイダの選択画面を表示します。 また、/_ah/login_requiredにリダイレクトされた際に、パラメータcontinueには、最初にリクエストされた、保護されたURLが格納されているので、 OpenIDプロバイダへのリクエスト時に、同様にパラメータcontinueにそのURLを設定することで、OpenIDプロバイダ側での認証完了後に、 continueに設定されたURLにリダイレクトしてくれます。 Slim3の場合 Slim3の場合は、/_ah/login_requiredにControllerを割り当てることができます。 [パッケージルート].controllerに、AddRouterクラスを作成します。 package jp.fujiyan.controller; import org.slim3.controller.router.RouterImpl; public class AppRouter extends RouterImpl { public AppRouter() { addRouting("/_ah/login_required", "/loginRequired"); } } AppRouter#addRouting()を使うことで、第1引数で指定したURLへのリクエストで、第2引数で指定したURLをハンドルするControllerが呼び出されるようになります。 上記の場合、/_ah/login_requiredへのリクエストで、/loginRequeredをハンドルする、jp.fujiyan.controller.LoginRequiredControllerが呼び出されます。 ローカルのDatastoreのデータを削除 参考プログラマ的京都生活 /war/WEB-INF/appengine-generated/local_db.binを削除して、同名のファイルを新規作成する。 削除直後のアクセスで"Failed to load from the backing store"というログとともにスタックとレースがでるけど気にしない ローカルテスト環境での管理コンソール http //localhost 8888/_ah/adminで、ローカルテスト環境の管理コンソールにアクセスできます。主に、Datastore Viewerで、ローカルのDatastoreが閲覧したい場合に。 つうか、つい最近までコイツの存在を知りませんでした…。 /work/は使わないほうがいい パス/work/を実現しようとして、/war/work/というディレクトリを作ると、Jettyがテンポラリファイルをそこに作成してしまい、何かと面倒くさいです。 ロギング まぁ、Log4Jは使えるけど、たとえばwarn()でログ出力しても、Administration Console上ではWarningとしては扱ってくれません。Info扱いですね。 ということで、管理面を考えると、Log4Jは使わずに、おとなしく標準ロギングAPIを使ったほうが良いのですかね。 なので、下記の記事は、参考までに… Log4Jを使うには 参考 I can't commons-loggingのjarファイルをwar/WEB-INF/libにコピー log4Jのjarファイルをwar/WEB-INF/libにコピー war/WEB-INF/appengine-web.xmlの system-properties にorg.apache.commons.logging.Logを追加する system-properties ... property name="org.apache.commons.logging.Log" value="org.apache.commons.logging.impl.Log4JLogger"/ ... /system-properties srcにlog4j.propertiesまたはlog4j.xmlを置き、内容を利用したい設定に変更する 新規プロジェクト作成時には、デフォルトでlog4j.propertiesが作成されるが、DataNucleusのログ設定しかないので、修正が必要 war/WEB-INF/logging.propertiesは不要なので削除してもよい。 削除の際には、war/WEB-INF/appengine-web.xmlの system-properties のjava.util.logging.config.fileも削除する JDOを使わない場合 参考 Song of Cloud プロジェクトのプロパティダイアログを開き(プロジェクトを選択して、右クリック→[Properties])、[Builders]の[Configure the builders for the project]で、[Enhancer]のチェックをOFFにするJDO向けのモデル拡張を行うプロセス。チェックしていると処理が実行されるので外しておく。 src/META-INF/jdoconfig.xmlを削除JDOの設定ファイル。不要なので削除する。 GAEでStruts2 GAEでStruts2
https://w.atwiki.jp/python/pages/14.html
なぜgoogle app engineなのか Google App Engineの機能と制限について
https://w.atwiki.jp/vsync/pages/22.html
Google App Engineスタートアップ 本家のサイトのスタートアップガイド http //code.google.com/intl/ja/appengine/docs/python/gettingstarted/ Google App Engine 用の Python アプリケーションの開発とアップロードには、 App Engine Python ソフトウェア開発キット(SDK)を使用しする。 SDKインストールに先立って Python 2.5 がインストールされている必要がある Google App Engineのインストールパッケージ↓ http //code.google.com/intl/ja/appengine/downloads.html Windows1.4.0 - 2010-12-02GoogleAppEngine-1.4.0.msi のウインドウズ版をインストールしてみた googleのチュートリアル通りSDK の次の 2 つのコマンドを使用してみる。 dev_appserver.py、開発用 Web サーバー appcfg.py、App Engine にアプリケーションをアップロードするツール