我一直在使用redis
作为我的nodejs
服务器的内存存储。
会议也通过redis进行管理。
目前我一直在做的是,每当我的服务器连接到它时,我都会刷新redis
,这样每当服务器启动时都没有会话
像这样:
redisClient.on('connect', function () {
redisClient.flushdb(function (err, succeeded) {
logger.debug("redis db cleared on startup--", succeeded); // will be true if successfull
});
});
我还将redis
用于其他一些数据存储,例如queue
。
但现在我想在我的服务器上实现群集。
我的问题是,如果我有4个cores
,我的服务器上将运行4个节点实例。
num_processes = require('os').cpus().length;
if (cluster.isMaster) {
console.log(`Master ${process.pid} is running`);
var workers = [];
// Helper function for spawning worker at index 'i'.
var spawn = function(i) {
console.log("spawing at index---",i);
workers[i] = cluster.fork();
console.log("----worker id-------", workers[i].id,"-------");
// Optional: Restart worker on exit
workers[i].on('exit', function(code, signal) {
console.log(`code is ${code} and signal is ${signal}`)
console.log(`worker ${workers[i].process.pid} died array index is ---${i}`);
console.log('respawning worker', i);
spawn(i);
});
workers[i].on('listening', () => {
workers[i].send({'index' : i });
});
};
// Spawn workers.
for (var i = 0; i < num_processes; i++) {
spawn(i);
} // Code to run if we're in a worker process
} else {
var redis = require('redis');
const sio_redis = require('socket.io-redis'),
redisClient = redis.createClient();
redisClient.on('connect', function () {
redisClient.flushdb(function (err, succeeded) {
logger.debug("redis db cleared on startup--", succeeded); // will be true if successfull
});
});
var RedisStore = require('connect-redis')(session);
const redisStore = new RedisStore({'host': 'localhost', 'port': 6379, 'client': redisClient});
var server = require('http').Server(app);
var listeningServer = server.listen(3002);
}
如果由于某种原因导致任何实例退出或死亡,它将清除redis
我不希望这种情况发生。在这种情况下我应该如何使用redis,以便清除与该实例对应的会话和数据?
答案 0 :(得分:2)
您可以检查当前进程是否为主进程。这样,它只会在您第一次启动应用时刷新。如果任何fork重新启动,那么它将不会刷新db。
redisClient = redis.createClient();
redisClient.on('connect', function() {
if (cluster.isMaster) {
redisClient.flushdb(function(err, succeeded) {
logger.debug("redis db cleared on startup--", succeeded); // will be true if successfull
});
}else{
logger.debug("Forked instance no need to flush redis db"); //
}
});
答案 1 :(得分:1)
基本上有两种解决方法我认为是理智的:
您说要在启动时清理会话数据。好吧,让会话不在内存中的一点是在会话中坚持他们,并保持你的实际应用服务器(Node.js应用程序)无状态。
你可以,例如在所有会话数据上设置过期密钥。所以每次你“保存”一个会话,你也会在那个会话上setex,甚至可以在你每次访问会话时延长这个TTL(所以,会话在上次触摸后12小时有效,或者其他什么)。或者,根据您的使用情况,会话中间件可以执行此操作,例如https://stackoverflow.com/a/45019589/162070
或者根本没有过期。
也许您只刷新会话,因为您希望有更改,而旧会话将无效。或者有明确的要求,即在每个新的部署上,您清理会话数据。无论如何,你将其分开。例如,您的server.js
作为您的应用,并且有一个单独的session-cleanup.js
文件,可以连接到redis,刷新和断开连接。然后像这样设置npm:
"scripts": {
"session.cleanup": "node lib/session-cleanup.js",
"start": "npm run session.cleanup && node lib/server.js",
...
}
这样,在运行server.js
并运行集群模式之前,您将首先清理会话。如果您的群集实例死亡并重生,则不会发生任何事情。
现在,每次重新部署时,都要清理它。或者甚至从“开始”中删除它,并让您的部署管道显式调用npm run session.cleanup
。您甚至可以在管理UI中公开一个按钮来在运行时执行此操作(这可能会让您退出:)),重点是,会话清理现在是服务器启动时的一个单独问题。