Я думаю, что нашел больше ошибок в моем веб-приложении. Обычно я не беспокоюсь о проблемах параллелизма, но когда вы получаете исключение ConcurrentModificationException, вы начинаете переосмысливать свой дизайн.
Я использую JBoss Seam в сочетании с Hibernate и EHCache на Jetty. Сейчас это один сервер приложений с несколькими ядрами.
Я кратко просмотрел свой код и нашел несколько мест, в которых еще не было исключений, но я уверен, что они могут.
Первый фильтр сервлетов, который у меня есть, в основном проверяет, есть ли сообщения, чтобы уведомить пользователя о событии, которое произошло в фоновом режиме (из задания или другого пользователя). Фильтр просто добавляет сообщения на страницу в модальном всплывающем окне. Сообщения хранятся в контексте сеанса, поэтому возможно, что другой запрос может извлечь те же сообщения из контекста сеанса.
Сейчас это работает нормально, но я не захожу на страницу с множеством одновременных запросов. Я думаю, что мне может понадобиться написать несколько тестов JMeter, чтобы этого не произошло.
Второй фильтр сервлетов регистрирует все входящие запросы вместе с сеансом. Это позволяет мне знать, откуда приходит клиент, какой браузер у него запущен и т. Д. Проблема, с которой я сталкиваюсь в последнее время, связана со страницами галереи изображений (где одновременно происходит много запросов), и в итоге я получаю исключение одновременной модификации, потому что я добавляю запрос к сеансу.
Сеанс содержит список запросов, по-видимому, этот список обрабатывается несколькими потоками.
@Entity
public class HttpSession
{
protected List<HttpRequest> httpRequests;
@Fetch(FetchMode.SUBSELECT)
@OneToMany(mappedBy = "httpSession")
public List<HttpRequest> getHttpRequests()
{return(httpRequests);}
...
}
@Entity
public class HttpRequest
{
protected HttpSession httpSession;
@ManyToOne(optional = false)
@JoinColumn(nullable = false)
public HttpSession getHttpSession()
{return(httpSession);}
...
}
В этом втором фильтре сервлетов я делаю что-то вроде:
httpSession.getHttpRequests().add(httpRequest);
session.saveOrUpdate(httpSession);
Часть, которая выдает ошибку, - это когда я делаю некоторое сравнение, чтобы увидеть, что изменилось от запроса к запросу:
for(HttpRequest httpRequest:httpSession.getHttpRequests())
Эта строка взорвана с исключением одновременной модификации.
Вещи, чтобы уйти с:
1. Будут ли здесь полезны тесты JMeter?
2. Какие книги вы рекомендуете для написания веб-приложений, которые масштабируются при одновременной загрузке?
3. Я попытался поместить синхронизированный туда, где, как мне кажется, он мне нужен, то есть в методе, который перебирает запросы, но все равно не получается. Что еще мне нужно сделать?
Я добавил несколько комментариев:
Я думал о том, чтобы сделать запись http-запросов фоновой задачей. Я могу легко вызвать фоновое задание, чтобы сохранить эту информацию. Я пытаюсь вспомнить, почему я не оценил это слишком сильно. Я думаю, что есть некоторая информация, к которой я хотел бы получить доступ на месте.
Если бы я сделал это асинхронным, это немного увеличило бы пропускную способность - ну, мне пришлось бы использовать JMeter для измерения этих различий.
Мне все равно придется решать проблему параллелизма.
Спасибо
Walter