Play Framework 2.3 For Java ことはじめ #12 sessionとcache編
Play Framework 2.3 For Java 入門記事一覧
第12回はPlay frameworkのsession
とCache
ついて説明します。
Javaアプリケーションの世界で俗に言われているsession
とPlay frameworkのsession
は微妙に違います。という辺りから説明してみようと思います。
そもそもHTTPのsessionって何
ざっくり言うと、サーバー側で接続してくるユーザーを覚えておく仕組み。サーバーがセッションIDを発行してユーザーに関する情報をサーバー側に保存しておくことができます。
http session
とかでググるとたくさんでてきます。このあたりが簡潔で分かりやすいです。
Play frameworkのsessionの使い方
Play frameworkでは、session
という仕組みがあって、そのオブジェクトを経由すれば簡単にセッションに値を保存したり取得したりすることができます。使い方は、簡単でJavaSessionFlashに書いてある通り、controllerの処理の中で、こんな風に使います。
// sessionに値をセット session("connected", "user@gmail.com"); // sessionにセットした値を取得 String user = session("connected"); // sessionの値をクリア session().remove("connected");
好きなキー名を指定して、文字列を保存することができます。
ただ、sessionって書いてあるから、一見サーバー側に保存されてるように思うかもしれませんが、実は、Play frameworkではcookie
、つまり、サーバー側ではなくブラウザ側にデータが保存されています。
実際にsession
に値をコントローラーでセットしたあとのページを、ChromeのDeveloper ToolsでCookiesのところを見てみればどうなってるか分かるでしょう。
ここが一般的なJavaのアプリケーションとは微妙に違うところです。
Play Frameworkのsessionのメリットとデメリット
ここで、なぜPlay Frameworkではサーバー側にデータを保存しないのか?という疑問がわきますが、これにはこれでメリットがあります。
例として、サーバーの負荷を分散するために、サーバーを複数台用意してそれぞれに処理を振り分けるということをしようと考えたとしましょう。このときに、セッションをサーバー側に値を保存するという方法では、ある問題が発生します。
分散させたサーバーA、Bが稼働していたとして、次のケースでサーバーはユーザーを認識できなくなります。
- ユーザーは、サーバーAに接続してきてサーバーAはユーザーのセッションデータを保存
- 次にユーザーがサーバーBに接続
- セッションデータはサーバーAにあるため、サーバーBはユーザーを識別することができない
このように、処理を行うサーバーを複数台用意したときに、ユーザーは常に同じサーバーに接続しなければならないという保証が必要になります。でも、Play Frameworkのsessionは、ブラウザ側にデータを保存しているので、どのサーバーに接続してもOKということになり、何も気にすることなくサーバーを増やすことができます。
こちらの方の記事ステートレスなPlay2でログイン状態を管理する - C Sharpens you upの銀行のたとえが分かりやすいです!
一方で、このcookie
に保存するということにも、デメリットはあって、cookieにはサイズ制限があるので、4KBぐらいの文字列しか保存できません。
最新ブラウザのクッキーの制限(数,サイズ)を調べてみた - ITコンサルタント成長録
あとは、ブラウザ側にデータが保存されているので、一度発行してしまったものを自分のアプリケーションに接続させることなく強制的に削除したいと思っても、その仕組みは作ることができません。
Play FrameworkのCache
その辺りの、メリットデメリットをふまえた上で、Play Frameworkには、Cache
という仕組みがあります。これは、サーバー側で値を保持する仕組みなので、一般的なJavaのアプリケーションのセッションに近いものがあります。
Playの公式ページJavaCacheに使用方法は書いてあります。
値の操作方法はこんな感じでほぼsession
と似たようなものですが、文字列以外も保存できたり、有効期限を設定できたりします。
// キャッシュをセット(文字列じゃないオブジェクトをセットできる) Cache.set("item.key", frontPageNews); // 15分間だけ有効期限をつけてキャッシュをセット Cache.set("item.key", frontPageNews, 60 * 15); // キャッシュを取得 News news = (News) Cache.get("item.key"); // キャッシュを削除 Cache.remove("item.key");
Cacheを使うということは、サーバー側に保存することになるので、サーバーをたくさん増やすことができなくなってしまうじゃないかと思うかもしれません。
ですが、そこはちゃんとPlay Frameworkでは考えてあって、Cacheに保存したデータを別のサーバーで管理できる仕組みが用意されています。なので、Playが動いているアプリケーションサーバー自体を増やしても、各サーバーはCacheが保存されているサーバーを見に行けばいいので、問題を解決しています。
まとめ
すごい雑ですが、Play Frameworkのsession
とCache
についてまとめました。
session
とCache
の違いを理解しながら、保存するデータの性質を見極めてどっちを使うかを決めて欲しいです。
Play Frameworkは、他のフレームワークと違ってステートレスで、スケーラブルなと言われていた理由が少し分かった気がしました。