Автоматизация, Программирование

Асинхронное программирование с использованием фреймворка «Vert.x»Часть 1

Время прочтения: 5 мин.

Vert.x — событийно-ориентированный фреймворк, работающий на JVM, который отличается высокой производительностью, простой асинхронностью и конфигурированием. Проект Vert.x был запущен в 2011 году и изначально назывался «Node.x», позже был переименован в «Vert.x». Vert.x имеет схожую структуру с Node.js, разворачивающую сервер внутри виртуальной машины Java, использующую JVM возможности для регулирования движения в облегченных процессах однопоточного сервера вместо тяжеловесных контейнеров. Фреймворк относится к проектам с открытым исходным кодом.

Код Vert.х-приложения состоит из определения обработчиков событий, выполняющих такие функции, как управление http-запросами и передача сообщений через шину событий. В отличие от традиционных событийно-ориентированных приложений Vert.х приложение за счет асинхронности гарантированно не блокируется.

Особенности фреймворка

  1. Основной единицей развертывания в Vert.х является Verticle.
  2. Verticle выполняются внутри экземпляра Vert.х. Каждый экземпляр Vert.х запускается в собственном объекте JVM и может размещать в себе несколько Verticle, выполняющихся каждый в своем загрузчике классов. Хост может запустить один Vert.х-экземпляр или несколько (рисунок 1).
Рисунок 1. Архитектура системы Vert.x

3. В экземпляре Vert.х все Verticle выполняются в одном потоке. Параллелизм в Vert.х является однопоточным.

4. Vert.x способен использовать все процессоры компьютера или все ядра в процессоре, делая это путем создания по одному потоку на процессор. Каждый поток может посылать сообщения нескольким Verticle (рисунок 2).

Рисунок 2. Схема потоковой модели Vert.x

5. Verticle общаются путем передачи сообщений через шину событий (рисунок 3).

Рисунок 3. Схема обмена сообщениями между Verticle

Обработка сообщений является асинхронной. Если Verticle отправляет сообщение другому Verticle, то сообщение сначала помещается в шину событий, и управление возвращается к Verticle-отправителю. Позже, сообщение извлекается из очереди и передается всем Verticle прослушивающим адрес, на который было послано сообщение.

  1. Vert.x предоставляет общую карту и общий набор средств для передачи неизменяемых данных через Verticle в рамках одного Vert.х.
  2. В некоторых случаях Vertical нужно сделать что-то вычислительно дорогое, или то, что может блокироваться, и тогда Vert.x позволяет разработчику пометить экземпляр Vertical как рабочий Verticle. В этом случае он будет выполняться в фоновом потоке пула.

8.   Функциональность Vert.x можно разделить на две категории: основные услуги и модули. Основные услуги могут быть непосредственно вызваны из Verticle, включая в себя клиентов и серверы для TCP/SSL, HTTP и веб-сокетов; услуги доступа к шине событий; таймеры, буферы, управление потоком, доступ к файловой системе, общие карты и наборы, журналирование, конфигурацию доступа, серверы SockJS, развертывание и сворачивание потока Verticle. Основные услуги довольно статичны и неизменчивы, так что все другие функциональные возможности обеспечиваются модулями.

Примеры создания и развертывания Verticles

Простой пример создания экземпляра Vert.x выглядит так:

Vertx vertx = Vertx.vertx();

Чтобы получить приложение, выполняющее какие-то полезные действия, нужно развернуть один или несколько Verticle внутри экземпляра vertx путем создания класса, расширяющего AbstractVerticle. К примеру:

public class MyVerticle extends AbstractVerticle {
    @Override
    public void start(Future<Void> startFuture) {
        System.out.println("MyVerticle started!");
    }
    @Override
    public void stop(Future stopFuture) throws Exception {
        System.out.println("MyVerticle stopped!");
    }
}

Verticle имеет методы start и stop, вызываемые при развертывании и сворачивании Verticle. После создания Verticle его требуется развернуть в экземпляре Vert.x. Делается это с помощью одного из встроенных в экземпляр vertx методов deployVerticle.

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

vertx.deployVerticle(new BasicVerticle(), new Had-ler<AsyncResult<String>>() {
    @Override
    public void handle(AsyncResult<String> stringAsyncResult) {
        System.out.println("BasicVerticle deployment complete");
        }
    });

Примеры передачи сообщений с использованием протокола TСP. Создание TCP сервера

Одной из возможностей Vert.x является создание одного или нескольких TCP серверов в приложении. TCP сервер создается на объекте vertx с помощью вызова метода createNetServer часто внутри Verticle. После создания TCP сервера, он запускается методом listen. Перед запуском сервера TCP для обработки подключений к нему необходимо установить соответствующий обработчик. Для считывания данных из входящих соединений необходимо установить обработчик на объекте NetSocket. Пример программного кода – githab.

Закрытие сервера TCP является асинхронным действием. Для получения уведомления о выключении сервера TCP методом Close можно передать обработчик Handler, который будет вызываться, когда сервер TCP полностью закрыт. Пример:

server.close(new Handler<AsyncResult<Void>>() {
    @Override
    public void handle(AsyncResult result) {
        if(result.succeeded()){
            //TCP server fully closed
        }
    }
});

Создание TСP клиента

Создание TCP-клиента происходит путем создания экземпляра NetClient с помощью метода createNetClient объекта vertx. Часто NetClient создается внутри Verticle. Подключение к удаленному серверу осуществляется с помощью вызова метода connect. (код размещен на githab)

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

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

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

Продолжение следует

Советуем почитать