您的位置:首页 > 编程语言 > Java开发

基于spring_session实现的分布式集群会话管理

2017-10-11 13:44 681 查看
1:添加依赖

<!-- 分布式session解决方案: Spring session -->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
<version>${spring-session-redis.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
</exclusion>
<exclusion>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</exclusion>
</exclusions>
</dependency>


<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session</artifactId>
<version>1.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.4.1.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.5.2</version>
</dependency>


我们知道Tomcat再启动的时候首先会去加载
web.xml
 文件,Tomcat启动的时候
web.xml
被加载的顺序:
context-param
-> listener -> filter -> servlet


2:使用Spring Session的时候,我们配置了一个filter,配置代码如下(web.xml中添加):

<!-- Spring Session分布式会话解决方案 -->
<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>

3:实现共享会话有两种方式

其中第一种方式是:自定义方式继承RedisHttpSessionConfiguration,具体实现如下:

package io.flysium.framework.session;

/**
* Spring Session分布式会话解决方案
*/
@Configuration
@EnableScheduling
public class SpringSessionConfig extends RedisHttpSessionConfiguration {

private String getApplicationName() {
return AppConfig.getInst().getApplicationName();
}

private int getSessionCacheTimeout() {
return CacheConfig.getInst().getSessionCacheTimeout(TimeUnit.SECONDS);
}

/**
* Spring Data Redis 的连接工厂配置,必选
*/
@Bean(name = "connectionFactory")
public RedisConnectionFactory connectionFactory() {
return CacheConfig.getRedisConnectionFactory();
}

/**
* Redis session操作模板
*/
@Override
@Bean(name = "sessionRedisTemplate")
public RedisTemplate sessionRedisTemplate(
@Qualifier("connectionFactory") RedisConnectionFactory connectionFactory) {
return super.sessionRedisTemplate(connectionFactory);
}

/**
* Spring Data Redis 的会话存储仓库配置,可选
*/
@Override
@Bean(name = "sessionRepository")
public RedisOperationsSessionRepository sessionRepository(RedisOperations<Object, Object> sessionRedisTemplate,
ApplicationEventPublisher applicationEventPublisher) {
this.setMaxInactiveIntervalInSeconds(getSessionCacheTimeout()); // 单位:秒
this.setRedisNamespace(getApplicationName());
this.setRedisFlushMode(RedisFlushMode.ON_SAVE);
return super.sessionRepository(sessionRedisTemplate, applicationEventPublisher);
}

/**
* Spring Data Redis 的默认序列化工具,可选
*/
@Bean(name = "springSessionDefaultRedisSerializer")
public RedisSerializer springSessionDefaultRedisSerializer() {
return new FastJsonStringRedisSeriaziler(Charset.forName(Consts.CHARSET.UTF_8));
}

/**
* Session会话策略配置,可选
*
* 1、Spring Session 默认支持Cookie存储当前session的id, 即CookieHttpSessionStrategy。
* 2、Spring Session 支持RESTFul APIS,响应头回返回x-auth-token,来标识当前session的token,
* 即HeaderHttpSessionStrategy。
*/
/**
* @Bean(name = "httpSessionStrategy") public HttpSessionStrategy
*            httpSessionStrategy() { HeaderHttpSessionStrategy
*            headerHttpSessionStrategy = new HeaderHttpSessionStrategy();
*            headerHttpSessionStrategy.setHeaderName("X-Auth-Token");
*            return headerHttpSessionStrategy; }
*/

/**
* Session会话策略为 CookieHttpSessionStrategy 情况下配置的 Cookie序列化工具,可选
*/
@Bean(name = "cookieSerializer")
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
// Cookie名称
cookieSerializer.setCookieName(new StringBuilder(getApplicationName()).append("SESSION").toString());
// HttpOnly
cookieSerializer.setUseHttpOnlyCookie(true);
// HTTPS定义
cookieSerializer.setUseSecureCookie(true);
/**
* 解决子域问题:把cookiePath的返回值设置为统一的根路径就能让session id从根域获取,
* 这样同根下的所有web应用就可以轻松实现单点登录共享session
*/
cookieSerializer.setCookiePath("/");
return cookieSerializer;
}

}
接着在配置文件添加如下配置:

<!-- spring session配置文件,主要处理分布式session解决方案 -->

<!-- 自动扫描类包,将标志Spring注解的类自动转化为Bean,同时完成Bean的注入 -->
<context:component-scan base-package="io.flysium.framework.session"></context:component-scan>


其中第二种方式是:Spring Session和Redis解决分布式Session跨域共享问题
其中redis.properties配置如下:

#redis中心
redis.host=127.0.0.1
redis.port=6379
redis.password=123456
redis.maxIdle=100
redis.maxActive=300
redis.maxWait=1000
redis.testOnBorrow=true
redis.timeout=100000其中配置文件配置如下:
<!-- 加载资源文件 其中包含变量信息,必须在Spring配置文件的最前面加载,即第一个加载-->
<context:property-placeholder location="classpath:redis.properties" />
<!-- redis -->
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxTotal" value="500" />
<property name="maxIdle" value="256" />
<property name="maxWaitMillis" value="10000" />
<property name="testOnBorrow" value="true" />
<property name="testOnReturn" value="false" />
</bean>

<bean id="jedisConnectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="${os.write.redis.ip}" />
<property name="port" value="${os.write.redis.port}" />
<property name="timeout" value="2000" />
<property name="poolConfig" ref="jedisPoolConfig" />
<property name="usePool" value="true" />
</bean>

<bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory" />
</bean>

<!-- 将session放入redis -->
<bean id="redisHttpSessionConfiguration" class="org.springframework.session.data.redis.config.annotation.web
.http.RedisHttpSessionConfiguration">
<property name="maxInactiveIntervalInSeconds" value="172800" />
</bean>
<!-- 如果你的Redis不是你自己维护的,比如你是使用阿里云的Redis数据库,你不能够更改它的配置,那么可以使用如下方法 -->
<util:constant static-field="org.springframework.session.data.redis.config.ConfigureRedisAction.NO_OP"/>

<!-- <bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration"/>
<bean class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
redis 配置
<property name="hostName" value="10.60.81.32"/>
<property name="port" value="6379"/>
</bean> -->

<import resource="classpath*:spring/datasource-mysql-${deployType}.xml" />
</beans>

如果我们要设置session的过期时间的话。需要如下配置:



使用如下:

@ResponseBody
@RequestMapping("/get")
public String index(Model model,HttpServletRequest request,String action,String msg,String key){
HttpSession session=request.getSession();
String message = "ok";
if ("set".equals(action)){
session.setAttribute(key, msg);
}else if ("get".equals(action)){
message=(String)session.getAttribute(key);
}
return message;
}同时也可以参考如下文章:http://www.cnblogs.com/smallSevens/p/6763114.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐