Предположим, что у меня есть балансировщик нагрузки (LB) перед экземплярами Vert.V (V), каждый экземпляр VertX подключен к очереди (Q), и у меня есть 1. .m Бэкэндз (BE).Соответствующий ответный обработчик с запросом в VertX
Пользователь нажимает кнопку, которая отправляет запрос или даже открывает сетевой сокет, балансировщик нагрузки пересылает запрос одному из экземпляров VertX, который запускает запрос в очередь, один из бэкендов потребляет сообщение и отправляет ответ обратно; если правильный экземпляр VertX его использует, он может найти обработчик ответа и написать ответ пользователю, если неправильный экземпляр VertX его использует, не будет обработчика ответа, чтобы написать ответ, и пользователь будет ждать бесконечно для ответ.
Смотрите этот эскиз:
В качестве альтернативы, V2 умирает и балансировка нагрузки переподключает пользователь V1, который означает, что даже если бы я мог отправить его обратно в тот же самом тот, который сделал запрос, это не гарантируется, что он все еще будет там, как только ответ вернется, но пользователь все еще может ждать ответа через другой экземпляр VertX.
В настоящее время я создаю GUID для каждого нового соединения, а затем, как только веб-узел подключится, сохраните обработчик websocket внутри хэш-карты с идентификатором GUID, а затем, когда BE хочет ответить, он выполняет fanout для всех экземпляров Vert.X..1, тот, который в настоящее время имеет правильный GUID в своем хэшмапе, может затем написать ответ пользователю. То же самое для обработки POST/GET таким образом.
псевдокод:
queue.handler { q ->
q.handler {
val handler = someMap.get(q.guid)
// only respond if handler exists
if (handler != null){
handler.writeResponse(someresponsemessagehere)
}
}
}
vertx.createHttpServer().websocketHandler { ws ->
val guid = generateGUID()
someMap.put(guid, ws)
ws.writeFinalTextFrame("guid=${guid}")
ws.handler {
val guid = extractGuid(it)
// send request to BE including generated GUID
sendMessageToBE(guid, "blahblah")
}
}.requestHandler { router.accept(it) }.listen(port)
Это однако означает, что если у меня есть 1000 приложений VertX работающих, что бэкенд необходим для разветвления его сообщения до 1000 внешнего интерфейса экземпляров, из которых только один будет воспользоваться сообщение.
VertX похоже, что он очень хорошо разбирается в асинхронных операциях, есть ли способ в VertX идентифицировать каждое подключение к веб-соединению вместо того, чтобы поддерживать карту GUID, сопоставленную с обработчиками/обработчиками websocket?
Также, ссылаясь на изображение, есть ли способ для V3 использовать сообщение, но все же быть в состоянии написать ответ обратно обработчику websocket, который в настоящее время подключен к V2?
Я не знаком с VertX, так что я может быть что-то, что в противном случае было бы очевидно, но почему бы не использовать 1..n очереди (один отсутствующий для каждого VertX (V)) или использовать очередь, которая поддерживает селектор, чтобы клиенты могли потреблять для них только сообщения (например, http://activemq.apache.org/how-do-i-consume-a-specific-message.html)? – mfulton26
Мы используем RabbitMQ, я не думаю, что RabbitMQ может это сделать - другими словами, специально потреблять конкретные сообщения из одной очереди. Чтобы получить маршрутизацию в 1000 очередей, вам нужно настроить обмен темы, обмен темы ограничен 255 темами, если я правильно помню.На самом деле я искал аналогичную функцию в RabbitMQ 2 года назад: https://stackoverflow.com/questions/25489301/only-consuming-messages-with-certain-headers-using-rabbitmq-and-springamqp#25491291 Если мы использовали ActiveMQ, возможно, это было бы решением. –
@JanVladimirMostert В качестве побочного вопроса, зачем вам нужна очередь (-а) в вашей «формуле»? Vert.x по умолчанию асинхронный, и если все ваши операции не блокируются и асинхронны, я думаю, что вам не нужна очередь ... а «back-end» также может быть и в виде вершин (любого типа). –