Google App Engine はマルチスレッドで動いているのか?

Programming Google App Engine の93ページ上のあたりに,App Engine の一つのインスタンス上で同時に複数のリクエストをそれぞれのスレッドで処理する「かもしれない (may) 」,だからちゃんとスレッドセーフに書く様に,という趣旨のことが書いてある.実際のところどうなのか,調べてみた.

テストプログラム

いたって簡単.static で乱数値を生成して保持しておく.これがインスタンスのIDの代わりになる.で,10秒休む.開始時刻と終了時刻とIDを出力する.

public class UpTest extends HttpServlet {
    static double val = Math.random();
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        long start = System.currentTimeMillis();
        try {
            Thread.sleep(10 * 1000);
        } catch (InterruptedException e) {
        }
        long end   = System.currentTimeMillis();
                
        resp.setContentType("text/plain");
        resp.getWriter().println(start + "\t" + end + "\t" + val);
    }
}

開発サーバ上でテスト.

これを,curlで複数同時に実行してやる.まずは開発サーバ.

1263135518486     1263135528486   0.18555702437909982
1263135518489     1263135528489   0.18555702437909982
1263135518490     1263135528492   0.18555702437909982
1263135518500     1263135528500   0.18555702437909982
1263135518509     1263135528509   0.18555702437909982

左から開始時刻,終了時刻,ID.当然同じインスタンスで,明らかに同時並行に動作している.

実サーバでテスト

それでは,ということで,App Engine の実環境にデプロイして試してみる.

同じように5つ同時に実行すると...

1つをのぞいて全部エラー!つまり,インスタンスが一つだけあがり,残りはインスタンスがあがるまでに落ちてしまったわけだ.何度か試しているうちに,インスタンスが複数立ち上がったようで,4つまでは答えが帰ってくるようになった.

1263135983868     1263135993870   0.7026211717179606
1263135983864     1263135993866   0.0889454177444502
1263135983865     1263135993867   0.1862037358470383
1263135983864	  1263135993870   0.4121154577213929

IDを見てわかるように,すべて別のインスタンスで処理されている,らしい.

所感

現在のところ,App Engineではマルチスレッドでリクエストを処理することはないようだ.スレッドセーフティを考えずに書いても,当面は安全っぽい.

ただし,今後もそうだとは限らない.Googleがスレッドセーフティについて何も言っていない(と思う)以上,いつマルチスレッドで実行されるようになっても文句は言えない.

また,開発サーバではガンガンマルチスレッドで実行されることは間違いない.ということは,やっぱりある程度はスレッドセーフティを意識して書いておいた方がいいような気がする.

ところで,4つしかインスタンスがあがってくれなかったのも気になる.たしか20あたりまでは増えてくれる,って話しじゃなかったか?負荷のかけ方が足りないか?