Nodejs 用redis存储session的尝试。
Nodejs 用redis存储session的尝试。
想用redis存储session,但半天没看懂connect-redis,而且把secret值暴露出来的API真心不习惯。
所以就做了一个可以用redis存储session的小插件,欢迎来拍砖:https://github.com/zaobao/redis-session
先来谈谈用redis存储session的优缺点。 优点:就是可以共享session,随便什么服务,只要能连上redis服务器就可以获取session。 缺点:数据可靠性变差,同时有两个任务修改session时该怎么办(虽然不常见),如果自己实现事务机制,代码复杂度和性能都会受影响;另外,redis访问存储都是异步的,这样频繁访问session存储的话就会有很多回调函数,代码可读性会降低。
基于上述考虑,这个插件放弃的一部分的数据可靠性,来换取更友好的接口、更好的性能,当然还有更少的代码。
为什么说这是个插件呢?因为你可以很轻易地把它集成到各种框架中,只要有类似的至少是继承原生API的request、response和一个基于redis和generic-pool的访问池。你也可以单独地使用它,甚至和其他组件一起搭建属于你自己的框架。 <br /> <h3>使用方法</h3>
只有一个100多行的session.js文件,只要下载下来,然后
sessionModule = require(./session.js);
sessionModule.useSession(request, response, redisPool, [options]);
在使用前,你还得自己解析一下cookie,大部分框架都帮你做好了,自己做也很简单:
request.cookie = {};
if (request.headers.hasOwnProperty("cookie")) {
cookieString = request.headers.cookie;
request.cookie = qs.parse(cookieString.replace(/\s+/g,""), ";", "=");
}
然后你就可以像在J2EE里一样操作session了,当然只有最基本的API。
request.getSession(true, function (session) {
session.setAttribute("username","2b");
session.destroy(function () {
request.getSession(true, function (session) {
session.setAttribute("username","3b");
response.endWithSession("Success! " + session.getAttribute("username"));
})
});
});
只定义6个接口,2个是用来让你集成到框架中用的,真正操作只有4个
Nodejs 用redis存储session的尝试
摘要
本文介绍了一种基于Redis存储session的方法,并提供了一个简单的插件来简化这一过程。该插件旨在提高代码的可读性和性能,同时减少数据可靠性的依赖。
优点与缺点
优点:
- 共享session: 可以在多个服务之间共享session信息,只需要能够连接到同一Redis服务器即可。
缺点:
- 数据可靠性: 由于Redis的异步特性,当两个进程同时修改session时可能会出现数据不一致的问题。
- 代码复杂度: 实现事务机制会增加代码复杂度和性能开销。
- 回调地狱: 频繁的异步访问会导致大量的回调函数,影响代码的可读性。
插件介绍
这个插件的主要目的是提供一个更友好的接口来使用Redis存储session,同时保持良好的性能和较少的代码量。该插件的设计目标是易于集成到不同的框架中,并且支持基本的session操作。
使用方法
首先,你需要安装并引入插件。假设插件已经下载并放在session.js
文件中:
// 引入插件模块
const sessionModule = require('./session.js');
// 初始化插件
sessionModule.useSession(request, response, redisPool, [options]);
接下来,你需要解析请求中的cookie。大多数框架已经内置了解析功能,但如果需要手动处理,可以这样做:
// 解析cookie
request.cookie = {};
if (request.headers.hasOwnProperty("cookie")) {
const cookieString = request.headers.cookie;
request.cookie = qs.parse(cookieString.replace(/\s+/g,""), ";", "=");
}
示例代码
以下是一个完整的示例,展示了如何使用插件进行session操作:
// 假设已经初始化了request和response对象
const sessionModule = require('./session.js');
const redisPool = /* 初始化你的Redis连接池 */;
// 使用插件
sessionModule.useSession(request, response, redisPool);
// 获取session
request.getSession(true, function (session) {
// 设置session属性
session.setAttribute("username", "2b");
// 销毁当前session
session.destroy(function () {
// 获取新的session
request.getSession(true, function (session) {
// 更新session属性
session.setAttribute("username", "3b");
// 结束响应
response.endWithSession("Success! " + session.getAttribute("username"));
});
});
});
总结
通过这个插件,你可以方便地将session存储在Redis中,同时避免了一些常见的问题,如数据一致性等。该插件提供了简洁的API,使得session管理变得更加容易。希望这个插件能帮助你在项目中更好地利用Redis存储session。
收藏了
redis支持lua了,可以解决你的同步修改问题
redis支持简单的事务,且提供了乐观锁,可尝试使用WATCH来检测多客户端同时修改引发的冲突问题。
怎么用lua?业务逻辑都用lua写了,怎么给出统一的session接口?
事务失败怎么办?我还要给它写个回滚机制,效率低又容易出bug,太蛋疼了。
在Node.js中使用Redis存储Session是一种常见的做法,特别是在需要分布式Session管理的应用场景下。下面是关于如何使用Redis存储Session的一个简要示例,并讨论其优缺点。
示例代码
首先,你需要安装必要的包:
npm install express session redis connect-redis
接下来,创建一个简单的Express应用,将Session存储在Redis中:
const express = require('express');
const session = require('express-session');
const RedisStore = require('connect-redis')(session);
const app = express();
app.use(session({
store: new RedisStore(), // 使用Redis存储Session
secret: 'your_secret_key', // 用于加密Session ID的密钥
resave: false,
saveUninitialized: false,
}));
app.get('/', (req, res) => {
if (!req.session.views) {
req.session.views = 0;
}
req.session.views++;
res.send(`Views: ${req.session.views}`);
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
优点
- Session共享:由于Redis是分布式存储系统,所以任何连接到Redis的服务器都可以访问相同的Session数据。
- 易于扩展:添加更多服务器时,不需要担心Session同步问题。
缺点
- 数据一致性:在高并发环境下,可能存在多个请求同时修改同一个Session的情况,导致数据不一致。
- 异步操作:Redis的操作是异步的,频繁使用可能会增加代码复杂度,影响可读性和性能。
通过这种方式,你可以轻松地将Session存储在Redis中,而不需要担心Session在不同服务器之间的同步问题。希望这个示例对你有所帮助!