Quantcast
Channel: ウィリアムのいたずらの、まちあるき、たべあるき
Viewing all articles
Browse latest Browse all 7271

ビッグデータにおけるセッションの先勝ち・後勝ち処理の問題と、解決策

$
0
0
■お題

セッションを使うWebシステムにおいて、

  同一ログイン名の人が、ログインしたらどうするか?

という問題があり、

たぶん、一般的な解答は、

  「複数回ログインは、可能だが、ある一定回数がきたら、
    「これ以上、ログインできません」
   というエラーメッセージを出してログインさせない」

という回答がふつうではないだろうか。
(一定回数=ライセンス数)


■先勝ち方式

この場合、
・同一セッションが既に存在する場合(=一つのブラウザからタブで2回ログインしてる)
   同一セッションでは、複数ログインさせないのであれば、
      2回目のとき、上記エラーメッセージを出して、ログインさせない
    又は
      現在ログイン中の同じ画面がでる(gooはこちら)

   複数ログインさせる場合
      別のセッションID等を降って別セッション(相当)でログイン、
      何人ログインしたかは、下記「・・・複数ログイン」の方法に従う
    →別のセッションにしなければならないわけでなく、領域が分かれていれば、
     同一セッション内でも、別のURL先でもよい。そういう意味で
     別セッション「相当」と、「相当」の字をつけている
 →これを考慮しないで、単にセッションとってきて、ログイン情報を書き込んでしまうと、
  前にログインしている人の処理が消えてしまう。
 →この場合、Cookieで管理すると、後の人のセッションID相当が入る可能性があるので、
  それなりの注意(切り分け処理)が必要

・同一セッションではないとき、複数ログイン
   どこかでユーザーログイン人数を管理。
   ログイン要求が来たら、毎回新しいセッションID相当を発行し、セッションを作成
   この場合、セッション終了(タイムアウトとユーザー手動の両方)の場合、

javax.servlet.http.HttpSessionBindingListenerインターフェイス
http://ash.jp/java/webapp_session.htm
(のセッションの開始・終了時の処理)

   で、ユーザーログイン数を引く処理する

これは、先に入った人が必ず入れる方式なので、「先勝ち方式」と呼ぶことにする



■先勝ち方式の問題点

この方法は、たとえば、ライセンス数2のとき
・1個目のブラウザでAという処理をかけた→処理中になって、操作できない
・2個目のブラウザでBという処理をかけた→処理中になって、操作できない
Cという処理を本当はしたいんだけど・・・
2つとも処理中なので、ログインできず、処理Cを投入できない

という状態になってしまう。

特にライセンス数2でなく、ライセンス1の場合、

ある処理をやったら、処理中になっちゃって、何も操作できない・・・
処理をとめることさえ出来ない(Xボタンが利かない)

っていうのは、問題なのだ



■後勝ち方式の誕生

この問題を回避するため、

・ログイン数が一定数を超えたら、古いものから順に、セッション強制開放し、
 新しい人のログインを優先させる

という手法が出てきた。ここでは後勝ち手法と呼ぶ。

このとき、強制開放された処理は、セッションが開放されているので、戻ってきたときに
異常終了する

一見、この方法で、うまくいくように思う・・・



■後勝ち方式の問題点

しかし、実は問題があるケースがある。
この「セッションを強制開放させられる」先の処理が、
ビッグデータ検索等を行っていて、すぐに帰ってこない場合。
(→だから処理中になっていて、だから、後からログインしたいわけだ)


先の処理をキャンセルしなければ、あとの処理は投入しても、
とってもおそい(たぶん、先の処理が終わってから投入したほうが早い。
だけど、先の処理の終わりを待てないから、今投入したんだ!)

このとき、1つ1つのサーブレットのインスタンスから直接、処理を
呼び出しているのなら、The Endだが、普通こういうときは、
キューにいれている。したがって、キューをキャンセルしなければならない。

このことを意識して、コーディングしている場合は問題ないが、
意識していないと、

・先の強制開放する処理のセッションを開放する
   →開放されたセッションは、 HttpSessionBindingListener のvalueUnbound で
    キューをキャンセルに行く

・後のログインに対するセッションを確保して、かえる

とプログラムを書いてしまう。
こう書くと、キューをキャンセルにいって、失敗したとき(あるいはなかなかキャンセル
出来なかったとき)、結局、あとでログインした人は、投入した処理は、待たされる。



■対策

制限人数(ライセンス数)を超えてログインしたら

「制限人数を超えています。先にログインした人を消しますか?」

ときいて、Noがクリックされたら、そこで終了(ログインできない)
YESがクリックされたら、
・消す人のビッグデータ検索等の処理がキュー入っていたら、それを中止する
・後処理して、セッション開放する
・これが成功したのを確認して、新しいログインに対して、セッションを発行する
  →この間に失敗したり、CANCELされたら、新しいセッションが発行されず
   「ふるい人のセッションも異常終了する(のを仕様とする)」
・古い人は、サーバーアクセスしたときに、異常終了通知を受け取る

とすればよい。

(後がち、先勝ちは、YES,NOのクリックでユーザーが選べる)

Viewing all articles
Browse latest Browse all 7271

Trending Articles