勉強日記

チラ裏

PoEAA Ch6 Session State

martinfowler.com


Session State

  • 同時処理
  • トランザクションにも2種類ある(ch5)
  • stateless/stateful sessionに関する議論の根底には、これらのの差異がある
  • 主要な課題
    • 本質的にステートフルなセッションが存在すると認識する
    • ステートをどう扱うか決める

The Value of Statelessness

  • Stateless server objectとは
    • 真の意味
      • メンバを持たないオブジェクト
      • めったにない
    • 人々が意図するところ
      • メンバを持つ
        • 処理を開始するまでundefined
        • リクエストの間変化しない(immutable)
  • Stateless Server Objectの例
    • 書籍情報を返すWebページ
      • URLアクセスでASPとか処理開始
        • クエリパラメータかなにかでISBNを渡す
      • HTTPレスポンスに書籍情報載せて返す
      • 中間オブジェクト
        • ISBN
        • 本のタイトル
        • 価格
        • 補足レビュー
      • レスポンスを返した時点でこのオブジェクトは不要になる
      • 新しいリクエストが来たらまた0から処理開始
  • Stateful Server Objectの例
    • あるIPアドレスからのアクセスについて、ISBNを記録する
    • リクエストをまたいで保存
  • 大いなる違いがある
  • Statefulであることは悲惨の極み
  • なぜ
    • リソース食う
      • アクセスしていないユーザーの情報も保持しなければならない
    • 逆に、Statelessでさえあれば、リソースプールを作って使いまわすことができる
      • 【補】DBコネクションプールとか
    • アクセスしていないしていないユーザーが多いほどStatelessの価値は高まる
  • では全部Statelessにすべきか?
  • できるならそうしたいのはやまやま
  • できない
    • ショッピングカートとか
  • ステートフルなビジネストランザクションはどうしてもつきまとう

Session State

  • Session State
  • cf. Record Data
    • DBに永続化するやつ
    • すべてのセッションから見える
    • Session StateをRecord Dataにするには、ビジネストランザクションをコミットする必要がある
  • Session Stateにまつわる最大の課題点はIsolation(独立性)
    • 複数ユーザのセッションが重なったときのデータ一貫性をどうするか
      • ch5にて
  • Session Stateじゃないヤツ
    • パフォーマンス目的のキャッシュ
    • なくても振る舞い(機能)が変わらないものはSession Stateではない

Way to Store Session State

  • セッションが必要不可欠なことはわかった
  • どう実装するの
  • 3種類ある
    • Client Session State
      • クライアントサイドで状態を保持する
    • Server Session State
      • サーバサイドで状態を保持する
    • Database Session State
      • DBに状態を保持する
      • 広義的にはServerSide
Client Server Database
保存場所 Cookie文字列, クエリ文字列等 オンメモリ、ファイル等 テーブル
帯域 x リクエストのたびに全ステート送受信 o o
セキュリティ x 要対策(改ざん防止) o o
独立性 o o x 頑張って実装する必要あり
Session Migration o x クラスタリングのバランシング o
データ加工の手間 x (デ)シリアライズ o x オブジェクト組み立て等
開発の手間 x (デ)シリアライズ、セキュリティ o x 独立性
向いている用途 B2C(クライアントがセッション放棄して離脱すること多い) リースシステム(ステート変化激しい) 小売システム(殆どのユーザがidling)
  • Session Migration
    • サーバーをクラスタリングした構成にて
    • あるセッション中の複数リクエストを複数サーバーに振り分ける
    • ロードバランシング的には望ましい
    • が、Server Session State型だとうまくいかない
      • その特定のサーバマシンがステートを持ってしまっている
  • Session Affinity
    • あるセッション中の複数リクエストは全部単一サーバで処理する
    • 「あるセッション中」を判定できるとは限らない
    • のでIPアドレスで「同じクライアント」を判定すること多し
    • しかしこれを行うと、Proxyを挟んだときに多くのユーザーが同一IPになってしまう
      • 多くのユーザのリクエストが単一のサーバに集中
      • ロードバランシング台無し
  • セッションが切れるケース
  • クライアント側
    • クライアントが落ちる
    • クライアントが離脱して返ってこない
      • B-Cでよくある
    • Client Session State
      • 放置でOK
      • ステートを持っているのはクライアントだから
    • Server Session State / Database Session State
      • 宙ぶらりんのSession Stateが残ってしまう
      • セッションが放棄されたことを検知してクリーンアップしないといけない
  • サーバ側
    • サーバ停止する
    • Database Session State
      • セッション情報に関して心配いらない
    • Server Session State
      • 不揮発性の記憶装置にバックアップするなどが必要
  • 著者の好み
    • Server Session State
      • リモート(のファイルサーバー等)にステートを保存できるなら
    • Client Session State
      • セッションIDと小さなデータなら
    • Database Session State
      • フェールオーバー・クラスタリングが必要で
      • かつリモートにステートを保存できない事情があり
        • = Server Session Stateでは用を足せず
      • かつセッション間の独立性の担保に問題がないなら