2

他の誰かが以前にこの問題に遭遇したことを願っています:

問題の説明

redis-store モジュールを使用するように Socket.IO を構成しました。これは、ルームへのブロードキャスト/イベントの発行時にノード インスタンスの同期を維持するのに最適です。ただし、私は障害点をテストしており、redis インスタンスが再起動されると、ノード サーバーが他のノードからのメッセージの受信を停止するようです。

これがsocket.ioクライアントのセットアップ方法です(このコードの前にredis接続が作成されます)

// Setup the socket server for web clients
self.ioServer = socketIo.listen(9000);
self.ioServer.enable('browser client minification');    // send minified client
self.ioServer.set('log level', 3);

self.ioServer.set( 'store', new socketIo.RedisStore ({
        redisPub: self.redisPub, 
        redisSub: self.redisSub, 
        redisClient: self.redisStore
    })
);

本質的に、socket.io redis-store は、redis がクラッシュ/再起動するたびに、redis を介して他のノード サーバーにイベントを送信し続けることができません。

redis サーバーに再接続するために必要な特別な手順はありますか? この問題の解決策を見つけるためにかなりの時間を費やしましたが、うまくいきませんでした。

よろしく、

-ライアン

4

2 に答える 2

3

誰かがここに興味を持っている場合は、上記の問題に対して私が実装した修正があります:

システムは socket.io ノードにクラスターを使用しているため、redis 接続 (reidsPub、redisSub など) で「終了」イベントをキャッチし、フォークされたプロセスを強制終了しています。マスター プロセスで、子プロセスの終了をキャッチし、再フォークします。

余談ですが、redis と socket.io の redis-store に関するもう 1 つの厄介な問題も発見しました。redis とデータが交換されない場合、redis 接続は最終的にタイムアウトになります。これを解決するには、15 秒ごとに実行され、上記のすべての redis 接続に対して redis とデータを交換する単純なキープアライブ機能を実装する必要がありました。

通常、デフォルトの redis クライアント再接続ロジックを使用しても問題ありませんが、redis サーバーが実際に再起動したのか、それとも単なるタイムアウトだったのかを知る方法がないためです。

于 2012-07-16T02:01:09.153 に答える
1

redis-store の実装については詳しく説明していません。Redis を使用した pub-sub がデフォルトでディスクにバックアップされるとは思わず、サーバーを再起動するとメッセージが失われます。redis-store が既に同じことを行っていない限り、pub-sub の使用に加えて、リストまたはおそらくソートされたセットのいずれかを使用してメッセージを保存できます。

デフォルトで redis-store によって提供されない場合は、リスト/ソート済みセットが大きくなりすぎてパフォーマンスに悪影響を及ぼさないようにする必要があります。ACID 保護のために MULTI/EXEC (および ACK メッセージを調べる) トランザクションの使用を検討し、サブスクライバーによって処理/消費されない限りメッセージが削除されないようにすることができます。

永続的な (ディスクでバックアップされた) メッセージング キュー/トピックを提供する ActiveMQ などの他のメッセージング サーバーをいつでも調べることができます。

それが役に立てば幸い。

于 2012-07-09T03:17:44.850 に答える