Я использую Spring MVC 3 + Tiles для webapp. У меня медленная работа, и я бы хотел, пожалуйста, подождите.Пожалуйста, подождите страницу Spring MVC + Apache Tiles
Есть два основных подхода к Пожалуйста, подождите страницы, о которых я знаю:
- долгоживущих запросов: визуализации и промыть «Пожалуйста, подождите» немного страницы, но не выполнить запрос пока действие не завершится, и в этот момент вы можете передать остальную часть ответа с помощью некоторого javascript для перенаправления или обновления страницы.
- Немедленно возвращайтесь и начинайте обработку на фоновом потоке. Клиент проверяет сервер (в javascript или через обновление страницы) и перенаправляет, когда заканчивается фоновый поток.
(1) приятно, поскольку он сохраняет действие полностью однопоточным, но не представляется возможным с помощью Tiles, поскольку каждый JSP должен полностью выполнить рендеринг до того, как страница будет собрана и возвращена клиенту.
Итак, я начал внедрять (2). В моей реализации первый запрос запускает операцию в фоновом потоке, используя аннотацию Spring @Async
, которая возвращает Future<Result>
. Затем он возвращает пользователю страницу «Подождите», которая обновляется каждые несколько секунд.
Когда страница ожидания подождите, обновляется, контроллер должен проверить ход фонового потока. Каков наилучший способ сделать это?
- Если я положил объект
Future
в сеанс напрямую, то потоки запроса опроса могут вытащить его и проверить ход потока. Однако не означает ли это, что мои сеансы не являются сериализуемыми, поэтому мое приложение не может быть развернуто с несколькими веб-серверами (без необходимости использования липких сеансов)? - Я мог бы поставить какой-то флаг состояния в сеанс, а фоновый поток обновить сеанс, когда он будет завершен. Я очень обеспокоен тем, что передача объекта HttpSession в поток без запроса приведет к отладке ошибок. Это разрешено? Может ли кто-нибудь ссылаться на любую документацию в любом случае? Он отлично работает, когда сеансы хранятся в памяти, конечно, но что делать, если сеансы хранятся в базе данных? Что делать, если у меня есть несколько веб-серверов?
- Я мог бы установить какой-то флаг состояния в моей базе данных, используя ключ сеанса или какой-либо другой аспект медленной операции. Кажется странным иметь данные сеанса в моей базе данных домена, а не в сеансе, но, по крайней мере, я знаю, что база данных является потокобезопасной.
- Есть ли еще один вариант, который я пропустил?
Могу ли я обобщить ваш ответ как (2) из первого списка и (3) из второго списка? У меня есть одна основная проблема с наличием данных с областью действия в базе данных: база данных не автоматически связана с сеансом, поэтому мне нужно будет добавить задание на очистку, чтобы периодически проверять базу данных на данные мертвой сессии и удалять ее. Как вы думаете (2) из второго списка жизнеспособны? У вас есть доказательства относительно того, безопасно или нет доступ к объектам сеанса из потоков без запроса? Это позволит избежать несоответствия области видимости. – Rich
Я бы придерживался 2-3, а не 2-2. Я бы не обновил сеанс. Я не думаю, что это возможно вообще. Скажем, сеанс 1 активен на сервере 1, и фон-поток на сервере 2 также хотел бы изменить сеанс. Это невозможно. – ChrLipp
Обычно архитектура выглядит так: выполнять действия в режиме онлайн, когда продолжительность составляет менее 3 минут. Если у вас есть длительное действие, сохраните запрос в базе данных и позвольте ему обработать пакетный планировщик. Планировщик может работать на дополнительном сервере. Нет необходимости хранить что-либо в сеансе. – ChrLipp