Вопрос: Какой лучший способ вызвать веб-службу (0,5-1,5 секунды / звонок) из сервлета в AppEngine? Являются ли блокирующие вызовы масштабируемыми в среде AppEngine?
Контекст: я разрабатываю веб-приложение с использованием AppEngine и J2EE. Приложения вызывают веб-сервис Amazon, чтобы получить некоторую информацию для пользователя. Исходя из моего опыта работы с asp.net, лучший способ сделать вызовы - это использовать асинхронный http-обработчик, чтобы предотвратить голодание в пуле потоков IIS. Эта функция недоступна для J2EE со спецификацией Servlet 2.5 (планируется 3.0 ).
Сейчас я думаю о том, чтобы сделать мои контроллеры (и сервлеты) потокобезопасными и запросить объем. Есть ли что-нибудь еще, что я могу сделать? Это даже проблема в среде J2EE + AppEngine?
РЕДАКТИРОВАТЬ: я знаю о поддержке асинхронных вызовов AppEngine и JAX-WS, но я не уверен, как она работает со средой сервлетов. Насколько я понимаю, чтобы завершить запрос сервлета, код все еще должен ждать завершения асинхронного вызова WS (обратного вызова или чего-то еще).
Я предполагаю, что выполнение этого с использованием примитивов синхронизации заблокирует текущий рабочий поток.
Таким образом, поскольку поток заблокирован, для обслуживания другого контейнера сервлета запроса пользователя необходимо выделить новый поток в пуле потоков, выделить новую память для стека и тратить время на переключение контекста. Более того, запросы могут блокировать весь сервер, когда у нас заканчиваются потоки в пуле потоков. Эти предположения основаны на модели потоков ASP.Net и IIS. Применимы ли они к среде J2EE?
ОТВЕТ: После изучения документации Apache и GAE кажется, что голодание потоков в пуле потоков не является реальной проблемой. Apache по умолчанию имеет 200 потоков для пула потоков (по сравнению с 25 в asp.NET и IIS). Исходя из этого, я могу сделать вывод, что потоки в JVM довольно дешевы.
В случае, если действительно требуется асинхронная обработка, или в контейнере сервлета закончились потоки, можно изменить дизайн приложения для отправки ответа через API канала Google.
Рабочий процесс будет выглядеть так:
- Сделать запрос на синхронизацию сервлету
- Сервлет создает создает канал для асинхронного ответа и ставит в очередь задачу для фон работник
- Сервлет возвращает ответ клиенту
- [Обслуживание других запросов]
- Фоновый рабочий выполняет обработку и передает данные клиенту через канал API