Nodejs的session模块是怎么回收垃圾的?
Nodejs的session模块是怎么回收垃圾的?
用的express框架做了个网站, session用的connect-mongodb中间件,才四天表就有29220条数据。并且还在迅猛增加,感觉要爆表的节奏。
connect-mongodb每分钟会遍历一次数据库,把过期的session数据删除。 你应该是没有设置maxAge参数吧。这时候session的有效期是两周!所以你的数据两周内会一直增加!
Node.js 的 Session 模块是如何回收垃圾的?
在使用 Node.js 和 Express 框架时,Session 管理是一个常见的需求。为了管理 Session 数据,我们通常会使用一些中间件,比如 connect-mongodb
,它将 Session 存储在 MongoDB 中。然而,随着时间的推移,这些 Session 数据会不断累积,可能会导致数据库变得庞大,影响性能。
如何处理垃圾回收?
在 connect-mongodb
中,你可以通过设置过期时间(TTL)来自动清理过期的 Session 数据。TTL 是一个索引属性,可以让 MongoDB 自动删除超过指定时间的数据。具体步骤如下:
-
创建 TTL 索引: 在 MongoDB 中,你需要为 Session 集合创建一个 TTL 索引,并指定一个合理的过期时间。
-
配置
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');
});
解释
-
创建 TTL 索引: 在 MongoDB 中,你需要手动为
sessions
集合创建一个 TTL 索引。可以在 MongoDB 命令行工具中运行以下命令:db.sessions.createIndex({ "expires": 1 }, { expireAfterSeconds: 0 })
-
配置
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 的 touchAfter
和 autoRemove
配置项可以帮助你自动清理过期 Session,而手动清理则提供了额外的灵活性。
以上代码应放置在你的 Express 应用启动逻辑中,以确保每次应用启动时正确配置 connect-mongodb
。