私はWebSocket接続を介してSlackチームに接続する必要があるSlackボットを作成しました。ボットは何千ものチームで使用される可能性があるため、最終的にはチームを複数のサーバーに分散させる必要があります。新しいチームは、初期のOAuth認証を処理するHTTPサーバーを介して追加されます。
私は次のことを達成するのに役立つソリューションを探しています。
サーバーが停止または再起動すると、そのサーバーが割り当てられていたすべてのチームを残りのサーバーに再度割り当てる必要があります。 Slackチームがサーバーにすぐに接続される限り、Slackチームへの接続が一時的にダウンしても問題ありません。
チームが追加されると、「ビジー」でないサーバーに割り当てられます。 Busyは、現在処理しているチームの数によって簡単に定義できます。
これをすべて、最小限のカスタムコードで記述したいと思います。
これまでのところ、私は次の解決策を検討しました:
1) ワークキュー RabbitMQを使用。ボットサーバーは、チームを獲得するために競争します。サーバーがダウンしたときにチームをキューに戻す確実な方法が必要ですが、これは問題ありません。
2)カスタムの「オーケストレーション」サービスを記述します。オーケストレーションサービスは、httpサーバーからチームを受け取り、サーバーのクラスターにチームをディスパッチします。サーバーがダウンしたときと、どのチームを再割り当てする必要があるかを追跡する必要があります。このようなサービスを確実に作成する方法がよくわからないので、これが単一障害点になります。
3)あなたの提案!
基本的に、負荷分散を実現する方法に関するアドバイスを探しています。あなたが提供した制限があっても、これはかなり広いトピックです。
考えられる解決策の1つ:
任意のクライアントが現在アクティブなサーバーのリストを取得するための何らかの手段があるという前提の下で、 Consistent Hashing または Rendezvous Hashing のバリエーションを使用できます。
簡単な例として、各サーバーを0から1の間の多数のランダムなバケット値にマッピングします。特定のクライアントについて、ある種のクライアントID(たとえば、クライアントのIPアドレス)を数値にハッシュし、それをサーバーに送信します選択したサーバーに最も近いバケット[1]。
このアプローチにはいくつかの利点があります。
このアプローチの欠点は、ランダムであることです。特にクライアントの数が少ない場合、負荷が均等に分散されないリスクがあります。
[1]この計算はラップします(そのため、ほとんどの議論が角度または円について話している理由です)が、これを無視することの影響はかなり小さいです。最も簡単な修正は、1+Min(bucket_value)
バケットを追加することです。基本的に、0.01は、バケットの最高値と最低値の偏りを少なくするために、0.5ではなく0.99に近いものとして扱う必要があります。