Nodejs redis做session必须得有断开重连机制。

Nodejs redis做session必须得有断开重连机制。

官方demo是这样:

    app.use(session({
        store: new RedisStore(options),
        secret: 'keyboard cat'
    }));

其实应该要这样:

	var sessionMiddleware;
    var createMiddlware = _.throttle(function() {
        var store = new RedisStore(redisConfig);

        store.on('disconnect', function() {
            createMiddlware();
        });

        app.set('sessionStore', store);

        settings.store = store;
        sessionMiddleware = session(settings);

    }, 2000);

    createMiddlware();

    return function(req, res, next) {
        sessionMiddleware.apply(this, arguments);
    }

Node.js有些坑很隐蔽,一不小心就很容易掉下去~~


4 回复

当然可以!在使用 Node.js 和 Redis 进行会话管理时,确保连接的稳定性和可靠性是非常重要的。Redis 可能会因为各种原因断开连接,因此我们需要实现一个自动重新连接的机制。

以下是一个示例代码,展示了如何为 Redis 创建一个会话存储,并在断开连接时自动重新连接:

示例代码

const express = require('express');
const session = require('express-session');
const RedisStore = require('connect-redis')(session);
const _ = require('lodash');

const app = express();

// 配置 Redis 连接选项
const redisConfig = {
    host: 'localhost',
    port: 6379,
};

let sessionMiddleware;

// 创建中间件函数,限制每2秒调用一次
var createMiddleware = _.throttle(function () {
    const store = new RedisStore(redisConfig);

    // 监听 Redis 断开事件
    store.on('disconnect', function () {
        console.log('Redis connection lost. Attempting to reconnect...');
        createMiddleware();
    });

    // 设置 session 存储
    app.set('sessionStore', store);

    // 配置 session 中间件
    const settings = {
        store: store,
        secret: 'keyboard cat',
        resave: false,
        saveUninitialized: false,
    };

    sessionMiddleware = session(settings);
}, 2000);

createMiddleware();

app.use(function (req, res, next) {
    sessionMiddleware(req, res, next);
});

app.get('/', (req, res) => {
    req.session.views = (req.session.views || 0) + 1;
    res.send(`You have viewed this page ${req.session.views} times.`);
});

app.listen(3000, () => {
    console.log('Server is running on port 3000');
});

解释

  1. 引入必要的模块

    • express:用于创建 Web 应用。
    • session:用于创建会话中间件。
    • RedisStore:从 connect-redis 模块中引入 Redis 存储。
    • _:使用 lodashthrottle 函数来限制 createMiddleware 函数的调用频率。
  2. 配置 Redis 连接选项

    • redisConfig 对象包含了 Redis 服务器的主机名和端口号。
  3. 创建中间件函数

    • createMiddleware 函数使用 _.throttle 来限制每2秒调用一次。
    • 在每次调用时,创建一个新的 RedisStore 实例。
    • 监听 disconnect 事件,当 Redis 连接断开时,重新调用 createMiddleware 函数以尝试重新连接。
  4. 设置 session 存储

    • RedisStore 实例设置为应用的 sessionStore
    • 配置 sessionMiddleware 使用这些设置。
  5. 应用中间件

    • 在应用中使用 sessionMiddleware 中间件。

通过这种方式,我们确保了即使 Redis 连接断开,系统也能自动重新连接并恢复会话管理功能。


这个redis client本身就会做重连的把

哇哈哈

为了确保Redis与Node.js应用之间的会话持久化能够可靠地工作,并且在网络断开时能够自动恢复,确实需要实现断开重连机制。上述代码片段展示了如何使用throttle函数来限制重新创建中间件的频率,以防止在频繁断连的情况下导致不必要的资源消耗。

以下是改进版的示例代码,其中添加了断开重连机制:

const express = require('express');
const session = require('express-session');
const RedisStore = require('connect-redis')(session);
const _ = require('lodash');

const app = express();

var sessionMiddleware;
var createMiddleware = _.throttle(function() {
    const store = new RedisStore(redisConfig);

    // 监听断开事件
    store.on('disconnect', function() {
        console.log("Redis disconnected, attempting to reconnect...");
        createMiddleware();
    });

    // 设置store到app中,便于以后使用
    app.set('sessionStore', store);

    const settings = {
        store: store,
        secret: 'keyboard cat',
        resave: false,
        saveUninitialized: false
    };

    sessionMiddleware = session(settings);
}, 2000);

createMiddleware();

// 使用中间件
app.use(function(req, res, next) {
    sessionMiddleware(req, res, next);
});

// 启动服务器
app.listen(3000, () => {
    console.log('Server started on port 3000');
});

在这段代码中:

  1. _.throttle用于限制在Redis断开连接后重新创建中间件的频率。
  2. store.on('disconnect', ...)监听Redis断开连接的事件,并在此时调用createMiddleware重新创建中间件。
  3. app.set('sessionStore', store);store对象保存到应用实例上,方便后续可能的操作或调试。

这样做可以保证即使Redis连接断开,应用也能自动恢复会话管理功能。

回到顶部