req.session 集群模式下 运行 pm2 重定向后数据丢失
req.session data lost when after redirect when running pm2 in cluster mode
我们正在 运行使用 express 4.6.1 cookie 解析器 1.3.2 connect-flash 0.1.1 和 express session 1.7.0 创建一个 node.js 应用程序。
我们使用 flash 在重定向后的页面上显示消息,有时将数据存储在 req.session 中,以便在用户出错并需要重新输入时自动填写表单。最近我们开始在集群模式下使用 pm2,大多数事情似乎都运行良好,但我们注意到在重定向后我们丢失了闪存数据和存储在 req.session 中的数据。
这是一个例子:
req.flash("signup", errorString);
req.session.storedData = {};
req.session.storedData.username = "";
req.session.storedData.password = req.body.password;
req.session.storedData.email = req.body.email;
req.session.storedData.emailConfirm = req.body.emailConfirm;
res.redirect(problemRedirectPath);
这来自一个端点,该端点在用户尝试注册但出现某种错误后接受请求。如果我们 运行 在没有集群模式的情况下,会话数据和闪存都会正确显示,但如果我们 运行 在集群模式下,它们几乎总是丢失(并不总是 :/)
在集群模式下有更好的方法吗?
除非您使用 Redis、Memcache 或其他一些进程来存储会话数据,否则您将无法使用多个 Node 进程来处理请求。现在您的应用仅使用 express-session
来存储会话数据,默认情况下它仅将会话数据存储在内存中。
https://github.com/expressjs/session#sessionoptions
参见上面的警告部分link。
当您 运行 具有集群模块的应用程序时,它将为每个应用程序实例派生一个不同的进程。如果您不做一些工作,这些进程不能直接共享内存,这意味着当请求循环分发到应用程序实例时,任何不在同一进程中结束的请求将无法将它们的 cookie 与服务器端会话存储。
我建议将您的会话存储更改为更适合生产的存储,例如 Redis 或 Memcache。如果你使用 Redis,你可能想看看使用 connect-redis.
我遇到了同样的问题。从使用内存进行 Express 会话切换到 memcached 后,在 pm2 集群模式下一切正常。
始终建议应用程序永远不要将状态存储在内存中。通过使用像 pm2 这样的 tool/solution,它是一个负载 balancer/process 管理器,它将根据算法在所有实例中分发请求,一个进程将不会包含与其他进程具有的存储在内存中的相同状态。解决方案是:使用外部存储,所有实例都可以共享和访问,比如 mongo/redis/sql/etc。这样所有进程将从同一个源(不是内存,而是数据库)读取状态,解决问题。
我们正在 运行使用 express 4.6.1 cookie 解析器 1.3.2 connect-flash 0.1.1 和 express session 1.7.0 创建一个 node.js 应用程序。
我们使用 flash 在重定向后的页面上显示消息,有时将数据存储在 req.session 中,以便在用户出错并需要重新输入时自动填写表单。最近我们开始在集群模式下使用 pm2,大多数事情似乎都运行良好,但我们注意到在重定向后我们丢失了闪存数据和存储在 req.session 中的数据。
这是一个例子:
req.flash("signup", errorString);
req.session.storedData = {};
req.session.storedData.username = "";
req.session.storedData.password = req.body.password;
req.session.storedData.email = req.body.email;
req.session.storedData.emailConfirm = req.body.emailConfirm;
res.redirect(problemRedirectPath);
这来自一个端点,该端点在用户尝试注册但出现某种错误后接受请求。如果我们 运行 在没有集群模式的情况下,会话数据和闪存都会正确显示,但如果我们 运行 在集群模式下,它们几乎总是丢失(并不总是 :/)
在集群模式下有更好的方法吗?
除非您使用 Redis、Memcache 或其他一些进程来存储会话数据,否则您将无法使用多个 Node 进程来处理请求。现在您的应用仅使用 express-session
来存储会话数据,默认情况下它仅将会话数据存储在内存中。
https://github.com/expressjs/session#sessionoptions
参见上面的警告部分link。
当您 运行 具有集群模块的应用程序时,它将为每个应用程序实例派生一个不同的进程。如果您不做一些工作,这些进程不能直接共享内存,这意味着当请求循环分发到应用程序实例时,任何不在同一进程中结束的请求将无法将它们的 cookie 与服务器端会话存储。
我建议将您的会话存储更改为更适合生产的存储,例如 Redis 或 Memcache。如果你使用 Redis,你可能想看看使用 connect-redis.
我遇到了同样的问题。从使用内存进行 Express 会话切换到 memcached 后,在 pm2 集群模式下一切正常。
始终建议应用程序永远不要将状态存储在内存中。通过使用像 pm2 这样的 tool/solution,它是一个负载 balancer/process 管理器,它将根据算法在所有实例中分发请求,一个进程将不会包含与其他进程具有的存储在内存中的相同状态。解决方案是:使用外部存储,所有实例都可以共享和访问,比如 mongo/redis/sql/etc。这样所有进程将从同一个源(不是内存,而是数据库)读取状态,解决问题。