NodeJS+Redis实现分布式Session方案
2016-01-07 16:08
681 查看
Session是什么?
Session 怎么工作?
分布式Session
Session_id
Hashing Ring
配置
分布式Redis 操作
分布式Session操作
结合 Express 应用
小结
在服务端存储 Session,可以有很多种方案:
内存存储
数据库存储
分布式缓存存储
如前述, Session使用的标识其实是客户端传递的 session_id,在分布式方案中,一般会针对这个值进行哈希,以确定其在 hashing ring 的存储位置。
服务端查询客户端Cookies 中是否存在 session_id
有session_id,是否过期?过期了需要重新生成;没有过期则延长过期
没有 session_id,生成一个,并写入客户端的 Set-Cookie 的 Header,这样下一次客户端发起请求时,就会在 Request Header 的 Cookies带着这个session_id
比如我用 Express, 那么我希望这个过程是自动完成的,不需要每次都去写 Response Header,那么我需要这么一个函数(摘自朴灵的《深入浅出Node.js》):
?
这个函数替换了writeHead,在每次Response写Header时它都会得到执行机会,所以它是自动化的。这个req.session.id 是怎么得到的,稍候会有详细的代码示例。
实现这个回路的算法多种多样,比如 一致性哈希。
我的哈希环实现( hashringUtils.js:
?
?
在Node 中序列化/反序列化JSON 是件令人愉悦的事,写个配置读取器也相当容易(configUtils.js:
?
?
?
?
这个被引用的 session 模块暴露了一些操作 session 的方法,在需要时可以这样使用:
?
Session 怎么工作?
分布式Session
Session_id
Hashing Ring
配置
分布式Redis 操作
分布式Session操作
结合 Express 应用
小结
Session是什么?
Session 是面向连接的状态信息,是对 Http 无状态协议的补充。Session 怎么工作?
Session 数据保留在服务端,而为了标识具体 Session 信息指向哪个连接,需要客户端传递向服务端发送一个连接标识,比如存在Cookies 中的session_id值(也可以通过URL的QueryString传递),服务端根据这个id 存取状态信息。在服务端存储 Session,可以有很多种方案:
内存存储
数据库存储
分布式缓存存储
分布式Session
随着网站规模(访问量/复杂度/数据量)的扩容,针对单机的方案将成为性能的瓶颈,分布式应用在所难免。所以,有必要研究一下 Session 的分布式存储。如前述, Session使用的标识其实是客户端传递的 session_id,在分布式方案中,一般会针对这个值进行哈希,以确定其在 hashing ring 的存储位置。
Session_id
在 Session 处理的事务中,最重要的环节莫过于 客户端与服务端 关于 session 标识的传递过程:服务端查询客户端Cookies 中是否存在 session_id
有session_id,是否过期?过期了需要重新生成;没有过期则延长过期
没有 session_id,生成一个,并写入客户端的 Set-Cookie 的 Header,这样下一次客户端发起请求时,就会在 Request Header 的 Cookies带着这个session_id
比如我用 Express, 那么我希望这个过程是自动完成的,不需要每次都去写 Response Header,那么我需要这么一个函数(摘自朴灵的《深入浅出Node.js》):
?
Hashing Ring
hashing ring 就是一个分布式结点的回路(取值范围:0到232 -1,在零点重合):Session 应用场景中,它根据 session_id 的哈希值,按顺时针方向就近安排一个大于其值的结点进行存储。实现这个回路的算法多种多样,比如 一致性哈希。
我的哈希环实现( hashringUtils.js:
?
配置
配置信息是需要根据环境而变化的,某些情况下它又是不能公开的(比如Session_id 加密用的私钥),所以需要一个类似的配置文件( config.cfg:?
?
分布式Redis 操作
有了上述的基础设施,实现一个分布式 Redis 分配器就变得相当容易了。为演示,这里只简单提供几个操作 Hashes 的方法(redisMatrix.js:?
分布式Session操作
session_id 的事务和 分布式的Redis都有了,分布式的 Session 操作呼之欲出(sessionUtils.js:?
结合 Express 应用
在 Express 中只需要简单的 use 就可以了( app.js:?
?
小结
虽然本文提供的是基于 Express 的示例,但基于哈希算法和缓存设施的分布式思路,其实是放之四海而皆准的相关文章推荐
- Redis中hash表中的field的value自增可以用hincrby
- redis安装及简单使用
- Redis缓存技术及JAVA应用
- redis学习(二)redis数据类型 Date Types
- Java连接vm中的redis (Vmware 配置端口转发)
- redis命令 举例
- Redis常用命令
- redis学习(一)redis for mac安装,启动,关闭,卸载
- Spring-data-redis: 分布式队列
- mac下,redis的安装与配置
- PHP 使用 Redis
- redis 笔记03 RDB 持久化、AOF持久化、事件、客户端
- Redis之安装篇(windows 7 64位)
- Redis之java操作篇(数据对象的存取)
- 动态字段插入及查询redis小结
- redis配置认证密码
- redis作为一个高速数据库,在互联网上,必须有对应的安全机制来进行保护。
- 使用普通账户安装 Redis 服务
- ubuntu安装 LNMP+redis
- c#中用lua脚本执行redis命令