Веб-приложение Java останавливается при медленных запросах MySQL - PullRequest
4 голосов
/ 14 августа 2011

У меня есть веб-приложение, написанное с использованием Java-сервлетов.Я использую Tomcat 7 в качестве своего движка сервлетов, но ранее использовал Glassfish и имел ту же проблему.

На данной странице есть раздел «статистика», который обновляется каждые 5 минут.Для генерации статистики требуется около 30 секунд из-за размера используемых таблиц MySQL.

Когда я загружаю страницу, я показываю кэшированную статистику.После того, как все на странице было отрендерено, я очищаю, а затем закрываю поток вывода.Я тогда обновляю статистику.Таким образом, ни один пользователь не должен ждать ~ 30 секунд для загрузки страницы и обновления статистики после того, как страница уже полностью отправлена.

Проблема в том, что если я обновлю страницу во время выполнения запросастраница не загружается до тех пор, пока запрос не будет завершен, что означает, что, хотя у первоначального пользователя нет никакой задержки, после этого возникает длительная задержка.

Почему приложение эффективно останавливается?Разве Tomcat не может использовать другой рабочий поток для обработки запроса, даже если один поток все еще занят?

Спасибо.

1 Ответ

2 голосов
/ 14 августа 2011

Возможно, ваши данные «заблокированы для обновления» во время обновления - это зависит от того, как именно данные пересчитываются.

Хороший способ обойти это - сделать новый расчет в отдельной области данных, а затем переключиться на использование новых данных после того, как все готово. Один из способов реализовать это - использовать представление базы данных и номер версии, например:

create table my_statistics (
  id int not null primary key auto_increment,
  version int not null,
  -- other columns with your data
);

create table stats_version (current_version int); -- holds just one row

create view stats as
select * 
from stats_version v
join my_statistics s on s.version = v.current_version);

Поместите вашу новую статистику в таблицу с номером версии current_version + 1. После того, как все вычисления были сделаны. Затем простой update stats_version set current_version = current_version + 1 переключится на использование новых данных. Для выполнения этого последнего оператора требуется всего несколько миллисекунд, поэтому ожидания блокировки незначительны.

После переключения вы можете удалить старую статистику, чтобы сэкономить место.

Использование подхода «switch» делает обновление и «атомарное обновление» - обновление происходит «мгновенно и полностью», поэтому пользователи не видят частично измененный набор данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...