node.js 在生产中使用 MemoryStore

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10760620/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 15:46:01  来源:igfitidea点击:

Using MemoryStore in production

node.js

提问by Milan Babu?kov

Today I ran my Node.js application in "production" mode for the first time and got this warning:

今天我第一次在“生产”模式下运行我的 Node.js 应用程序并收到以下警告:

Warning: connection.session() MemoryStore is not
designed for a production environment, as it will leak
memory, and obviously only work within a single process.

I only need to run a single process, but what should I use instead? I want my sessions to reside in RAM for fast access. I also want to be able to discard all the sessions by simply shutting down the Node app.

我只需要运行一个进程,但我应该使用什么?我希望我的会话驻留在 RAM 中以便快速访问。我还希望能够通过简单地关闭 Node 应用程序来丢弃所有会话。

It seems an overkill to install Redis, MongoDB or another database just for this simple task. I also don't understand why is MemoryStore included in Node when it should not really be used?

仅仅为了这个简单的任务而安装 Redis、MongoDB 或其他数据库似乎是一种矫枉过正。我也不明白为什么不应该真正使用 MemoryStore 时将它包含在 Node 中?

采纳答案by alessioalex

MemoryStore is just for (rapid) development mode, because if your app restarts (process dies) you will lose all the session data (that resided in the memory of that process).

MemoryStore 仅适用于(快速)开发模式,因为如果您的应用程序重新启动(进程终止),您将丢失所有会话数据(驻留在该进程的内存中)。

If you don't want to use a database, use encrypted cookie storage instead.

如果您不想使用数据库,请改用加密的 cookie 存储。

http://www.senchalabs.org/connect/cookieSession.html

http://www.senchalabs.org/connect/cookieSession.html

回答by Milan Babu?kov

Ok, after talking to Connect developers, I got more information. There are two things considered memory leaks here:

好的,在与 Connect 开发人员交谈后,我获得了更多信息。这里有两件事被认为是内存泄漏:

  1. problem with JSON parsing which is already fixed in recent versions
  2. the fact that there is no cleanup of expired sessions if the users never access them (i.e. the only cleanup is on-access)
  1. JSON 解析问题已在最新版本中修复
  2. 如果用户从不访问过期会话,则不会对其进行清理(即唯一的清理是在访问时)

The solution seems to be rather simple, at least this is what I plan to do: use setInterval to periodically clean up the expired sessions. MemoryStore provides all() to get the list, and we can use get() to force reading and thus expire them. Pseudo-code:

解决方案似乎相当简单,至少这是我打算做的:使用 setInterval 定期清理过期的会话。MemoryStore 提供了 all() 来获取列表,我们可以使用 get() 来强制读取,从而使它们过期。伪代码:

function sessionCleanup() {
    sessionStore.all(function(err, sessions) {
        for (var i = 0; i < sessions.length; i++) {
            sessionStore.get(sessions[i], function() {} );
        }
    });
}

Now just call sessionCleanup periodically via setInterval() and you have automatic garbage collection for expired sessions. No more memory leaks.

现在只需通过 setInterval() 定期调用 sessionCleanup ,您就可以对过期会话进行自动垃圾收集。没有更多的内存泄漏。

回答by igneosaur

So the accepted answer to this is [edit: was] pretty much a hack, and the others are just recommending using a database which I think is overkill.

因此,对此的公认答案是 [edit: was] 几乎是一个黑客,而其他人只是建议使用我认为是矫枉过正的数据库。

I had the same problem and just replaced express-session with cookie-session.

我遇到了同样的问题,只是用cookie-session替换了 express -session

To do this simply install cookie-session:

为此,只需安装cookie-session

npm install cookie-session

Then in your app.js, find where express-sessionis being used and replace with cookie-session.

然后在您的 中app.js,找到express-session正在使用的位置并替换为cookie-session.

app.use(require('cookie-session')({
    // Cookie config, take a look at the docs...
}));

You may need to change some other things, for me is was a simple swap-out-bobs-your-uncle-no-harm-done.

你可能需要改变一些其他的东西,对我来说是一个简单的交换,你的叔叔没有伤害。

回答by Dovev Hefetz

This module was designed to deal with the memory leak issue. https://www.npmjs.com/package/session-memory-store

该模块旨在处理内存泄漏问题。 https://www.npmjs.com/package/session-memory-store

The accepted answer may be fine. However, since this question shows up high in the list of search results I figured I would include this in case it helps anyone else.

接受的答案可能没问题。但是,由于这个问题在搜索结果列表中的位置很高,我想我会包括它,以防它对其他人有帮助。

回答by Kristian

I think the consensus around the web is that the right way would be to indeed use a DB for that, but if you're positive you don't want to do that, then suppress the warning -- the warning is not law.

我认为网络上的共识是,正确的方法是确实为此使用数据库,但如果您确定不想这样做,则取消警告——警告不是法律。

However, since you and I both agree that the memory leak is a real problem, it is hard to justify saying redis is overkill, since it would solve your problem.

但是,由于您和我都同意内存泄漏是一个真正的问题,因此很难证明 redis 是矫枉过正,因为它可以解决您的问题。

I also don't understand why is MemoryStore included in Node when it should not really be used

我也不明白为什么不应该真正使用 MemoryStore 时将它包含在 Node 中

that is a great point -- but to that I would say that node iself has only recently itself become production ready. Some people would not agree with the notion that it is at all.

这是一个很好的观点 - 但对此我想说节点本身最近才成为生产就绪。有些人根本不同意这种说法。

回答by huggie

The alternative is to use Redis or Mongo as a store. With Mongo you use the express-session-mongomodule.

另一种方法是使用 Redis 或 Mongo 作为存储。使用 Mongo,您可以使用express-session-mongo模块。

There is an advice to remove stale sessions with an indexing option:

有一个建议可以使用索引选项删除陈旧的会话:

var MongoStore = require('express-session-mongo');
app.use(express.session({ store: new MongoStore() }));

db.sessions.ensureIndex( { "lastAccess": 1 }, { expireAfterSeconds: 3600 } )

Since stale sessions are removed by the database itself, Express session doesn't need to handle the cleanup by itself.

由于陈旧的会话由数据库本身删除,因此 Express 会话不需要自己处理清理工作。

EDIT: It seems like you need to have your own "lastAccess" field. When you access it you update that field yourself. Check the MongoDB documentation expire-datahttp://docs.mongodb.org/manual/tutorial/expire-data/

编辑:似乎您需要拥有自己的“lastAccess”字段。当您访问它时,您自己更新该字段。检查 MongoDB 文档expire-data http://docs.mongodb.org/manual/tutorial/expire-data/

EDIT2:

编辑2

Now becomes db.sessions.createIndex( { "createdAt": 1 }, { expireAfterSeconds: 3600 } )

现在变成 db.sessions.createIndex( { "createdAt": 1 }, { expireAfterSeconds: 3600 } )

The Mongo background thread to check this field runs every 60 seconds. So the timing to remove the document is not exact.

检查此字段的 Mongo 后台线程每 60 秒运行一次。因此,删除文档的时间并不准确。

回答by Garry May

For those who are having trouble with Redis try the following - hope this helps.

对于那些在使用 Redis 时遇到问题的人,请尝试以下操作 - 希望这会有所帮助。

I'm using Redis for DEV and PROD and targeting Express v4. On Windows I'm using the lightweight MSOpenTech Redis v3.0 toolset, otherwise, I just use the Heroku Redis Addon. To get it to work via Node hasn't been too hard - so far...

我将 Redis 用于 DEV 和 PROD,并针对 Express v4。在 Windows 上,我使用轻量级的 MSOpenTech Redis v3.0 工具集,否则,我只使用 Heroku Redis Addon。通过 Node 让它工作并不太难 - 到目前为止......

var session = require('express-session');

. . .

var RedisStore = require('connect-redis')(session);

var redisClient = require('redis').createClient(process.env.REDIS_URL);

var redisOptions = { 
        client: redisClient, 
        no_ready_check: true,
        ttl: 600,
        logErrors: true
};

var redisSessionStore = new RedisStore(redisOptions);

app.use(session({
    store: redisSessionStore,
    secret: 'Some.Long.Series.of.Crazy.Words.and.Jumbled.letter.etc',
    resave: true,       
    saveUninitialized: true 
}));

Good luck!

祝你好运!

ps. I only just re-read the original query and noticed this - sorry!

附:我只是重新阅读了原始查询并注意到了这一点 - 抱歉!

It seems an overkill to install Redis, MongoDB or another database just for this simple task.

仅仅为了这个简单的任务而安装 Redis、MongoDB 或其他数据库似乎是一种矫枉过正。

回答by Anthony

If you use OSX use

如果您使用 OSX,请使用

brew install memcached

if linux

如果是 linux

apt install memcached

solve session message, becose de app can connect to 127.0.0.1:11211 memcache service.

解决session消息,因为de app可以连接到127.0.0.1:11211 memcache服务。