知道为什么嵌入在 grails 中的 vertx 请求会同步排队


Environment: Mac osx lion
Grails version: 2.1.0
Java: 1.7.0_08-ea

如果我在 Bootstrap.groovy 中以嵌入式模式启动 vertx,并尝试通过多个浏览器访问相同的 websocket 端点,则请求会排队。

因此,根据请求的时间,在一个请求执行完毕后,下一个请求将进入处理程序。

我已经在websocket和SockJ上尝试过这个,并注意到两者的行为相同。

BootStrap.groovy (SockJs(:

    def vertx = Vertx.newVertx()
    def server = vertx.createHttpServer()
    def sockJSServer = vertx.createSockJSServer(server)
    def config = ["prefix": "/eventbus"]
    sockJSServer.installApp(config) { sock ->
      sleep(10000)      
    }
    server.listen(8088)

JavaScript:

<script>
    function initializeSocket(message) {
            console.log('initializing web socket');
            var socket = new SockJS("http://localhost:8088/eventbus");
            socket.onmessage = function(event) {
                console.log("received message");
            }
            socket.onopen = function() {
                console.log("start socket");
                socket.send(message);
            }
            socket.onclose = function() {
                console.log("closing socket");
            }
    }

BootStrap.groovy (Websockets(:

    def vertx = Vertx.newVertx()
    def server = vertx.createHttpServer()
    server.setAcceptBacklog(10000);
    server.websocketHandler { ws ->
        println('**received websocket request')
        sleep(10000)
    }.listen(8088)

JavaScript

socket = new WebSocket("ws://localhost:8088/ffff");
            socket.onmessage = function(event) {
                console.log("message received");
            }
            socket.onopen = function() {
                     console.log("socket opened")
                socket.send(message);
            }
            socket.onclose = function() {
                console.log("closing socket")
            }

来自 vertx 的乐于助人的人:

def server = vertx.createHttpServer(( 实际上是一个垂直点,一个顶点是一个单线程进程

正如布鲁斯曼所说,每个顶点都有自己的线程。您可以跨硬件中的内核跨越顶点,甚至可以将它们与更多计算机进行集群。但这增加了接受同时请求的能力。

在对实时应用程序进行编程时,我们应该尝试尽快构建响应以避免阻塞。如果您认为您的操作可能非常耗时,请考虑以下模型:

  1. 提出请求
  2. 将任务传递给工作线程垂直点,并为此任务分配一个 UUID(例如(,并将其置于响应中。呼叫者现在知道工作正在进行中,并很快收到响应
  3. 当工作人员结束任务时,使用分配的 UUID 在事件总线中放置通知。
  4. 调用方检查事件总线以获取任务结果。

这是在Web应用程序中完成的,vía websockets,sockjs等。

这样,您可以接受数千个请求而不会阻塞。客户端将在不阻止 UI 的情况下收到结果。

Vert.x 使用 JVM 创建所谓的"多反应器模式",即修改为性能更好的反应器模式。

据我了解,每个顶点都有自己的线程是不正确的:事实是每个顶点总是由同一个事件循环提供服务,但更多的顶点可以绑定到同一个事件循环,并且可以有多个事件循环。事件循环基本上是一个线程,因此很少有线程应该服务于许多顶点。

我没有在嵌入式模式下使用 vert.x(我不知道主要概念是否发生了变化(,但您应该更好地实例化工作的许多顶点

问候卡 罗

如前所述,Vertx 概念基于反应器模式,这意味着单个实例至少有一个单线程事件循环并按顺序处理事件。现在请求处理可能包含多个事件,这里的重点是使用非阻塞例程为请求和每个事件提供服务。

例如,当您等待 Web 套接字消息时,请求应该暂停,如果出现消息,它会被唤醒。无论您对消息做什么,也应该是非阻塞的,因此是异步的,就像任何文件 IO、网络 IO、数据库访问一样。Vertx 提供了您应该用来构建此类异步流的基本元素:缓冲区、泵、计时器、事件总线。

要包装它 - 只是永远不要阻止。使用sleep(10000)扼杀了这个概念。如果您确实需要停止执行,请使用 VertX 的计时器。

相关内容

  • 没有找到相关文章

最新更新