2016-12-18 5 views
2

ロードバランサ(LB)が1..n VertX(V)インスタンスの前にあり、各VertXインスタンスがキュー(Q)に接続されていて、1があるとします。 .mバックエンド(BE)。VertXでのリクエストに対応するレスポンスハンドラ

ユーザーがポスト要求を行うボタンまたはWebソケットを開くボタンをクリックすると、ロードバランサは要求をキューに送信するVertXインスタンスの1つに要求を転送し、バックエンドの1つがメッセージを消費します応答を返送する。正しいVertXインスタンスがそれを消費すると、レスポンスハンドラをルックアップしてユーザーに応答を書き込むことができます。間違ったVertXインスタンスがそれを消費した場合、応答を書き込むレスポンスハンドラがなくなり、ユーザーは無期限に待機します応答。それはだ、

またenter image description here

は、V2が死ぬと、ロードバランサは、私が要求を行ったとまったく同じものに戻ってそれを送ることができても、意味V1にユーザーを再接続:

このスケッチを参照してください。応答が返ってもまだそこにいることは保証されていませんが、ユーザーは別のVertXインスタンスを介して応答を待っている可能性があります。

私が現在行っていることは、新しい接続ごとにGUIDを生成し、websocketが接続するとすぐにGUIDに対してハッシュマップ内にwebsocketハンドラを格納し、BEが応答したいときにすべての1..n VertXインスタンスにファンアウトすると、現在ハッシュマップに正しい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に慣れていないよので、私はそれ以外の場合は明らかであろう何かが欠落している可能性がありますが、なぜ1..nのキュー(各VERTXための1つを使用しません(V)インスタンス)、またはセレクタをサポートするキューを使用して、クライアントがメッセージを消費できるようにします(例: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はデフォルトでは非同期で、すべての操作が非ブロック型で非同期であると仮定すると、キューが本当に必要ないと思います。また、「バックエンド」も(任意のタイプの)頂点になる可能性があります。 –

答えて

2

ダイアグラムに欠けているものは、Vertx EventBusです。

基本的に、あなたのV1は... Vnのが相互接続されていることを前提とすることができます

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

はのVaがVbのために意図されたアウトバウンドQメッセージ(赤線)を、受信したと仮定しましょう。
それは、その後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 
    } 
}); 
+0

あなたの提案に基づいて、V1からV1000が起動し、それ自身のUUIDを生成し、それぞれが存在する他のインスタンスにGUIDで通知します。インスタンスV777がキューにメッセージを送信すると、それ自体のUUIDが含まれるため、インスタンスV367がレスポンスを消費すると、そのレスポンスは実際にV777用であったことがわかり、V777およびV777に転送されてサイクルを完了します。 ユーザが接続を失い、V12またはV777のダイに再接続すると、V367はメッセージを正常に送信せず、V367はV1、nope、V2、nope ...、V12、yepで開始してサイクルを完了します。 –

+0

Dockerコンテナ間でVertX Eventbusを使用できますか?私はそれが動作するための正しいポートを開く必要があると思いますか? –

+0

あなたは考えを持っています。ドッカーについては、これをチェックしてください(元のGoogleの会話も参照してください):http://stackoverflow.com/questions/39812848/how-do-i-configure-vert-x-event-bus-to-work-across - ドッキング・コンテナのクラスタ –

関連する問題