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

或者

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

4 回答 4

1

来自 vertx 的乐于助人的人:

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

于 2012-09-07T19:37:07.870 回答
1

正如 bluesman 所说,每个 verticle 都有自己的线程。您可以将您的 Verticle 跨越硬件中的核心,甚至将它们与更多机器进行集群。但这增加了接受同时请求的能力。

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

  1. 发出请求
  2. 将任务传递给工作人员 Verticle 并为该任务分配一个 UUID(例如),并将其放入响应中。调用者现在知道工作正在进行中并且收到响应如此之快
  3. 当工作人员结束任务时,使用分配的 UUID 在事件总线中放置通知。
  4. 调用者检查事件总线以获取任务结果。

这通常通过 websockets、sockjs 等在 web 应用程序中完成。

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

于 2012-09-09T16:51:54.903 回答
0

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

据我了解,每个verticle都有自己的线程并不是真的:事实是每个verticle总是由同一个事件循环提供服务,但是更多的verticle可以与同一个事件循环绑定,并且可以有多个事件循环。事件循环基本上是一个线程,所以很少的线程应该服务于很多 Verticle。

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

问候, 卡罗

于 2012-10-23T21:00:12.380 回答
0

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

例如,当您等待 Web Socket 消息时,请求应该被挂起,如果有消息,它会被唤醒。无论您对消息做什么也应该是非阻塞的,因此是异步的,就像任何文件 IO、网络 IO、数据库访问一样。Vertx 提供了构建此类异步流的基本元素:Buffers、Pumps、Timers、EventBus。

总结一下 - 永远不要阻塞。使用sleep(10000)扼杀了这个概念。如果您真的需要停止执行,请改用VertX 的计时器

于 2014-04-02T10:15:52.047 回答