用redis存储session的尝试。
发布于 11 年前 作者 zaobao 28498 次浏览 最后一次编辑是 8 年前

想用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个

5 回复

redis支持lua了,可以解决你的同步修改问题

redis支持简单的事务,且提供了乐观锁,可尝试使用WATCH来检测多客户端同时修改引发的冲突问题。

怎么用lua?业务逻辑都用lua写了,怎么给出统一的session接口?

事务失败怎么办?我还要给它写个回滚机制,效率低又容易出bug,太蛋疼了。

回到顶部