Nodejs的session模块是怎么回收垃圾的?

Nodejs的session模块是怎么回收垃圾的?

用的express框架做了个网站, session用的connect-mongodb中间件,才四天表就有29220条数据。并且还在迅猛增加,感觉要爆表的节奏。

7 回复

connect-mongodb每分钟会遍历一次数据库,把过期的session数据删除。 你应该是没有设置maxAge参数吧。这时候session的有效期是两周!所以你的数据两周内会一直增加!


Node.js 的 Session 模块是如何回收垃圾的?

在使用 Node.js 和 Express 框架时,Session 管理是一个常见的需求。为了管理 Session 数据,我们通常会使用一些中间件,比如 connect-mongodb,它将 Session 存储在 MongoDB 中。然而,随着时间的推移,这些 Session 数据会不断累积,可能会导致数据库变得庞大,影响性能。

如何处理垃圾回收?

connect-mongodb 中,你可以通过设置过期时间(TTL)来自动清理过期的 Session 数据。TTL 是一个索引属性,可以让 MongoDB 自动删除超过指定时间的数据。具体步骤如下:

  1. 创建 TTL 索引: 在 MongoDB 中,你需要为 Session 集合创建一个 TTL 索引,并指定一个合理的过期时间。

  2. 配置 connect-mongodb: 在你的 Express 应用中配置 connect-mongodb,使其能够使用这个 TTL 索引。

示例代码

const express = require('express');
const session = require('express-session');
const MongoDBStore = require('connect-mongodb-session')(session);

// 创建 MongoDB 连接
const store = new MongoDBStore({
  uri: 'mongodb://localhost:27017/mydatabase',
  collection: 'sessions',
  expires: 86400 * 7 // 设置 Session 过期时间为一周
});

// 错误处理
store.on('error', function(error) {
  console.error(error);
});

const app = express();

app.use(session({
  secret: 'mysecretkey',
  cookie: { maxAge: 86400 * 7 }, // 设置 Cookie 过期时间为一周
  store: store,
  resave: false,
  saveUninitialized: false
}));

app.get('/', (req, res) => {
  res.send(`Session ID: ${req.session.id}`);
});

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

解释

  1. 创建 TTL 索引: 在 MongoDB 中,你需要手动为 sessions 集合创建一个 TTL 索引。可以在 MongoDB 命令行工具中运行以下命令:

    db.sessions.createIndex({ "expires": 1 }, { expireAfterSeconds: 0 })
    
  2. 配置 connect-mongodb: 在上面的代码中,connect-mongodb-session 中间件被用来创建一个存储对象 store,并将它传递给 express-session 中间件。expires 参数用于设置 Session 的过期时间,这里设置为一周(86400 秒 * 7 天)。

通过这种方式,MongoDB 会自动删除超过一周的 Session 数据,从而有效地进行垃圾回收,避免数据库变得过大。

[@eeandrew](/user/eeandrew) “有效期是两周” 我看了源码,搜遍了谷歌、百度都没找到,大哥你可别骗我

cookie.maxAge: 默认值null,表示当浏览器关闭后cookie被删除。

Note: By connect/express's default, session cookies are set to expire when the user closes their browser (maxAge: null). In accordance with standard industry practices, connect-mongo will set these sessions to expire two weeks from their last 'set'. You can override this behavior by manually setting the maxAge for your cookies -- just keep in mind that any value less than 60 seconds is pointless, as mongod will only delete expired documents in a TTL collection every minute.

[@eeandrew](/user/eeandrew) 我用的是connect-mongodb ,没想到还有connect-mongo。不过我已经改了源码,maxAge 为 null 的话 两天后自动过期。

在使用 connect-mongodb 中间件管理 Session 的情况下,Session 数据会存储在 MongoDB 中。为了有效管理和回收垃圾(即不再活跃的 Session),可以采取以下几种措施:

1. 设置过期时间

在初始化 connect-mongodb 时,可以通过配置项设置 Session 的过期时间。这样 MongoDB 会自动清理过期的 Session 记录。

const MongoStore = require('connect-mongo')(session);

app.use(session({
  store: new MongoStore({
    url: 'mongodb://localhost/mydatabase',
    touchAfter: 24 * 3600, // 触发 Session 更新的时间间隔(秒)
    collection: 'sessions',
    autoRemove: 'interval', // 自动删除策略
    autoRemoveInterval: 1 // 自动删除间隔时间(小时)
  }),
  secret: 'your_secret_key',
  resave: false,
  saveUninitialized: false
}));

2. 手动清理

除了自动清理外,也可以定期手动清理 MongoDB 中的 Session 数据。可以编写一个定时任务来执行清理操作。

const sessionCollection = db.collection('sessions');

function cleanUpSessions() {
  const expirationTime = new Date(Date.now() - (24 * 60 * 60 * 1000)); // 一天前的时间
  sessionCollection.deleteMany({ expires: { $lt: expirationTime } })
    .then(result => console.log(`Deleted ${result.deletedCount} expired sessions`))
    .catch(err => console.error('Error cleaning up sessions:', err));
}

// 每天执行一次清理
setInterval(cleanUpSessions, 24 * 60 * 60 * 1000);
cleanUpSessions(); // 立即执行一次清理

总结

通过上述配置,你可以有效地管理 Session 数据并防止数据库中的 Session 数据过多。MongoDB 的 touchAfterautoRemove 配置项可以帮助你自动清理过期 Session,而手动清理则提供了额外的灵活性。

以上代码应放置在你的 Express 应用启动逻辑中,以确保每次应用启动时正确配置 connect-mongodb

回到顶部