2017-01-31 14 views
0

Я разрабатываю сервер датаграмм, который прослушивает сообщения на конкретном порту, и мы используем Vertx Java Framework для его реализации. Все работает нормально, если я укажу только один экземпляр в параметрах развертывания при запуске вертикали. Как только я укажу более одного экземпляра, я получаю ошибку привязки сокета. Я понимаю, что на компьютере, когда открывается сокет, и если мы попытаемся снова прослушать его в одном сокете, это приведет к ошибке. Но для использования многоядерных процессоров мне нужно разделить Datagram Socket между несколькими экземплярами одной и той же вертикали. Я не уверен, как это сделать с использованием рамки vertx. Ниже я упомянул фрагмент кода, где я пытаюсь добиться того же. Пожалуйста, дайте мне знать, где я ошибаюсь.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, но я не хочу идти в этом направлении в этот момент до тех пор, пока нет других вариантов, оставшихся без меня.

Что является наиболее интересной частью здесь, если я прокомментирую первый метод запуска, когда я реализую сокет datagram и раскомментирую второй метод запуска, когда я запускаю httpserver на порт 8080 с теми же параметрами развертывания, которых я не вижу это исключение связывания сокета происходит вообще.

Я верю, что у меня что-то отсутствует в реализации сокета для пакетных дейтаграмм, что приводит к этой проблеме. Пожалуйста, дайте мне знать правильный способ решения этой проблемы с использованием рамки vertx.

+0

Пожалуйста, проверьте - http://stackoverflow.com/a/40205145/3940047 –

+0

@PavanKumar Я задаю вопрос о DatagramSocket для запуска UDP-сервера, ответ, который вы упомянули, говорит о TCP-сервере, который я признал, что он работает как ожидалось в мой вопрос сам. Вы читаете об этом @ http://vertx.io/docs/vertx-core/java/#_scaling_sharing_tcp_servers. – Ajay

+0

Есть вторая часть ответа, которую я поделил, где он использует eventBus - вы проверили это решение? Я считаю, что это должно помочь. Выделите раздел в ответ - 'Теперь, как вы должны это сделать:' –

ответ

1

Начиная с версии 3.3.3, балансировка нагрузки не поддерживается на серверах дейтаграмм. Я создал этот GitHub issue для отслеживания проблемы.

В качестве обходного пути вы можете установить флаг reuseAddress на rue. Это позволит избежать BindException, но только один экземпляр Verticle получит сообщения.

Все, что сказало, в зависимости от вашего случая использования, один цикл событий может меня достаточно для обработки вашего груза. Я бы рекомендовал загрузить его перед попыткой обходных решений с использованием шины событий.

+0

Вы видите какие-либо проблемы с производительностью или недостатки в отношении использования подхода на основе шины на основе событий? – Ajay

+0

Отправка сообщений по шине сообщений просто не бесплатна. Особенно в режиме кластера. Поэтому, если вы можете сделать это с помощью одной вертикали (чтобы ее можно было проверить при нагрузочном тестировании), сохраните все просто. – tsegismont

+0

Нагрузка будет довольно тяжелой, так как она станет интеллектуальной системой мониторинга событий, основанной на протоколе SNMP, где миллионы устройств будут отправлять обновления. Поэтому мне нужно учитывать масштабируемость.Мы оцениваем vertx, так как это полигот, поэтому мы можем предложить нашим пользователям сообщества разрабатывать плагины поверх нашей платформы для настройки нашего предложения. Думаю, исходя из вашего предложения, мне нужно либо пройти через реализацию httpserver, либо реализовать аналогичную методологию для распределения нагрузки используя сокет datagram или полностью развить этот компонент без использования vertx. – Ajay