我不太明白 vert.x 是如何应用于网络服务器的。
我所知道的网络服务器概念是基于线程的。
- 您启动您的网络服务器,然后它正在运行。
- 然后对于每个连接的客户端,您都会获得一个套接字,然后将其传递给它自己的线程处理程序。
- 然后线程处理程序处理这个特定套接字的任务。
因此明确定义了哪个线程为哪个套接字工作。但是,对于每个套接字,您都需要一个新线程,从长远来看,这对于许多套接字来说是昂贵的。
然后是 vert.x 提供的基于事件的概念。到目前为止,我已经理解,它应该像这样工作:
- Vertx 实例部署 Verticle。
- Verticle 在后台线程中运行,但并不是每个 Verticle 都有自己的线程。例如,一个 Vertx 实例中可能部署了 1000 个 Verticle,但 Vertx 实例仅处理 8 个线程(nr of cores * 2)。
- 然后是事件循环。我不确定它们是如何指代verticles的。我读过每个verticle都有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()
}
}
此 WebServer 可以在 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)
}
}
}
}
有人知道对此的解释吗?