Как масштабировать Vert.x по вертикали без вертикалей?

#java #vert.x #event-loop #vertx-verticle

#java #vert.x #цикл событий #vertx-verticle

Вопрос:

Согласно документам Vert.x — развертывание с использованием вертикалей необязательно. Если это так — как я могу развернуть, скажем, HTTP-сервер на несколько циклов событий? Вот что я пробовал — также прочитал документы api и ничего не смог найти:

 Vertx vertx = Vertx.vertx(new VertxOptions().setEventLoopPoolSize(10));

HttpServerOptions options = new HttpServerOptions().setLogActivity(true);

for (int i = 0; i < 10; i  ) {
  vertx.createHttpServer(options).requestHandler(request -> {
    request.response().end("Hello world");
  }).listen(8081);
}
 

Похоже, что это создает 10 HTTP-серверов в первом цикле событий, но я надеюсь на 1 сервер на цикл событий.

Вот что я вижу в своих журналах — все eventloop-thread-0:

08:42:46.667 [vert.x-eventloop-thread-0] ОТЛАЖИВАТЬ io.netty.обработчик.ведение журнала.LoggingHandler — [id: 0x0c651def, L:/0:0:0:0:0:0:0:1:8081 — R:/0:0:0:0:0:0:0:1:50978 ] ЧИТАТЬ: 78B

08:42:46.805 [vert.x-eventloop-thread-0] ОТЛАЖИВАТЬ io.netty.обработчик.ведение журнала.LoggingHandler — [id: 0xe050d078, L:/0:0:0:0:0:0:0:1:8081 — R:/0:0:0:0:0:0:0:1:51000 ] ЧИТАТЬ: 78B

08:42:47.400 [vert.x-eventloop-thread-0] ОТЛАЖИВАТЬ io.netty.обработчик.ведение журнала.LoggingHandler — [id: 0x22b626b8, L:/0:0:0:0:0:0:0:1:8081 — R:/0:0:0:0:0:0:0:1:51002 ] ЧИТАТЬ: 78B

Ответ №1:

«Необязательно» не означает «вы можете, получая те же преимущества». «Необязательно» просто означает «вы можете».

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

Вы можете сравнить приведенный выше пример кода со следующим кодом:

         Vertx vertx = Vertx.vertx();

        HttpServerOptions options = new HttpServerOptions().setLogActivity(true);

        // Spawn multiple threads, so EventLoops won't be bound to main
        ExecutorService tp = Executors.newWorkStealingPool(10);
        CountDownLatch l = new CountDownLatch(1);
        for (int i = 0; i < 10; i  ) {
            tp.execute(() -> {
                vertx.createHttpServer(options).requestHandler(request -> {
                    System.out.println(Thread.currentThread().getName());
                    // Slow the response somewhat
                    vertx.setTimer(1000, (h) -> {
                        request.response().end("Hello world");
                    });
                }).listen(8081);
            });
        }
        // Just wait here
        l.await();
 

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

 vert.x-eventloop-thread-0
vert.x-eventloop-thread-1
vert.x-eventloop-thread-2
vert.x-eventloop-thread-0
 

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

Комментарии:

1. Итак, вы говорите, что невозможно написать многопоточный код Vertx без использования вертикалей? Я также не понимаю, какое отношение к потоку имеет к этому? Я прочитал это «Методы подготовки, такие как createHttpServer или SetTimer, могут быть вызваны из потока, отличного от Vert.x» здесь freecontent.manning.com /.

2. Я не говорил, что это невозможно. Я сказал «вы можете». Но вы не получите от этого никаких преимуществ. Я обновил свой ответ некоторыми примерами кода.

3. Это полезно — я пытался понять, как работают вертикали, и это проясняет ситуацию. Я бы сказал, что есть преимущество в интеграции Vertx с существующей платформой на основе исполнителя, такой как Camel camel.apache.org/components/latest /.