Redis以及tomcat-redis-session-manager

redis用内存来提高数据的读取速度,而使用tomcat-redis-session-manager将session放在redis中存放管理,进行session同步

2016-05-27 | 阅读

Redis的安装配置

Redis 是一个Key-value存储系统,与Memcached类型.redis的高性能,体现在数据是缓存在内存中的,会周期性地把数据写入磁盘或者把修改操作写入追加的记录文件中.

# 下载
wget http://download.redis.io/redis-stable.tar.gz
# 解压
tar -zxvf redis-stable.tar.gz
mv redis-stable /usr/local/redis
# 编译安装
yum install tcl # 安装redis需要tcl,所以先安装tcl.
make
make install

安装后,将redis移动到/usr/local/bin目录下:

cp -p redis-server /usr/local/bin
cp -p redis-benchmark /usr/local/bin
cp -p redis-cli /usr/local/bin
cp -p redis-check-dump /usr/local/bin
cp -p redis-check-aof /usr/local/bin


ln -s  /usr/local/redis/redis.conf  /etc/redis.conf  #添加配置文件软连接

然后执行命令,就可以启动redis了 :

redis-server  

redis的配置文件:

daemonize 如果需要在后台运行,把该项改为yes
pidfile 配置多个pid的地址 默认在/var/run/redis.pid
bind 绑定ip,设置后只接受来自该ip的请求
port 监听端口,默认是6379
loglevel 分为4个等级:debug verbose notice warning
logfile 用于配置log文件地址
databases 设置数据库个数,默认使用的数据库为0
save 设置redis进行数据库镜像的频率。
rdbcompression 在进行镜像备份时,是否进行压缩
dbfilename 镜像备份文件的文件名
Dir 数据库镜像备份的文件放置路径
Slaveof 设置数据库为其他数据库的从数据库
Masterauth 主数据库连接需要的密码验证
Requriepass 设置 登陆时需要使用密码
Maxclients 限制同时使用的客户数量
Maxmemory 设置redis能够使用的最大内存
Appendonly 开启append only模式
Appendfsync 设置对appendonly.aof文件同步的频率(对数据进行备份的第二种方式)
vm-enabled 是否开启虚拟内存支持   (vm开头的参数都是配置虚拟内存的)
vm-swap-file 设置虚拟内存的交换文件路径
vm-max-memory 设置redis使用的最大物理内存大小
vm-page-size 设置虚拟内存的页大小
vm-pages 设置交换文件的总的page数量
vm-max-threads 设置VM IO同时使用的线程数量
Glueoutputbuf 把小的输出缓存存放在一起
hash-max-zipmap-entries 设置hash的临界值
Activerehashing 重新hash

使用默认配置,即直接执行utils目录下的install_server.sh,全部使用默认配置进行安装.

然后就可以通过service命令来开启和关闭redis了,不过现在的redis名字叫redis_6379 . 可以到/etc/init.d目录下修改redis的名称.

使用systemctl enable redis命令,设置开机启动.

然后简单使用测试一下,通过redis-cli :

➜  ~ redis-cli 
127.0.0.1:6379> set key1 value2
OK
127.0.0.1:6379> get key1
"value2"
127.0.0.1:6379> del key1
(integer) 1
127.0.0.1:6379> quit

放开redis时,由于没有设置密码和绑定ip,会被默认的protected mode所关闭连接,所以需要关闭这个protected mode,直接在连接时,执行CONFIG SET protected-mode no

使用Redis存储tomcat的session

主要使用Github上这个项目

使用方式,首先先自行修改一下这个项目,然后打包,使用gradle进行构建.将构建完成的tomcat-redis-session-manager-VERSION.jar,与jedis.jarcommons-pool2.jar一起放在tomcat的lib目录下.

然后在Tomcat的context.xml中添加配置:

<Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />
<Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"
         host="localhost" <!-- optional: defaults to "localhost" -->
         port="6379" <!-- optional: defaults to "6379" -->
         database="0" <!-- optional: defaults to "0" -->
         maxInactiveInterval="60" <!-- optional: defaults to "60" (in seconds) -->
         sessionPersistPolicies="PERSIST_POLICY_1,PERSIST_POLICY_2,.." <!-- optional -->
         sentinelMaster="SentinelMasterName" <!-- optional -->
         sentinels="sentinel-host-1:port,sentinel-host-2:port,.." <!-- optional --> />

同时,一定要设置

<Manager pathname="" />

这一段十分重要,因为tomcat默认开启了自己的session持久化机制,会与redis manager冲突,所以必须去掉这行的注释,以使`redis manager`正常运作。

重启tomcat,之后就是用redis在管理session了.

随便登录一下,然后在redis中查看一下:

# 列出所有key.
keys *

就可以发现,上面已经在管理session了.

管理在redis中存放的session

主要需求是,同一个账号,只能在一台设备上登录,即只能有一个session.即当用户再次登录时,检测是否有已经存在的session,如果有,则删除这个session.

session是通过redis管理的,则这里,我们要通过tomcat-redis-session-manager来管理session,通过其的RedisSessionManager来进行session管理,而如何获取这个RedisSessionManager对象呢?

public static RedisSessionManager sessionManager ;

public static RedisSessionManager getSessionManager() throws Exception {
    if (sessionManager == null) {
        WebApplicationContext webApplicationContext = ContextLoader.getCurrentWebApplicationContext();
        ServletContext servletContext = webApplicationContext.getServletContext();
        ApplicationContextFacade appContextFacadeObj = (ApplicationContextFacade)servletContext;
        Field applicationContextField = appContextFacadeObj.getClass().getDeclaredField("context");
        applicationContextField.setAccessible(true);
        ApplicationContext appContextObj = (ApplicationContext)applicationContextField.get(appContextFacadeObj);
        Field standardContextField = appContextObj.getClass().getDeclaredField("context");
        standardContextField.setAccessible(true);
        StandardContext standardContextObj = (StandardContext)standardContextField.get(appContextObj);
        sessionManager = (RedisSessionManager)standardContextObj.getManager();
    }
    return sessionManager;
}

上面代码就是通过获取ServletContext来找到tomcat绑定的RedisSessionManager.