Понятие vert.x относительно веб-сервера? - PullRequest
1 голос
/ 29 мая 2019

Я не совсем понимаю, как vert.x применяется для веб-сервера.

Концепция, которую я знаю для веб-сервера, основывается на потоке.

  1. Вы начинаетеwebserver, который затем работает.
  2. Затем для каждого подключающегося клиента вы получаете сокет, который затем передается в его собственный обработчик потока.
  3. Затем обработчик потока обрабатывает задачи для этогоконкретный сокет.

Таким образом, четко определено, какой поток выполняет работу для какого сокета.Однако для каждого сокета вам нужен новый поток, который в долгосрочной перспективе обходится многим сокетам.

Тогда есть концепция, основанная на событиях, которую предоставляет vert.x.До сих пор я понял, что все должно работать так:

  1. Экземпляр Vertx развертывает Vericies.
  2. Версии запускаются в фоновых потоках, но не у каждой Verticle есть свой собственный поток.Например, в экземпляре Vertx может быть развернуто 1000 вершин, но экземпляр Vertx обрабатывает только 8 потоков (количество ядер * 2).
  3. Затем возникают циклы событий.Я не уверен, как они относятся к статьям.Я читал, что каждая вертикаль имеет 2 цикла событий, но на самом деле не знаю, как это работает.

В качестве примера веб-сервера:

class WebServer: AbstractVerticle() {
    lateinit var server: HttpServer

    override fun start() {
        server = vertx.createHttpServer(HttpServerOptions().setPort(1234).setHost("localhost"))
        var router = Router.router(vertx);
        router.route("/test").handler { routingContext ->
            var response = routingContext.response();
            response.end("Hello from my first HttpServer")
        }
        server.requestHandler(router).listen()
    }
}

Этот веб-сервер может быть развернутнесколько раз в экземпляре Vertx.И, как кажется, каждый экземпляр WebServer получает свой собственный поток.Когда я пытаюсь подключить 100 клиентов и отвечать простым ответом, кажется, что каждый клиент обрабатывается синхронно.Потому что, когда я делаю инструкцию Thread.sleep в каждом обработчике сервера, каждый второй клиент получает ответ.Однако должно быть так, что все обработчики сервера должны начать 1-секундный спящий режим, а затем почти одинаково ответить всем клиентам после этого времени.

Это код для запуска 100 клиентов:

fun main(){
    Vertx.vertx().deployVerticle(object : AbstractVerticle(){
        override fun start() {
            for(i in 0 .. 100)
                MyWebClient(vertx)
        }
    })
}

class MyWebClient(val vertx: Vertx) {
    init {
        println("Client starting ...")
        val webClient = WebClient.create(vertx, WebClientOptions().setDefaultPort(1234).setDefaultHost("localhost"))
        webClient.get("/test").send { ar ->
            if(ar.succeeded()){
                val response: HttpResponse<Buffer> = ar.result()

                println("Received response with status code ${response.statusCode()} + ${response.body()}")
            } else {
                println("Something went wrong " + ar.cause().message)
            }
        }
    }
}

Кто-нибудь знает объяснение этому?

Ответы [ 2 ]

0 голосов
/ 30 мая 2019

Там есть несколько серьезных проблем.

Когда вы сделаете это:

class WebServer: AbstractVerticle() {
    lateinit var server: HttpServer

    override fun start() {
        server = vertx.createHttpServer(HttpServerOptions().setPort(1234).setHost("localhost"))
       ...
    }
}

Тогда что-то вроде этого:

vertx.deployVerticle(WebServer::class.java.name, DeploymentOptions().setInstances(4)

Вы получите 4 фразы, но на самом деле только одна из них будет слушатьв порту.Таким образом, вы не получаете больше параллелизма.

Во-вторых, когда вы используете Thread.sleep в своем коде Vert.x, вы блокируете поток цикла событий.

В-третьих, ваш тест с клиентом неверен.Создание WebClient стоит очень дорого, поэтому, создавая один за другим, вы фактически делаете запросы очень медленно.Если вы действительно хотите протестировать свое веб-приложение, используйте что-то вроде https://github.com/wg/wrk

0 голосов
/ 29 мая 2019

Проблема с вашим кодом заключается в том, что по умолчанию Vert.x использует не более одного потока на одну строку (если число строк больше, чем доступных потоков, один поток должен обрабатывать несколько строк).

Поэтому, если вы выполняете 100 запросов к одному экземпляру одной вертикали, запросы обрабатываются одним потоком.

Чтобы решить вашу проблему, вы должны развернуть несколько экземпляров своей вертикали, то есть

vertx.deployVerticle(MainVerticle::class.java.name, DeploymentOptions().setInstances(4))

при этом всегда будет получено 4 ответа почти в одно и то же время, потому что 4 экземпляра вертикали работают и, таким образом, используются 4 потока.

В предыдущих версиях Vert.x,Вы также можете просто настроить многопоточность для вертикали, если не хотите устанавливать конкретное количество экземпляров.

vertx.deployVerticle(MainVerticle::class.java.name, DeploymentOptions().setWorker(true).setMultiThreaded(true))

Однако эта функция устарела и заменена пулами рабочих клиентов.

Для получения дополнительной информации по этой теме, я призываю вас взглянуть на Vert.x-corЭлектронная документация Kotlin

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...