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

时间:2012-09-01 22:43:21

标签: grails websocket vert.x grails-2.1

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

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

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

我用websocket和SockJs尝试了这个,并注意到两者都有相同的行为。

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");
            }
    }

OR

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

4 个答案:

答案 0 :(得分:1)

来自vertx的有用人员:

def server = vertx.createHttpServer()实际上是一个Verticle,Verticle是一个单线程进程

答案 1 :(得分:1)

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

在编写实时应用程序时,我们应尽快建立响应以避免阻塞。如果您认为您的操作需要时间,请考虑以下模型:

  1. 提出请求
  2. 将任务传递给工作者Verticle,并为此任务分配一个UUID(例如),并将其置于响应中。调用者现在知道工作正在进行并且收到响应的速度很快
  3. 当工作人员结束任务时,使用指定的UUID在事件总线中发出通知。
  4. 调用者检查事件总线以获取任务结果。
  5. 这是在Web应用程序中完成的,例如websockets,sockjs等。

    通过这种方式,您可以无阻塞地接受数千个请求。客户端将在不阻止UI的情况下收到结果。

答案 2 :(得分:0)

Vert.x使用JVM创建一个所谓的“多反应堆模式”,即修改后的反应堆模式以更好地执行。

据我所知,为真,每个Verticle都有自己的线程:事实是每个Verticle总是由同一个事件循环提供服务,但是更多Verticle可以用相同的事件绑定事件循环,可以有多个事件循环。事件循环基本上是一个线程,因此很少有线程应该服务于许多Verticle。

我没有在嵌入模式下使用vert.x(我不知道主要概念是否会改变)但是你应该更好地为作业实例化多个Verticle

此致 卡罗

答案 3 :(得分:0)

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

E.g。当你等待Web Socket消息时,请求应该被暂停,并且如果消息被唤醒,它将被唤醒。无论你对消息做什么,都应该是非阻塞的,因此是异步的,就像任何文件IO,网络IO,数据库访问一样。 Vertx提供了用于构建此类异步流的基本元素:Buffers,Pumps,Timers,EventBus。

把它包起来 - 永远不要阻止。 sleep(10000)的使用杀死了这个概念。如果你真的需要停止执行,请使用VertX's Timers