JavaScriptのランダム指数バックオフアルゴリズムを実装する方法★


サービスに再接続するときにランダム化と指数関数バックオフアルゴリズムを使用して、クラッシュ後にサーバー上の突然のスパイクを防ぐことができます.
たとえば、10.000クライアントが接続されているWebSocketサーバーを持っていることを想像してください.お使いのサーバーがクラッシュするが、かなり早く戻ってくる.再接続スクリプトを以下のように実装しているので、これは素晴らしいことです.
function connect() {
  ws = new WebSocket("ws://localhost:8080");
  ws.addEventListener('close', connect);
}
すべてのあなたのクライアントが自動的に再接続され、誰も、サーバーが正しいことを知っている?しかし、この簡単なアプローチにはいくつか問題があります.

バックオフ指数
サーバが終了するとすぐに、クライアントは再接続しようとします.これは、不要な要求の多くを作成し、ネットワークの混雑を引き起こす可能性があります.これは単に再接続しようとする間にタイマーで解決することができます.
このタイムアウトは、時間あたりのクライアントごとの再接続試行を制限します.しかし、あなたができるだけ早くクライアントを再接続したいのを切断した直後に、切断の理由はいくつかのローカルネットワークエラー、短い停電、またはサーバーの速い再ロードであるかもしれません.しかし、最初の試みが失敗するとき、接続エラーが回復するのに数秒より長くかかる何かに関連しているのは、よりたぶん可能になります.したがって、再接続しようとすると同じレートでサーバーをヒットし続ける必要はありません.
これは指数関数的バックオフアルゴリズムが入るところです.各試行の後に指数関数的に遅延を増加させることによって、スタート時にできるだけ速く再接続しようとしている間に、より高い最大値への間隔を徐々に設定することができます.
var initialReconnectDelay = 1000;
var currentReconnectDelay = initialReconnectDelay;
var maxReconnectDelay = 16000;

function connect() {
    ws = new WebSocket("ws://localhost:8080");
    ws.addEventListener('open', onWebsocketOpen);
    ws.addEventListener('close',  onWebsocketClose);
}

function onWebsocketOpen() {
    currentReconnectDelay = initialReconnectDelay;
}

function onWebsocketClose() {
    ws = null;
    setTimeout(() => {
        reconnectToWebsocket();
    }, currentReconnectDelay);
}

function reconnectToWebsocket() {
    if(currentReconnectDelay < maxReconnectDelay) {
        currentReconnectDelay*=2;
    }
    connect();
}

ランダムにする
だから今、私たちのクライアントは、彼らの再接続しようとしているが良いですが、何が起こるかは、サーバーがダウンしてすぐにバックアップ10.000クライアントが接続されているときに発生しますか?そうです、それらのクライアントのすべては、正確に同じ第2で再接続しようとします.これは、サーバー上でスパイクを引き起こす可能性があります悪いケースでそれを戻す.
このスパイクを防ぐためにバックオフアルゴリズムをランダムにすることができる.だから、すべてのクライアントが同じ瞬間に再接続します.これは優雅にすべてのクライアントのサーバーをスパイクせずに再接続できるようになります.
function onWebsocketClose() {
    ws = null;
    // Add anything between 0 and 3000 ms to the delay.  
    setTimeout(() => {
        reconnectToWebsocket();
    }, currentReconnectDelay + Math.floor(Math.random() * 3000)));
}
もちろん、あなたのサーバーの容量と同時クライアントに基づいて、特定のユースケースに番号を微調整することができます.
それは、あなたが取ったか、共有する価値がある別のアプローチを知っているならば、それをしてください!
How to implement a random exponential backoff algorithm in Javascript年には、Which Devが初めて登場した.