Session共享
实现负载均衡用户每一个请求都有可能被分配到不固定的服务器上,这样我们首先要解决session的统一来保证无论用户的请求被转发到哪个服务器上都能保证用户的正常使用,即需要实现session的共享机制。
由 redis 负责 session 数据的存储,而我们自己实现的 session manager 将负责 session 生命周期的管理。利用 redis 自身的key过期时间机智,我们不再需要定期刷新和做其他额外的处理。
截止到2015-09-20 前是不支持Tomcat8的.
开源项目git 地址: https://github.com/jcoleman/tomcat-redis-session-manager
什么是Redis
Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库
Redis 与其他 key - value 缓存产品有以下三个特点:
1,Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
2,Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
3,Redis支持数据的备份,即master-slave模式的数据备份。
1,Redis优势
1,性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
2,丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
安装Redis数据库
下载地址:https://github.com/MSOpenTech/redis/releases。
下载 Redis-x64-xxx.zip压缩包到 D 盘,解压后,将文件夹重新命名为 redis。
1,运行Redis
1,打开CMD窗口,切换到Redis目录下,运行:
D:\redis\32bit > redis-server.exe redis.conf
2,这时候另启一个cmd窗口,原来的不要关闭,不然就无法访问服务端了。
切换到redis目录下运行:
D:\redis\32bit> redis-cli.exe -h 127.0.0.1 -p 6379 。
设置键值对 set myKey “abc”
取出键值对 get myKey
3,正确停止Redis的方法应该是向Redis发送shutdown命令,当Redis收到shutdown命令后,会先断开所有客户端连接,然后根据配置执行持久化,最后完成退出。
Redis 数据类型(扩展,感兴趣自己下去学习)
Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。
1,String(字符串)
string是redis最基本的类型,一个key对应一个value。
string类型是二进制安全的。意思是redis的string可以包含任何数据。比如jpg图片或者序列化的对象 。
String类型是Redis最基本的数据类型,一个键最大能存储512MB。
示例:
添加:set key “hello,redis”
获取:get key
2,Hash(哈希)
Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象。
示例:
添加:hset myhash name “tom” age 18 sex “man”
获取:hgetall myhash
3,List(列表)
Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素导列表的头部(左边)或者尾部(右边)
示例:
添加:lpush mylist “haha”
添加:lpush mylist “hehe”
获取:lrange mylist 0 10
4,Set(集合)
Redis的Set是string类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。
示例:
添加:sadd myset “redis”
添加:sadd myset “mongodb”
获取:smembers myset
5,Java 中使用 Redis (百度)
配置Redis + Session共享
1,配置方式
将 tomcat-redis-session-manager-1.2.jar 、jedis-2.6.1.jar、commons-pool2-2.2.jar
三个jar包拷贝到tomcat7/lib中。
在两个Tomcat 的conf/context.xml 文件里增加如下内容(或者在server.xml的context块中添加):
<Context>
<!-- redis session 共享配置 -->
<Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />
<Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"
host="127.0.0.1"
port="6379"
database="0"
maxInactiveInterval="60" />
3,重启Tomcat7,到redis 中查看session_id,如下:
127.0.0.1:6379> Keys *
2,特殊说明
git 开源项目是直接将SESSIONID作为key存储到redis中的,如下所示:
1) "6D5B0E0FD89E3A170B8BC5B8C112D3FD"
2) "9546B26D78C99E8F0BF785535E319271"
3) "839A35CFE17E900A81F50D629C104D2F"
需要特别注意的是项目中要存入session的对象必须实现序列化,否知会出现序列化错误!
3,对项目做了一点修改 (貌似有点问题TODO)
修改原因包括几点:
1、项目也有使用redis 做其他数据存储,直接使用这样的key存储到redis中,直观上无法区分哪些key是用来做session共享用的。
2、项目包括好几个服务(web、wap、cms),每个服务都需要做负载均衡session共享,这样以来无法区分哪些session是属于哪个服务的。
3、很难统计每个服务的在线用户数。
我在集群部署中我的每个服务都有不同的sessionCookieName(web = WJSESSIONID、wap = MJSESSIONID、cms = CMSJSESSIONID)
直接在tomcat7/conf/server.xml 的最下面的Context中增加 sessionCookieName
配置即可:在<Valve/>下添加下面代码
<Context docBase="F:\workspace\web" path="" reloadable="false"
sessionCookieName="WJSESSIONID" />
4,测试
1,启动两个tomcat,项目名称改下,tomcat1、tomcat2
2,启动redis服务 、 nginx服务 、nginx 客户端
3,访问项目,可以看到session已经共享了,在客户端 keys * 可以查询所有的key