Я думаю, что даже EHCache убивает муху напалмовой бомбой. Проблема проста, как и реализация.
Я предлагаю использовать фильтр сервлетов на верхнем уровне, чтобы сделать как можно меньше обработки.
Создайте класс для хранения следующего:
- Количество попыток (кол-во)
- Время
Теперь, простой код в синхронизированном блоке:
if userid not in attemptMap:
attemptMap.add ( userid, new attemptItem ( userid, 1, now ) )
else
tmp = attemptMap.get ( userid )
if (acquire lock for tmp) :
if tmp.time + 30 > now :
tmp.count = 0
tmp.time = now
tmp.count++
if tmp.count > 3 :
error=true
release lock for tmp
else : error=true
Вот и все (пока код синхронизирован).