DynamoDB で Tomcat のセッション管理を行う の動作確認を行いましたが、一点不具合が見つかったので対処方法をメモしておきます。
まず、DynamoDBSessionManager の仕組みとしましては、簡単に説明すると PersistentManager の永続保存先が DynamoDB になっているという実装になっています。
つまり、実際のセッション管理を DynamoDB で行うのではなく、
メモリ不足を想定したスワップ先、およびフェイルオーバー時にセッション復帰するためのバックアップ先として DynamoDB が利用されます。
タイムアウト処理の際に Tomcat 内のセッションと DynamoDB 内のセッションを削除しますが、クラスタリング環境の場合、明示的にタイムアウト処理が呼ばれるとは限らないため、DynamoDB 内に期限切れのデータが残ることがあります。
DynamoDBSessionManager では ExpiredSessionReaper というスレッドで定期的にDynamoDB 内のデータの掃除を行います。
ただし、この ExpiredSessionReaper、配布されているリリースバージョン 1.0.0/1.0.1 では正常に動作しないようです。
private boolean isExpired(long sessionDateInMillis) { return sessionDateInMillis > (System.currentTimeMillis() + expirationTimeInMillis); }
この期限切れ判定が間違っているようです。/trunk では以下のように修正されています。
private boolean isExpired(long sessionDateInMillis) { return sessionDateInMillis < (System.currentTimeMillis() - expirationTimeInMillis);
これで判定については正しい挙動になるのですが、もう一点問題がありました。
ここの expirationTimeInMillis は maxInactiveInterval の値が利用されるのですが、 expirationTimeInMillis はミリ秒に対し maxInactiveInterval は秒の単位のため、 Tomcat に設定されているタイムアウト時間と食い違ってしまいます。
こちらについては DynamoDBSessionManager を以下のように修正することにより対処できます。
expiredSessionReaper = new ExpiredSessionReaper(dynamo, tableName, this.maxInactiveInterval); ↓ expiredSessionReaper = new ExpiredSessionReaper(dynamo, tableName, this.maxInactiveInterval * 1000);