如何将传入的 NetSocket 处理程序分派到不同的事件循环线程? [英] How to dispatch incoming NetSocket handlers into different event loop threads?

查看:31
本文介绍了如何将传入的 NetSocket 处理程序分派到不同的事件循环线程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 Vertx 来实现 TCP 服务器,接受传入的连接,然后处理不同的套接字.由于每个套接字可以独立处理,因此属于不同套接字的处理程序应该同时运行在不同的事件循环线程中.

I'm trying to use Vertx to implement a TCP server, accepting incoming connections and then handling different sockets. Since each socket can be handled independently, the handlers belonging to different sockets are supposed to run in different event loop threads concurrently.

根据 Vert.x 文档

标准 Verticle 在创建时会被分配一个事件循环线程,并且使用该事件循环调用 start 方法.当您从事件循环调用在核心 API 上接受处理程序的任何其他方法时,Vert.x 将保证这些处理程序在被调用时将在同一个事件循环中执行.

Standard verticles are assigned an event loop thread when they are created and the start method is called with that event loop. When you call any other methods that takes a handler on a core API from an event loop then Vert.x will guarantee that those handlers, when called, will be executed on the same event loop.

我认为,这个代码片段可以打印不同的线程名称:

I think, this code snippet can print different thread names:

Vertx vertx = Vertx.vertx(); // The number of event loop threads is 2*core.
vertx.createNetServer().connectHandler(socket -> {
    vertx.deployVerticle(new AbstractVerticle() {
        @Override
        public void start() throws Exception {
            socket.handler(buffer -> {
                log.trace(socket.toString() + ": Socket Message");
                socket.close();
            });
        }
    });
}).listen(port);

但不幸的是,所有处理程序都位于同一个线程中.

But unfortunately, all handlers were located in the same thread.

23:59:42.359 [vert.x-eventloop-thread-1] TRACE Server - io.vertx.core.net.impl.NetSocketImpl@253fa4f2: Socket Message
23:59:42.364 [vert.x-eventloop-thread-1] TRACE Server - io.vertx.core.net.impl.NetSocketImpl@465f1533: Socket Message
23:59:42.365 [vert.x-eventloop-thread-1] TRACE Server - io.vertx.core.net.impl.NetSocketImpl@5ab8dac: Socket Message
23:59:42.366 [vert.x-eventloop-thread-1] TRACE Server - io.vertx.core.net.impl.NetSocketImpl@5fc72993: Socket Message
23:59:42.367 [vert.x-eventloop-thread-1] TRACE Server - io.vertx.core.net.impl.NetSocketImpl@38ee66d7: Socket Message
23:59:42.368 [vert.x-eventloop-thread-1] TRACE Server - io.vertx.core.net.impl.NetSocketImpl@6a60a74: Socket Message
23:59:42.369 [vert.x-eventloop-thread-1] TRACE Server - io.vertx.core.net.impl.NetSocketImpl@5f3921e1: Socket Message
23:59:42.370 [vert.x-eventloop-thread-1] TRACE Server - io.vertx.core.net.impl.NetSocketImpl@39d41024: Socket Message
... more than 100+ lines ...

相反的例子类似于这个用 BOOST.ASIO 编写的回显服务器.如果使用线程池来执行 io_service::run(),则处理程序在不同的事件循环线程中运行.

An opposite example is similar to this echo server written in BOOST.ASIO. The handlers run in different event loop threads if a thread pool is used to execute io_service::run().

那么,我的问题是如何同时运行这些处理程序?

So, my question is how to run these handlers concurrently?

推荐答案

如果没有更多详细信息(例如测试机器的内核数),则无法确定 Vert.x 将分配给每个 Verticle 的事件循环.

It's not possible to determine which event loop Vert.x will assign to each of your verticles without more details (number of cores of your test machines for example).

无论如何,为每个传入连接部署一个 Verticle 并不是一个好主意.Verticles 是 Vert.x 中的部署单元.您通常会为每个功能"创建一个.

Anyway, it is not a good idea to deploy a verticle per incoming connection. Verticles are units of deployment in Vert.x. You would typically create one per "functionality".

回到您的用例,事件驱动编程的目的正是为了避免每个连接使用一个线程.您可以使用单个事件循环处理大量并发连接.如果您的机器上有多个内核,那么您可以部署您的 Verticle 的多个实例以全部使用它们(每个内核 1 个事件循环).

Back to your use case, the purpose of event driven programming is precisely to avoid using a thread per connection. You can handle a lot of concurrent connections with a single event loop. If you have multiple cores on your machine then you can deploy multiple instances of your verticle to use them all (1 event loop per core).

int processors = Runtime.getRuntime().availableProcessors();
Vertx vertx = Vertx.vertx();
vertx.deployVerticle(TCPServerVerticle.class.getName(), new DeploymentOptions().setInstances(processors));

public class TCPServerVerticle extends AbstractVerticle {

  @Override
  public void start(Future<Void> startFuture) throws Exception {
    vertx.createNetServer().connectHandler(socket -> {
      socket.handler(buffer -> {
        log.trace(socket.toString() + ": Socket Message");
        socket.close();
      });
    }).listen(port, ar -> {
      if (ar.succeeded()) {
        startFuture.complete();
      } else {
        startFuture.fail(ar.cause());
      }
    });
  }
}

使用 Vertx TCP 服务器共享,连接处理程序将在循环时尚.

With Vertx TCP server sharing the connect handlers will be called on a round-robin fashion.

这篇关于如何将传入的 NetSocket 处理程序分派到不同的事件循环线程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆