Vertx实例化侦听同一套接字的多个垂直实例

时间:2017-01-31 07:36:27

标签: java sockets udp rx-java vert.x

我正在开发监听特定端口上的消息的数据报服务器,我们正在使用Vertx Java Framework来实现相同的功能。如果我在启动垂直时在部署选项中仅指定一个实例,则一切正常。一旦我指定了多个实例,我就会收到套接字绑定错误。一旦打开套接字,我就会在机器上理解,如果我们尝试再次在同一个套接字上监听,则会导致此错误。但是为了利用多核处理器,我需要在同一垂直的多个实例之间共享数据报套接字。我不知道如何使用vertx框架实现这一点。下面我提到了代码片段,我试图实现相同的目标。请让我知道我哪里出错了。

public class TestServer  extends AbstractVerticle {

@Override
public void start(Future<Void> startFuture) throws Exception {


    DatagramSocket accessSocket = vertx.createDatagramSocket(new DatagramSocketOptions());
    int accessPort=1234;

    accessSocket.listen(accessPort, "0.0.0.0", asyncResult -> {
      if (asyncResult.succeeded()) {
          accessSocket.handler(packet -> {
                logger.error("Received on  Port  "+packet);
                InetSocketAddress localAddress =  new InetSocketAddress(accessSocket.localAddress().host(), accessSocket.localAddress().port());
                InetSocketAddress remoteAddress = new InetSocketAddress(packet.sender().host(), packet.sender().port());
                Buffer data = packet.data();
                try {

                    //handlePacket(localAddress, remoteAddress, decodePacket);

                } catch (Exception e) {
                     System.out.println("listen Error while processing the packet " +packet,  e);
                }
        });
      } else {
        System.out.println(" listen startAccessServer Failed " + asyncResult.cause());
      }
    });
}

/*
@Override
  public void start(Future<Void> fut) {
    vertx
        .createHttpServer()
        .requestHandler(r -> {
          r.response().end("<h1>Hello from Vertx " +
              "</h1>");
        })
        .listen(8080, result -> {
          if (result.succeeded()) {
            fut.complete();
          } else {
            fut.fail(result.cause());
          }
        });
  }
  */


 public static void main(String[] args) {

    DeploymentOptions options = new DeploymentOptions();
    //options.setInstances(1);
    options.setInstances(Runtime.getRuntime().availableProcessors());
    Vertx.vertx().deployVerticleObservable(TestServer.class.getName(),options).subscribe();
    System.out.println("Server Started ");
 }
}

只要我运行此代码,就会导致Socket绑定异常,但第一个垂直实例除外。如果我指定options.setInstances(1),问题就会得到解决,但只启动一个垂直实例。我知道我可能能够使用eventbus解决问题,但此刻我不想朝这个方向前进,直到或除非我没有其他选项。

这里最有趣的部分是,如果我注释掉第一个启动方法,我正在实现数据报套接字并取消注释第二个启动方法,我在端口8080上使用相同的部署选项启动httpserver我不会看到这个套接字绑定异常发生了。

我相信我在数据报套接字实现中遗漏了一些导致此问题的内容。请让我知道使用vertx框架解决此问题的正确方法。

1 个答案:

答案 0 :(得分:1)

从3.3.3开始,数据报服务器不支持负载均衡。我创建了这个GitHub issue来跟踪问题。

作为解决方法,您可以将reuseAddress标志设置为rue。这将避免BindException,但只有一个Verticle实例将接收消息。

所有这一切,根据您的使用案例,单个事件循环可能足以处理您的负载。我建议在使用事件总线尝试变通方法之前加载测试。