注意:借鉴原文章:http://www.cnblogs.com/roy-blog/p/7196054.html
感兴趣的可以加一下481845043 java交流群,共同进步。
1 session的概念
在网络应用中我们会称为“会话控制”,在开发中我们常称其为session对象,用来存储特定用户会话所需的属性及配置信息。当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当用户请求来自应用程序的 Web 页时,如果该用户还没有会话,则 Web 服务器将自动创建一个 Session 对象。当会话过期或被放弃后,服务器将终止该会话。Session 对象最常见的一个用法就是存储用户的首选项。例如,如果用户指明不喜欢查看图形,就可以将该信息存储在 Session 对象中。注意 :会话状态仅在支持 cookie 的浏览器中保留。
2 为什么实现session共享
在利用nginx实现了负载均衡和动静分离之后,会面临一个内存数据同步的问题,我们通常将一些例如:用户信息,重要标识等具有唯一标识的数据,存在内存中,典型的一种就是在数据存在session中。例如:我有A,B两台服务器做了负载均衡,当我在A服务器上执行了登录并且将登录数据存入session的时候,这些session数据只存在于A服务器上,而没有在B服务器上,假如在处理下一个请求的时候,我需要用到session的数据,而不巧的是,这个请求刚好被交由B服务器来处理,这时候就会出现B服务器拿不到session数据的情况,从而造成错误。如何让session数据在集群的各个分支中共享session呢,
肯定方法不只一种,但是本质肯定是实现session数据在各个服务器的同步,可能大家第一次想到的是使用数据库进行数据的存储,但其实质上是存储在改服务器的磁盘中,但是我们都知道session之所以出现是因为它是在内存中的,程序读取内存的数据要远远比读取磁盘的数据快,所以我们把一些经常用到的东西都放在session里面。
有没有一种数据库,是存放在内存中的呢?这就是redis。通俗的讲,它就是一个数据库,但是这个数据库是存储在内存里面的,所以读写数据速度要比磁盘的快得多。又因为它是一个数据库,所以可以实现数据的同步。我们把session数据存放在redis中,然后所有的集群分支都可以去访问这个数据库里面的东西,这就是全局缓存的原理。
3 安装与运行
本人是在Windows本地系统下下载测试的,下载地址:https://github.com/MSOpenTech/redis/releases。Redis 支持 32 位和 64 位。这个需要根据你系统平台的实际情况选择,这里我下载 Redis-x64-xxx.zip压缩包到 E 盘,解压后可以直接使用,将文件夹重新命名为 redis。目录结构如下。
可以通过目录下的redis.windows.conf 文件Ctrl+F 查找 # requirepass,将其前面的#删除 后面加入你的新密码,例如123,来设置你的密码,因为一开始redis是默认没有密码的。但是为了安全起见,在开发中使用要设置密码。
解压后打开一个 cmd 窗口 使用cd命令切换目录到 E:\redis 运行 redis-server.exe redis.windows.conf 。如果想方便的话,可以把 redis 的路径加到系统的环境变量里,这样就省得再输路径了,后面的那个 redis.windows.conf 可以省略,如果省略,会启用默认的。输入之后,会显示如下界面:
只要你出现上图样式,即为开启成功。注意的是,当你关闭这个dos窗口,redis服务会马上关闭,所以为了以后使用方便,可以使用redis命令:
redis-server --service-install redis.windows.conf 将其安装成Windows服务,设置自启或手动,安装成功后可以在服务中找到Redis。
还有需要注意的一点就是当你在redis.windows.conf 文件中修改密码后,不能马上起作用。需要使用redis命令,redis-server --service-stop进行redis服务的关闭。
设置密码相关命令:
E:\redis>redis-cli.exe -h 127.0.0.1 -p 6379
127.0.0.1:6379> config get requirepass
1) "requirepass"
2) ""
127.0.0.1:6379> config set requirepass "123456"
OK
127.0.0.1:6379> auth 123456
OK127.0.0.1:6379> config get requirepass
1) "requirepass"
2) "123456"
127.0.0.1:6379>
4 项目中使用,做一些配置工作,来实现session数据的全局缓存。
1)首先是添加jar包,如果你是maven项目,需要在pom.xml加入下面代码
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
<version>1.3.1.RELEASE</version>
<type>pom</type>
</dependency>
如果不是maven项目,你需要加入下面这些jar包。
2) 编写redis.properties,代码如下:
redis_isopen:yes
#主机地址
redis_hostName=xxx.xxx.xxx.xxx
#端口
redis_port=6379
#密码
redis_password=xxxxxxxx
#连接超时时间
redis_timeout=200000
redis_maxIdle=300
redis_maxActive=600
redis_maxWait=100000
redis_testOnBorrow=true
3)编写spring-redis.xml配置文件,这个文件配置关于redis的一些基本信息。
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd ">
<!-- session设置 maxInactiveIntervalInSeconds为session的失效时间,单位为秒-->
<bean
class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
<property name="maxInactiveIntervalInSeconds" value="3600"></property>
</bean>
<!-- redis连接池 -->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="${redis_maxIdle}" />
<property name="testOnBorrow" value="${redis_testOnBorrow}" />
</bean>
<!-- redis连接工厂 -->
<bean id="connectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="${redis_hostName}" />
<property name="port" value="${redis_port}" />
<property name="password" value="${redis_password}" />
<property name="timeout" value="${redis_timeout}" />
<property name="poolConfig" ref="poolConfig"></property>
</bean>
</beans>
4)在application.xml(spring的主配置文件)需要加入redis.properties配置文件的扫描,如下。
<!-- 读取redis参数配置 -->
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>/WEB-INF/classes/redis.properties</value>
</list>
</property>
</bean>
5)在主配置文件中引入spring-redis.xml,如下。
<import resource="spring-redis.xml" />
6)在web.xml中,加入关于session的过滤器,只有这样session才会被redis所操纵。
<filter>
<filter-name>springSessionRepositoryFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSessionRepositoryFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
这样以后,我们就实现了redis对session的管理。 PS.再退出的时候,需要这样写才不会出错。(ssh项目)
public String yipinExit(){
Iterator<String>keys=session.keySet().iterator();
while(keys.hasNext()){
String key=keys.next();
session.remove(key);
}
return "yipinExit";
}
来源:oschina
链接:https://my.oschina.net/u/4381003/blog/4029391