2016-12-18 6 views
2

로드 밸런서 (LB)가 1..n VertX (V) 인스턴스 앞에 있고 각 VertX 인스턴스가 대기열 (Q)에 연결되어 있고 1이 있다고 가정 해 봅니다. .m 백엔드 (BE).VertX에서 요청이있는 응답 처리기

사용자가 게시물 요청을하거나 심지어 웹 소켓을 열 단추를 클릭하면 부하 분산 장치가 큐에 요청을 발생시키는 VertX 인스턴스 중 하나에 요청을 전달하고 백 엔드 중 하나가 메시지를 소비합니다 응답을 되돌려 보냅니다. 올바른 VertX 인스턴스가이를 소비하면 응답 핸들러를 검색하여 사용자에게 응답을 쓸 수 있습니다. 잘못된 VertX 인스턴스가이를 소비하면 응답을 작성하는 응답 핸들러가 없으므로 사용자는 무기한 기다립니다. 응답. 그것의,

또는 enter image description here

는, V2가 죽으면 부하 분산 내가 요청을 동일한 하나에 다시 보낼 수 있습니다 경우에도 의미 V1로 사용자를 다시 연결 :

이 스케치를 참조하십시오 응답이 돌아 오더라도 여전히 거기에있을 수는 없지만 사용자가 다른 VertX 인스턴스를 통해 응답을 기다리고있을 수 있습니다.

내가 현재하고있는 일은 각각의 새로운 연결에 대해 GUID를 생성 한 다음 websocket이 연결 되 자마자 webSocket 처리기를 GUID에 대한 hashmap 내에 저장 한 다음 BE가 응답하려고 할 때 모든 1..n VertX 인스턴스에 fanout을 보내면 현재 해시 맵에 올바른 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 개 프론트 엔드 인스턴스의 메시지를 팬 아웃 할 필요가 있음을, 실행하는 1000 VertX의 응용 프로그램이있는 경우 메시지.

VertX는 이미 비동기 작업을 잘 처리하고있는 것처럼 보이지만 Vertex에서 websocket 핸들러/포스트 핸들러에 매핑 된 GUID 맵을 유지 관리하는 대신 각 websocket 연결을 식별 할 수있는 방법이 있습니까?

또한 그림을 참조하면 V3가 메시지를 소비하지만 현재 V2에 연결된 websocket 처리기에 응답을 쓸 수 있습니까?

+1

내가 VertX에 익숙하지 않아요 그래서 각 VertX에 대한 그렇지 않으면 명백 할 것이다 그러나 왜 1..N 큐를 사용하지 뭔가 (하나를 누락 될 수 있습니다 (예 : http://activemq.apache.org/how-do-i-consume-a-specific-message.html) 선택기를 지원하는 대기열을 사용하여 클라이언트가 메시지를 소비 할 수 있습니까? – mfulton26

+0

우리는 RabbitMQ를 사용하고 있습니다. RabbitMQ가 그렇게 할 수 있다고 생각지 않습니다. 즉, 특정 큐에서 특정 메시지를 특별히 소비한다고 저는 생각하지 않습니다. 1000 대기열로 라우팅하려면 주제 교환을 설정해야합니다. 정확하게 기억한다면 주제 교환은 255 주제로 제한됩니다.사실 2 년 전 RabbitMQ에서 비슷한 기능을 찾고있었습니다. https://stackoverflow.com/questions/25489301/only-consuming-messages-with-certain-headers-using-rabbitmq-and-springamqp#25491291 ActiveMQ를 사용하고 있었는데 어쩌면 해결책이었을 것입니다. –

+1

@JanVladimirMostert 부차적 질문으로 왜 "수식"에 대기열이 필요합니까? Vert.x는 기본적으로 비동기이며 모든 작업이 비 블로킹 및 비동기라고 가정 할 때 대기열이 실제로 필요하지는 않습니다. "백엔드"는 (모든 유형의) verticle 일 수 있습니다. –

답변

2

다이어그램에서 누락 된 부분은 Vertx EventBus입니다.

은 기본적으로 당신이 당신의 V1이 ... 내지 Vn이 서로 연결되어 있다고 가정 할 수 있습니다 :

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

이의이 버지니아가 아웃 바운드 Q 메시지 (레드 라인)를 수신한다고 가정하자 그는 VB를위한 것입니다.
그런 다음 VB 사용 EventBus로 보내야합니다 :

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 
    } 
}); 
+0

당신의 제안에 따라 V1 to V1000이 시작되어 스스로 UUID를 생성합니다. 각 인스턴스는 GUID를 사용하여 존재하는 다른 인스턴스를 알려줍니다. 인스턴스 V777이 대기열로 메시지를 전송할 때 자체 UUID를 포함하므로 인스턴스 V367이 응답을 사용하면 실제로 응답이 V777 용 이었음을 알게되고 V777 및 V777로 전달한 다음 해당주기를 완료합니다. 사용자가 연결이 끊어지고 V12 또는 V777이 다시 연결되면 V367이 메시지를 성공적으로 보내지 않고 V367이 V1, nope, V2, nope ..., V12, yep에서 시작하여주기를 완료합니다. –

+0

Docker 컨테이너에서 VertX Eventbus를 사용할 수 있습니까? 나는 그것이 작동하도록 올바른 포트를 열어야한다고 생각 했나요? –

+0

아이디어가 있습니다. Docker에 관해서는 이것을 확인하십시오. (원래 Google 대화를 참조하십시오) : http://stackoverflow.com/questions/39812848/how-do-i-configure-vert-x-event-bus-to-work-across - 클러스터 오브 도커 - 컨테이너 –