匹配响应处理程序与VertX中的请求

时间:2016-12-18 20:26:33

标签: java architecture kotlin vert.x

假设我在1..n VertX(V)实例前面有一个负载均衡器(LB),每个VertX实例都连接到一个队列(Q),我有1..m后端(BE)。

用户点击发出帖子请求的按钮甚至打开网络套接字,负载均衡器将请求转发给其中一个VertX实例,该实例向队列发出请求,其中一个后端使用该消息,发回一个回复;如果正确的VertX实例使用它,它可以查找响应处理程序并向用户写入响应,如果错误的VertX实例使用它,则不会有响应处理程序来写入响应,用户将无限期地等待回应。

见这个草图:

enter image description here

或者,V2死机并且负载均衡器将用户重新连接到V1,这意味着即使我可以将其发送回发出请求的完全相同的一个,但是一旦响应返回,它不能保证仍然在那里,但是用户可能仍在等待通过另一个VertX实例的响应。

我目前正在做的是为每个新连接生成一个GUID,然后一旦websocket连接,就将websocket处理程序存储在一个针对GUID的hashmap中,然后当BE想要响应时,它会进行扇出对于所有1..n VertX实例,当前在其hashmap中具有正确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中识别每个websocket连接而不必维护映射到websocket处理程序/后处理程序的GUID映射?

另外,参考图片,有没有办法让V3使用该消息,但是仍然可以将响应写回当前连接到V2的websocket处理程序?

1 个答案:

答案 0 :(得分:2)

您的图表中缺少的是Vertx EventBus。

基本上你可以假设你的V1 ... Vn是互联的:

V1<->V2<->...<->Vn

我们假设Va收到你的出站Q消息(红线),用于Vb 然后它应该使用EventBus将其发送到Vb:

eventBus.send("Vb UUID", "Message for Vb, also containing WebSocket UUID", ar -> {
  if (ar.succeeded()) {
    // All went well
  }
  else {
    // Vb died or has other problems. Your choice how to handle this
  }
});