Двусторонний RMI с Spring при поддержке очереди сообщений - PullRequest
0 голосов
/ 25 марта 2019

Система состоит из 1 или более клиентов и одного сервера. Каждый клиент добавляется вручную и получает идентификатор (client.id). Каждый клиент может отправлять сообщения на сервер. Сервер может отправлять сообщения каждому клиенту. Все сообщения можно разделить на две группы: с ответом и без.

Например, некоторые подписи:

  • CompletableFuture<Response> call(Request requestToServer)
  • void execute(Data dataToSend)

, где Ответ, Запрос и Данные - это мой POJO.

Итак, мне нужен своего рода RMI для реализации обмена сообщениями между сервером и клиентами.

Требования:

  1. Сервер должен иметь возможность идентифицировать клиента по его идентификатору client.id при обработке сообщения, но клиент перед отправкой этого сообщения не должен напрямую заполнять этот идентификатор;
  2. Сообщения должны быть POJO;
  3. Возможность ответить на сообщение с исключением;
  4. Обработчики, управляемые событиями (например, @RabbitListener) - несколько обработчиков - пружинный компонент для каждого типа входящего сообщения, с типом возврата или без него. Обработчик должен быть разрешен автоматически в зависимости от типа входящего сообщения;
  5. При поддержке RabbitMQ или ArtemisMQ;
  6. Единый сервис для отправки сообщений с сервера клиентам: при отправке сообщения должен быть указан идентификатор клиента. Пример: void sendToClient(int clientId, Data dataToClient).

Что я пытался настроить этот метод связи:

  1. Spring Integration Мой собственный шлюз с готовым будущим - отлично. Кроме того, можно обогатить заголовки сообщений с помощью client.id - отлично. Но я не нашел подходящего способа обработки входящего сообщения и возможности ответить на него. Попытка опубликовать ApplicationEvent, но все обработчики событий имеют тип возврата void. Итак, моя идея здесь состоит в том, чтобы получить correlationId и отправить обратно сообщение, при условии, что correlationId - это не похоже на ясное решение.

  2. RabbitListener / RabbitTemplate Минусы:

    • Много кода для настройки RabbitTemplate для отправки и получения сообщений;
    • Необходимо вручную настроить очереди запросов и ответов и привязок;
    • проблема с решением client.id в @ RabbitHandler.
  3. AmqpProxyFactoryBean Ближайший результат к моим потребностям, но несколько проблем, которые я не могу решить:

    • Разрешить client.id в обработчике сообщений;
    • Один обработчик для метода интерфейса службы.

Итак, мне нужно легкое решение для построения связи между службами, подкрепленное очередью сообщений. Должно быть легко добавить дополнительный тип сообщения - объявите класс, добавьте обработчик к получателю, создайте объект этого класса и отправьте его от производителя.

Но, может быть, я совершенно не прав насчет услуг связи? Может быть, я не должен использовать очередь сообщений для этой цели?

1 Ответ

0 голосов
/ 25 марта 2019

Хорошо использовать очередь сообщений или брокер сообщений, такой как RabbitMQ, - это совершенно правильное решение.Но вы должны подумать, действительно ли это то, что вам нужно.

Посредник сообщений позволяет разделить производителей и потребителей сообщений.Это также позволяет ввести уровень отказоустойчивости.Если потребитель временно недоступен, сообщение не теряется.Однако это также означает, что, если ожидается ответ, производитель сообщения может ошибочно полагать, что другой конец обработал его запрос, и продолжает ждать ответа.Брокеры сообщений также часто предлагают какую-то гарантию, например, один раз и только один раз или, по крайней мере, один раз, а также политику, как обрабатывать недоставленные сообщения (например, очереди недоставленных писем), время жизни и различную маршрутизацию.возможности (например, последовательная маршрутизация на основе хеша).В вашем случае вам, вероятно, придется маршрутизировать по некоторому значению заголовка, содержащему ваш client.id, если ваши серверные сообщения должны достигать только одного клиента.

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

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

...