当前位置: 首页 > 知识库问答 >
问题:

垂直的概念。关于Web服务器的x?

萧升
2023-03-14

我不太明白vert. x是如何应用于网络服务器的。

我所知道的webserver的概念是基于线程的。

  1. 启动Web服务器,然后该服务器正在运行
  2. 然后,对于每个连接的客户端,您都会得到一个套接字,然后将其传递给自己的线程处理程序
  3. 然后线程处理程序处理该特定套接字的任务

因此,可以清楚地定义哪个线程为哪个套接字执行工作。然而,对于每个套接字,您都需要一个新线程,从长远来看,对于许多套接字来说,这是非常昂贵的。

然后是vert. x提供的基于事件的概念。到目前为止,我所理解的是,它应该像这样工作:

  1. Vertx实例部署Verticles

作为网络服务器示例:

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()
    }
}

此Web服务器可以在Vertx实例中多次部署。看起来,每个Web服务器实例都有自己的线程。当我尝试连接100个客户端并用一个简单的响应进行回复时,似乎每个客户端都是同步处理的。因为当我做线的时候。在每个服务器处理程序中使用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个答案

范承志
2023-03-14

代码的问题是默认情况下垂直。x每个垂直线最多只使用一个线程(如果垂直线多于可用线程,则一个线程必须处理多个垂直线)。

因此,如果对单个verticle的单个实例执行100个请求,则这些请求由单个线程处理。

为了解决您的问题,您应该部署verticle的多个实例,即。

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-core静态编程语言留档

莫选
2023-03-14

这里有一些主要问题。

当你这样做时:

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个顶点,但其中只有一个会真正侦听端口。因此,您不会获得更多并发。

其次,当您在Vert. x代码中使用Thread.sleep时,您阻塞了事件循环线程。

第三,您的客户端测试不正确。创建WebClient非常昂贵,因此通过一个接一个地创建这些客户端,实际上发出请求的速度非常慢。如果您真的想测试您的web应用程序,请使用https://github.com/wg/wrk

 类似资料:
  • 我正在尝试创建一个启动QuickFIX/J接受器服务器(TCP FIX服务器)的版本。启动时,接受器线程在单独的线程上运行,Vert. x不知道这一点(不会阻止事件循环)。然而,我可以从接受器线程访问事件总线,并将消息传递给其他顶点。 问题是,这是一个好的做法吗?

  • Hyperledger Composer是一种编程模型,包含建模语言和一组API,可快速定义和部署业务网络和应用程序,允许参与者发出交易来交换资产的。 Hyperledger Composer组件 你可以使用我们基于浏览器的界面(称为Hyperledger Composer Playground)体验Hyperledger Composer。Playground可作为托管版本(无需安装)或本地安装

  • 我在laravel开发了一个网站,并上传到网络服务器。我将所有文件和文件夹上传到根目录和公共文件夹的文件public_html。现在,当我键入网址到我的浏览器的主页工作正常,但我的其他路线显示 在laravel文档中,我发现“存储和引导/缓存目录中的目录应该可以由web服务器写入,否则laravel将无法运行。” 这是原因吗。如果是,那么我该怎么做?

  • 我需要的是,我将在端口(本地机器)中打开一个服务器监听,并且可以向我发送数据包。我的计算机没有。基本上我需要。 我正在测试服务器/客户端项目。我在服务器(公共ip)中运行stuntman-server。在我的系统中运行客户端(本地ip)。我要求为端口提供映射IP/端口。 Stun服务器返回IP和端口。然后,我在本地系统中打开一个服务器(使用java),并开始侦听端口,并将一个消息从发送到stun服

  • Navicat 提供强大的工具助你管理服务器对象,例如数据库、表、视图、函数等。 【注意】在 Navicat 中开始使用服务器对象前,你要首先创建连接。 在对象设计器的“SQL 预览”或“脚本预览”选项卡中,你可以预览创建或编辑对象时所需的 SQL 语句和脚本。对于某些数据库或模式对象,你可以使用底部的下拉式列表来显示在“文件”菜单中选择“保存”或“另存为”时所运行的 SQL 或脚本。 Navic

  • Navicat 提供强大的工具助你管理服务器对象,例如数据库、表、视图、函数等。 【注意】在 Navicat 中开始使用服务器对象前,你要首先创建连接。 在对象设计器的“SQL 预览”或“脚本预览”选项卡中,你可以预览创建或编辑对象时所需的 SQL 语句或脚本。对于某些数据库或模式对象,你可以使用底部的下拉式菜单来显示在“文件”菜单中选择“保存”或“另存为”时所运行的 SQL 或脚本。 Navic