Nano Hash - криптовалюты, майнинг, программирование

Как создать простой балансировщик нагрузки Java с сокетами?

Запуск UDP-сервера, прослушивающего несколько портов, так же просто, как это

ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.execute(new UDPServer(9998));
executorService.execute(new UDPServer(9999));
// UDP server implementation
try (DatagramSocket socket = new DatagramSocket(port)) {
    System.out.println("Plain UDP server :" + this.port + " name :" + Thread.currentThread().getName());
    int numberOfPacketsReceived = 0;
    while (true) {
        // todo check to stop the server
        byte[] buffer = new byte[1024];
        DatagramPacket incomingDatagramPacket = new DatagramPacket(buffer, buffer.length);
        try {
            socket.receive(incomingDatagramPacket);
            System.out.println(Thread.currentThread().getName() + ":" + numberOfPacketsReceived++);
        } catch (IOException e) {
            e.printStackTrace();
            continue;
        }
    }
} catch (SocketException e) {
    e.printStackTrace();
}

Можем ли мы создать балансировщик нагрузки, программно прослушивающий порт 9997 и альтернативно пересылающий пакет на порт 9999/9998?

Можем ли мы даже перенаправить трафик, полученный в одном сокете UDP, в другой сокет?

13.09.2017

  • Что мешает вам попробовать? Запустите сервер на 9997, затем отправляйте каждый второй пакет на 9999 вместо 9998. 13.09.2017

Ответы:


1

Было бы лучше, если бы рабочие брали из очереди блокировки и имели бы третий поток, который просто читал пакеты и помещал их в очередь для вычисления значений.

Вы можете перенаправить пакеты в другой сокет, но это приведет к ненужным накладным расходам внутри той же программы, и вы потеряете метаданные пакета.

Если вы хотите использовать балансировщик нагрузки, вы можете реализовать балансировщик нагрузки следующим образом:

class C {
  public static void main(final String... args) {
    try (DatagramSocket socket = new DatagramSocket(9997);
         DatagramSocket out = new DatagramSocket()) {

      final InetSocketAddress[] sockets = {
          new InetSocketAddress("localhost", 9998),
          new InetSocketAddress("localhost", 9999)
      };

      int i = 0;
      while (true) {
      // todo check to stop the server
        byte[] buffer = new byte[1024];
        DatagramPacket incomingDatagramPacket = new DatagramPacket(buffer, buffer.length);
        try {
          socket.receive(incomingDatagramPacket);
          incomingDatagramPacket.setSocketAddress(sockets[i++%2]);
          out.send(incomingDatagramPacket);
        } catch (IOException e) {
          e.printStackTrace();
          continue;
        }
      }
    } catch (SocketException e) {
      e.printStackTrace();
    }
  }
}
13.09.2017
  • Неясно, хочет ли OP запускать балансировщик и рабочих отдельно или на одной машине. Однако для одной машины это достойный ответ. 13.09.2017
  • @ forum.test17 Я бы посоветовал вам профилировать свой код и поделиться результатами в отдельном вопросе о SO, если неясно, как с ними действовать. Балансировщики нагрузки обычно используются для разделения трафика между разными машинами, т.е. е. когда одной машины явно мало. 13.09.2017
  • @ Vovanrock2002 Vovanrock2002 я скоро сделаю это в этой теме запросы могут обрабатывать сокет java udp"> stackoverflow.com/questions/46023098/ 13.09.2017
  • Добавлен способ реализовать желаемое поведение 13.09.2017
  • Для этого вам не нужны три сокета, и вы ничего здесь не перенаправляете, просто отправляете пакеты обратно на тот же порт, с которого они пришли. 13.09.2017
  • Я протестировал его локально, и он, похоже, работает, адрес назначения изменен, я вижу только 2 сокета, хотя вместо этого можно было бы повторно использовать один 13.09.2017
  • Мой код был основан на этом 13.09.2017
  • @EJP, не могли бы вы объяснить проблемы, с которыми вы столкнулись при запуске моего кода, похоже, это сработало, я запустил 2 прослушивателя UDP с nc на портах 9998 и 9999 и подключился к порту 9997 с nc, и мои входные данные пошли на правильные экземпляры сервера 14.09.2017
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..