В моей предыдущей статье о создании Reactive API с использованием Vert.x и RxJava мы увидели, как обрабатывать HTTP-запросы асинхронно, используя рабочую очередь, и фиктивный Async API, который асинхронно возвращает результаты.

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

SockJS

Vert.x предоставляет способ установить канал связи с клиентом в реальном времени, публиковать и получать сообщения на хорошо известные темы. Мы будем использовать обработчик SockJS в нашем API, чтобы периодически публиковать внутренние метрики, чтобы помочь визуализировать, как события обрабатываются в API.

Мост автобуса событий

Vert.x предлагает различные мосты для расширения шины событий за пределы JVM. Vert.x SockJS Service Proxy создает клиентов служб, которые можно использовать из браузера или из приложения node.js. Эти клиенты полагаются на мост SockJS, который передает события из шины событий vert.x в / из SockJS. Он позволяет вам предоставлять службу на шине событий, так что любой другой компонент vert.x может использовать ее, как только они узнают адрес, на котором опубликована служба. . В нашем случае мы будем получать сообщения от службы метрик.

Обработчик SockJS

Добавить обработчик SockJS в статью API очень просто. Мы определяем хорошо известные темы и соединяем их между шиной событий и SockJS-соединением.

// set in and outbound permitted addresses
// Allow events for the designated addresses in/out of the event bus bridge
BridgeOptions opts = new BridgeOptions()
 .addInboundPermitted(new PermittedOptions().setAddress(“to.server”))
 .addOutboundPermitted(new PermittedOptions().setAddress(“to.client”));

Зарегистрируйтесь, чтобы прослушивать сообщения, поступающие на сервер.

vertx.eventBus().consumer(“to.server”).handler(message -> {
 // Process incoming message
 });

Давайте определим простой таймер, который своевременно публикует метрики:

Observable.interval(1, TimeUnit.SECONDS).subscribe(delay -> {
 measure();
}, 
error -> {}, 
() -> {});
private void measure() {       m_metrics.setWorkerQueueSize(((ThreadPoolExecutor)m_worker_executor).getQueue().size());
  m_metrics.setAsyncRequests(m_api.getAsyncRequests());
  m_metrics.setAverageLatency(m_latency.get() /  m_metrics.getCompletedCount());
  vertx.eventBus().publish(“to.client”, m_metrics.toString());
}

Использование шины событий из браузера

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

<script src=”https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src=”https://cdn.jsdelivr.net/sockjs/0.3.4/sockjs.min.js"></script>
<script src=”vertx-eventbus.js”></script>

Откройте соединение с шиной событий и подпишитесь на адрес:

<script>
 var eb = new EventBus(“/eventbus/”);
 eb.onopen = function () {
  eb.registerHandler(“to.client”, function (err, msg) {
  obj = JSON.parse(msg.body);
  $(‘#outstanding-value’).text(obj.pending);
  $(‘#completed-value’).text(obj.completed);
  $(‘#queue-value’).text(obj.queue);
  $(‘#async-value’).text(obj.async);
  $(‘#latency-value’).text(obj.avg_lat);
 });
 };
</script>

Простая html-страница, отображающая эти показатели:

Используя показатели в реальном времени, можно легко визуализировать, как API может обрабатывать запросы и отвечать на них асинхронно.