Jetty Continuations. Тестовое приложение.

Выпала мне как-то честь выполнять тестовое задание на одну уважаемую фирму. Отчет о моей работе приведен в этом топике.

Задание было примерно следующего содержания:

Разработать HTTP-сервер, предоставляющий информацию об изменениях котировок на фондовом рынке. Основным требованием является минимальная задержка доставки информации об обновлении котировок. То есть, интервал времени между изменением котировки и отображением этого изменения на веб-страницы должен быть минимальным насколько это возможно. Сервер должен принимать AJAX-запросы на обновление котировок из браузера (например, об обновлении котировок IBM или Microsoft) и посылать обновляющие сигналы только тогда, когда цена изменится. Важно помнить, что котировки обновляются со случайной периодичностью, поэтому не стоит надеяться на их синхронное обновление. Приложение должно быть способно поддерживать большое число long-polling подключений (~100), используя при этом не более 20 потоков. Это означает, что клиентские подключения замораживаются, пока запрошенные котировки не изменятся, но не более, чем на минуту. Другими словами, сервер должен реализовывать Comet (Revers-Ajax, Server push).

Надо сказать, с заданием в целом справился, посему решил поделится своими наработками. Не знаю, насколько эта информация актуальна сейчас, но все же для образовательных целей подойдет. (Важно отметить, что я использую Jetty 6 Continuations (http://docs.codehaus.org/display/JETTY/Continuations. В Jetty 7, вроде как, появятся альтернативные механизмы.)

В чем суть проблемы

Поскольку система рассчитана на обслуживание одновременно большого числа пользователей, возникает одна важная проблема, а именно: число пользователей может сильно превысить доступное число разрешенных подключений к серверу. AJAX-запросы посылаются браузером даже в те моменты, когда мы ничего не делаем — например смотрим открытую веб-страничку — и каждый запрос все равно для своей обработки требует отдельного подключения к веб-серверу. Поэтому, фактически, даже 100 пользователям необходимо постоянно 100 подключений для обработки их AJAX-запросов. Или больше.

А, как мы знаем, стандартная модель обработки подключений предполагает выделение одного потока на одно подключение. Значит, если у вас 100 подключений, то у вас 100 потоков. Но вряд ли ваш сайт рассчитан на 100 пользователей, так ведь 🙂 Здесь приведена любопытная табличка, показывающая сколько потоков потребуется, чтобы ваши клиенты остались довольны. В зависимости от используемых технологий это число очень разнится. И естественно, побеждает кто бы вы думали?

Jetty Continuations

Jetty Continuations — это такое новое API, предоставляемое веб-серверами Jetty (начиная с 6 версии). Оно позволяет использовать так называемый «Continuations»-объект для сохранения обрабатываемого запроса (если ответ, допустим, еще не готов; в нашем случае — котировки не изменились) и освобождения потока.

На языке кода это выглядит примерно так:

    RetryContinuation continuation = (RetryContinuation)         ContinuationSupport.getContinuation(request, continuations);
    continuation.suspend(60 * 1000);

* This source code was highlighted with Source Code Highlighter.

Первой строчкой мы формируем «Continuations»-объект, а второй — говорим серверу приостановить обработку запроса до появления новых данных, но не более чем на 60 секунд. Автоматически после вызова этой команды поток будет освобожден и может быть снова использован для обработки других запросов.

Когда же данные у нас обновятся, мы можем просто вызвать у сохраненного «Continuations»-объекта метод resume(), чтобы вновь инициировать обработку запроса.

Как это работает

Когда мы вызываем метод suspend(timeout), то бросается RetryRequest (runtime exception). Это исключение обрабатывается особым образом самим Jetty: Jetty помещает запрос в timeout-очередь и возвращает поток в пул потоков. Когда вызывается resume() или timeout истекает, запрос повторяется.

Выполненное тестовое задание с очень подробным readme можно скачать тут. Кому интересно с легкостью разберутся — у меня очень юзер-френдли 🙂

Реклама

Jetty Continuations. Тестовое приложение.: Один комментарий

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s