HTTP Session Timeout
最近というか、ここ数年はWebサービスがIT業界のトレンドとなっている。
Webサービスといえば、真っ先に思いつくのがJSP、Servletであろう。
(いや、まぁ、PHPとかPerlもあるけどね)
今回はこのJSPやServletでmustなClass(正確にはHttpSessionはInterfaceですが…)である
SessionObjectについて、
見落とされがちなTimeOutの豆知識です。
・TimeOutのチェック
HttpSessionにはTimeOutを設定できる。一定時間アクセスがなかった場合、タイムアウトにして、そのオブジェクトを
無効にする。(すぐには削除されないかもしれない。この実装はWEBコ
ンテナに依存します。)
ログインしたまんまでPCをほったらかしにしても、ずっとセッションが生きていればセッションハイジャックの危険性が
増すため、セキュアなWEBサービスであれば、この時間はずっと短く設定される。(たとえば銀行など)
このTimeOutのチェック間隔をcheckFrequencyとかで設定する。このトラッキングの仕組みもコンテナに依存するので
使用しているサーバーのドキュメント類にてチェックしてくださいな。
(少なくとも、Jservや、WebSphereはこの方式)
(2008/8/7 追記 Websphere v6 ではこの値はHttpSessionReaperPollInterval というカスタムプロパティ)
ということはTimeoutは次の式で表せることになる。
SessionTimeout =
session.getmaxInactiveInterval() + Δt
(ただし0 < Δt < Timeoutのチェック間隔)
図で表すとこうなる。
アプリケーション上で、HttpRequest.getSession()などと、取得した時には、その任意のタイミングでisInvalidate()
が行わ
れ、
チェックされるように実装されていると思われるので、通常はこのΔtの差を意識する必要は無い。
で、結局何が言いたいのかというと、ここからが本題。普段はあんまり意識する必要はございませんが、
Timeout
のチェック開始は最終アクセス時間(session.getLastAccessedTime())で起算されるので、
ServletやJSPの処理が、ヘッポコで、
(1)セッションからなにかを取り出す。
(2)やたら長い処理とかループ処理とか、
(3)セッションからなにかを取り出す。
のようになっていると、処理中にもかかわらずタイムアウトしちゃうよというお話。
よく、HTTPトランザクションの最終アクセスと間違われるから、気をつけましょう。
たとえば、このようなJSPを動かしてみるとよくわかるでしょう。
<%@ page language="java"%>
<%@ page import="java.util.*"%>
Now<%=System.currentTimeMillis()%>
session.getId()<%=session.getId()%>
session.getLastAccessedTime()<%=session.getLastAccessedTime()%>
session.getMaxInactiveInterval()<%=session.getMaxInactiveInterval()%>
<%out.flush();%>
<%
int setTime = Integer.parseInt(request.getParameter("setTime"));
int waitTime = Integer.parseInt(request.getParameter("waitTime"));
if(setTime > 0) session.setMaxInactiveInterval(setTime);
try{
if(waitTime > 0)
Thread.sleep(waitTime*1000);
}catch(Exception e){}
%>
Now<%=System.currentTimeMillis()%>
session.getId()<%=session.getId()%>
session.getLastAccessedTime()<%=session.getLastAccessedTime()%>
session.getMaxInactiveInterval()<%=session.getMaxInactiveInterval()%>
setTime=30、waitTime=330でアクセスしてみた結果。
そのときのログ。
IlleagalStateExceptionで、「オブジェクトの状態がおかしいときにメソッドを呼び出した」=タイムアウトと相成る。
普通のサーバーで、普通なプログラムであれば、まず、こういったケースには遭遇しないでしょう。
銀行などの厳しいタイムアウト等でも数分、普通のWEBアプリケーションでは30分程度がSessionTimeOutであるからです。
オンラインの処理でこれ以上の時間を費やすような処理は、もはやWEBサービスとは言えないからです。
また、このエラー画面がユーザーに告知されるようなケースも、システムとして問題があります。
その前のサービスであるApacheや、IBM HTTP Serverのタイムアウトがこれらよりも長いことはまず無いからです。
つまり、各タイムアウトの関係は、環境やシステムの目的にもよりますが、通常であれば、
SessionTimeOut >
ブラウザのタイムアウト > WebServerのタイムアウト
の大小関係があるからです。
このようなエラーがユーザー画面に返っていることは、すなわち2つの問題を抱えていることになります。
・アプリケーションが遅すぎる問題
・不適切なタイムアウト設定
ブラウザのBACKでお戻り下さい