Exponential Backoff(指数バックオフ)とは
Exponential Backoff とはリトライの仕組みの一種で、リトライ間隔を徐々に広げていくアルゴリズムになります。1秒→3秒→9秒→27秒... のように、指数関数的にリトライ間隔を広げることでアプリケーションの信頼性を向上させて、開発者の運用コストを削除します。
アルゴリズム
WebSocket接続処理のソースコード全体(実装例)
const endpoint = 'ws://localhost:8080';
// 指数バックオフ設定値
let initialReconnectDelay = 1000;
let currentReconnectDelay = initialReconnectDelay;
let maxReconnectDelay = 16000;
function wsConnection(endpoint) {
ws = new WebSocket(endpoint);
let s = (l) => console.log(l);
// コネクション確立
ws.onopen = (m) => {
s(' CONNECTED');
currentReconnectDelay = initialReconnectDelay;
};
// メッセージ受信
ws.onmessage = (m) => s(' RECEIVED: ' + JSON.stringify(m.data, null, 3));
// コネクションエラー
ws.onerror = (e) => s(' ERROR');
// コネクションクローズ (クローズしたら再接続)
ws.onclose = (e) => {
s(' CONNECTION CLOSED');
setTimeout(
function () {
reconnectToWebsocket();
}.bind(this),
currentReconnectDelay + Math.floor(Math.random() * 3000),
); // ランダム指数バックオフ
};
reconnectToWebsocket = () => {
if (currentReconnectDelay < maxReconnectDelay) {
currentReconnectDelay *= 2;
s(' RECONNECTION...');
wsConnection(endpoint);
}
};
}
wsConnection(endpoint);
バックオフをランダムにする
バックオフをランダムにすることのメリットは 10,000 のクライアントが接続されているときにサーバーがダウンし、すぐに復旧した場合はどうなるでしょうか? そうです、これらのクライアントはすべて、まったく同じ秒で再接続を試みます。これにより、サーバーでスパイクが発生し、最悪の場合はサーバーダウンする可能性があります。
このスパイクを防ぐために、バックオフ アルゴリズムをランダムにします。これにより、すべてのクライアントが同時に再接続するわけではなくなり、サーバーを急上昇させることなく、すべてのクライアントが正常に再接続できるようになります。
(これをジッターというらしい)
参考サイト