Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Vertx实例化多个垂直实例,侦听同一套接字_Java_Sockets_Udp_Rx Java_Vert.x - Fatal编程技术网

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

Java Vertx实例化多个垂直实例,侦听同一套接字,java,sockets,udp,rx-java,vert.x,Java,Sockets,Udp,Rx Java,Vert.x,我正在开发一个数据报服务器,它监听特定端口上的消息,我们正在使用VertxJava框架来实现同样的功能。如果在启动垂直部署时在部署选项中只指定一个实例,那么一切都可以正常工作。一旦我指定了多个实例,就会出现套接字绑定错误。我理解,在一台机器上,一旦一个套接字被打开,如果我们尝试在同一个套接字上再次侦听,就会导致这个错误。但是为了利用多核处理器,我需要在同一个垂直处理器的多个实例之间共享数据报套接字。我不知道如何使用vertx框架实现这一点。下面我提到了我正在尝试实现相同功能的代码片段。请告诉我哪

我正在开发一个数据报服务器,它监听特定端口上的消息,我们正在使用VertxJava框架来实现同样的功能。如果在启动垂直部署时在部署选项中只指定一个实例,那么一切都可以正常工作。一旦我指定了多个实例,就会出现套接字绑定错误。我理解,在一台机器上,一旦一个套接字被打开,如果我们尝试在同一个套接字上再次侦听,就会导致这个错误。但是为了利用多核处理器,我需要在同一个垂直处理器的多个实例之间共享数据报套接字。我不知道如何使用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 ");
 }
}
公共类TestServer扩展了AbstractVerticle{
@凌驾
public void start(Future startFuture)引发异常{
DatagramSocket accessSocket=vertx.createDatagramSocket(新DatagramSocketOptions());
int accessPort=1234;
侦听(accessPort,“0.0.0.0”,asyncResult->{
if(asyncResult.successed()){
accessSocket.handler(数据包->{
记录器错误(“在端口上接收”+数据包);
InetSocketAddress localAddress=新的InetSocketAddress(accessSocket.localAddress().host(),accessSocket.localAddress().port());
InetSocketAddress remoteAddress=新的InetSocketAddress(packet.sender().host(),packet.sender().port());
缓冲区数据=packet.data();
试一试{
//handlePacket(本地地址、远程地址、解码数据包);
}捕获(例外e){
System.out.println(“处理数据包时侦听错误”+数据包,e);
}
});
}否则{
System.out.println(“侦听startAccessServer失败”+asyncResult.cause());
}
});
}
/*
@凌驾
公共空间启动(未来未来未来){
顶点
.createHttpServer()
.requestHandler(r->{
r、 response().end(“来自Vertx的你好”+
"");
})
.听(8080,结果->{
if(result.successed()){
fut.complete();
}否则{
进一步失败(result.cause());
}
});
}
*/
公共静态void main(字符串[]args){
DeploymentOptions=新的DeploymentOptions();
//选项。设置实例(1);
options.setInstances(Runtime.getRuntime().availableProcessors());
Vertx.Vertx().deployVerticleObservable(TestServer.class.getName(),options.subscribe();
System.out.println(“服务器已启动”);
}
}
只要我运行这段代码,就会产生套接字绑定异常,第一个垂直实例除外。如果我指定options.setInstances(1),问题会得到解决,但只会启动一个垂直实例。我知道我可能可以使用eventbus解决这个问题,但我现在不想朝这个方向走,除非我没有其他选择

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


我相信我的数据报套接字实现中缺少了一些东西,这导致了这个问题。请让我知道使用vertx框架解决此问题的正确方法

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

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


综上所述,根据您的用例,单个事件循环可能足以处理您的负载。我建议在使用事件总线尝试解决方法之前对其进行负载测试。

请检查-@PavanKumar我要询问运行UDP服务器的DatagramSocket的具体情况,你提到的答案是关于TCP服务器的,我承认它在我的问题中工作正常。你可以阅读更多关于它的内容@。答案的第二部分是关于它使用eventBus的地方-你检查过这个解决方案吗?我相信这会有所帮助。现在滚动到回答中的部分-
了解您应该如何做:
@PavanKumar,感谢您尝试帮助我,但请完整阅读我的问题。我已经详细说明了事件总线解决方案,在这篇文章中,我正在寻找类似于HttpServer实现的东西,在HttpServer实现中,vertx实例是共享的,而不是基于事件总线的解决方案。很抱歉遗漏了这一部分。刚刚对答案中的问题投了赞成票。您也可以这样做以获得更好的可视性。您是否发现使用基于事件总线的方法有任何性能问题或缺点?通过消息总线发送消息不是免费的。尤其是在集群模式下。因此,如果您可以使用单个垂直通道(通过负载测试进行验证),请保持简单。由于它将是一个基于SNMP协议的智能事件监视系统,数百万设备将发送更新,因此负载将非常沉重。所以我需要在这里说明可伸缩性。我们正在评估vertx,因为它是polygot,因此,我们可以让我们的社区用户在我们的平台上开发插件,以定制我们的产品。我认为,根据您的建议,我需要通过httpserver实现并自己实现类似的方法,使用datagram socket进行负载共享,或者完全开发此组件而不使用vertx。我只能建议投票支持GitHub问题,以便在将来的版本中包含它。