我正在开发监听特定端口上的消息的数据报服务器,我们正在使用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框架解决此问题的正确方法。
答案 0 :(得分:1)
从3.3.3开始,数据报服务器不支持负载均衡。我创建了这个GitHub issue来跟踪问题。
作为解决方法,您可以将reuseAddress
标志设置为rue。这将避免BindException
,但只有一个Verticle实例将接收消息。
所有这一切,根据您的使用案例,单个事件循环可能足以处理您的负载。我建议在使用事件总线尝试变通方法之前加载测试。