单机session共享问题的解决
来源:互联网 发布:网络视频地址 编辑:程序博客网 时间:2024/04/28 11:10
在前台验证码使用servlet写的或者登录数据放入session中,但是当项目要发生产环境的话会产生该问题,原因是session只存在于单机如果多台服务器的话,在登录或者验证码等问题从session获取值时报错。
以下以验证码为例。
环境现场代码:
1、web.xml中配置
<!-- 配置验证码servlet -->
<servlet>
<servlet-name>validateCode</servlet-name>
<servlet-class>com.msok.insure.servlet.ValidateCodeServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>validateCode</servlet-name>
<url-pattern>/ValidateCodeServlet.do</url-pattern>
</servlet-mapping>
<servlet>
2、controller中servlet类-源码
http://note.youdao.com/share/?id=319bebf8110c29152515892b655db0ff&type=note
3、可以采用什么方式避免呢有以下几种想法 2-2配置jedisConnectionFactory2-3配置stringRedisSerializer
第一种想法:可以用分布式缓存
分布式环境下的session需要解决如下几个问题:
1.会话数据更新的同步
2.会话过期的同步
3.会话删除的同步
4.会话access的同步
第二种想法:Tomcat+memcached/redis
将session信息保存到缓存中生成唯一的key-value,然后在cookie中保存key,用户请求时通过key去缓存中获取session信息
第三种想法:
1.不使用session,session中的数据采用加密存放到cookie中
2.前段负载均衡按照请求IP分流到appserver,同一iP的请求分发到同一个appserver,防止session的分布式问题。
1.不使用session,session中的数据采用加密存放到cookie中
2.前段负载均衡按照请求IP分流到appserver,同一iP的请求分发到同一个appserver,防止session的分布式问题。
第四种想法:
不用session而是自己定义新的cookie来实现(如user_id) 客户端存状态,服务器端可以把数据放到如memcached、mysql内存表等中;
Cookie Based或者用session数据统一放到一个redis里面
第五种想法:
使用Session Sticky或者Session Replication
自己写的解决局部问题的方式(Springmvc+Redis配置好的--maven管理的)
ApplicationContext applicationContext=(ApplicationContext) req.getSession().getServletContext().getAttribute("org.springframework.web.context.WebApplicationContext.ROOT");
RedisTemplate redisTemplate =(RedisTemplate)applicationContext.getBean("redisTemplate");
如果多处用到了session而且为了减少最少的改动且提高复用性请往下看
相关环境配置
1首先,我们需要引入基本的jar包。maven中的基本引用如下:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.4.2.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.6.2</version>
</dependency>
2配置下springmvc.xml
2-1配置jedisPoolConfig
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxTotal" value="${redis.pool.maxTotal}" /><!--
maxActive -->
<property name="maxIdle" value="${redis.pool.maxIdle}" />
<property name="minIdle" value="${redis.pool.minIdle}" />
<property name="testOnBorrow" value="${redis.pool.testOnBorrow}" />
</bean>
<bean id="jedisConnectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="${redis.host}" />
<property name="port" value="${redis.port}" />
<property name="timeout" value="${redis.timeout}" />
<property name="usePool" value="${redis.usePool}" />
<property name="poolConfig" ref="jedisPoolConfig" />
</bean>
<bean id="stringRedisSerializer"class="org.springframework.data.redis.serializer.StringRedisSerializer" /> 2-4配置缓存机制
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory"/>
<property name="keySerializer" ref="stringRedisSerializer"/>
<property name="hashKeySerializer" ref="stringRedisSerializer"/></bean>
3、redis.properties
#\u6d4b\u8bd5
redis.host=172.30.9.12
#redis\u7aef\u53e3
redis.port=6908
#redis\u8fde\u63a5\u6c60\u6700\u5927\u503c
redis.pool.maxTotal=300
#redis\u8fde\u63a5\u6700\u5927\u7a7a\u95f2\u503c
redis.pool.maxIdle=20
#redis\u8fde\u63a5\u6700\u5c0f\u7a7a\u95f2\u503c
redis.pool.minIdle=5
#redis\u83b7\u53d6\u8fde\u63a5\u65f6\u662f\u5426\u9a8c\u8bc1\u53ef\u7528\u6027
redis.pool.testOnBorrow=true
#redis\u8fde\u63a5\u8d85\u65f6\u65f6\u95f4
redis.timeout=5000
#\u662f\u5426\u4f7f\u7528\u8fde\u63a5\u6c60\u7ba1\u7406\u8fde\u63a5
redis.usePool=true
在web.xml中配置(最终达到高效性,复用性、推荐)将所有的session数据都统一放入redis缓存中,依然照常可以使用session
<filter>
<filter-name>SessionFilter</filter-name>
<filter-class>com.msok.insure.utils.RedisSessionFilter</filter-class>
<init-param>
<param-name>sessionId</param-name>
<!-- cookie name, cookie value 是真实的sessionId -->
<param-value>insure_platform_sid</param-value>
</init-param>
<init-param>
<param-name>cookieDomain</param-name>
<param-value></param-value>
</init-param>
<init-param>
<param-name>cookiePath</param-name>
<param-value>/</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>SessionFilter</filter-name>
<url-pattern>/*</url-pattern>
<!-- <url-pattern>*.shtml</url-pattern> -->
</filter-mapping>
-------------------------------------------------配置的sessionFilter类 代码如下---------------------------------
package com.msok.insure.utils;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import javax.servlet.http.HttpSession;
/**
* Session数据存到Redis
*
*/
public class RedisSessionFilter implements Filter {
private String sessionId = "msok_sid";
private String cookieDomain = "";
private String cookiePath = "/";
private int timeoutMinute = 30;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.sessionId = filterConfig.getInitParameter("sessionId");
this.cookieDomain = filterConfig.getInitParameter("cookieDomain");
if (this.cookieDomain == null) {
this.cookieDomain = "";
}
this.cookiePath = filterConfig.getInitParameter("cookiePath");
if (this.cookiePath == null || this.cookiePath.length() == 0) {
this.cookiePath = "/";
}
String timeoutMinute = filterConfig.getInitParameter("timeoutMinute");
if(timeoutMinute != null && !timeoutMinute.isEmpty()){
try{
int timeTmp = Integer.parseInt(timeoutMinute);
if(timeTmp > 0){
this.timeoutMinute = timeTmp;
}
} catch(Exception e){
}
}
}
@Override
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
// 清除url链接上的jsessionid
if (request.isRequestedSessionIdFromURL()) {
HttpSession session = request.getSession();
if (session != null)
session.invalidate();
}
Cookie cookies[] = request.getCookies();
Cookie sCookie = null;
String sid = "";
if (cookies != null && cookies.length > 0) {
for (int i = 0; i < cookies.length; i++) {
sCookie = cookies[i];
if (sCookie.getName().equals(sessionId)) {
sid = sCookie.getValue();
}
}
}
if (sid == null || sid.length() == 0) {
sid = java.util.UUID.randomUUID().toString();
Cookie mycookies = new Cookie(sessionId, sid);
mycookies.setMaxAge(-1);
// mycookies.setHttpOnly(true);
if (this.cookieDomain != null && this.cookieDomain.length() > 0) {
mycookies.setDomain(this.cookieDomain);
}
mycookies.setPath(this.cookiePath);
response.addCookie(mycookies);
}
// 去除url中的jsessionid
HttpServletResponseWrapper wrappedResponse = new HttpServletResponseWrapper(
response) {
@Override
public String encodeRedirectUrl(String url) {
return url;
}
@Override
public String encodeRedirectURL(String url) {
return url;
}
@Override
public String encodeUrl(String url) {
return url;
}
@Override
public String encodeURL(String url) {
return url;
}
};
filterChain.doFilter(new HttpServletRequestRedisWrapper(sid, request,timeoutMinute),
wrappedResponse);
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
}
这样就再也不用担心单机共享session问题了。嘿嘿。
0 0
- 单机session共享问题的解决
- session共享问题的解决
- session被共享的问题及解决
- Tomcat二级域名Session共享问题的解决
- 解决IE8 Session共享问题
- session共享问题以及解决
- 利用spring session解决共享Session问题
- 利用spring session解决共享Session问题
- 利用spring session解决共享Session问题
- 利用spring session解决共享Session问题
- 利用spring session解决共享Session问题
- 利用spring session解决共享Session问题
- 如何解决不同的webApp的session 共享问题
- 解决ASP与ASP.NET之间的SESSION共享问题
- 解决nginx负载均衡的session共享问题
- 解决nginx负载均衡的session共享问题
- 解决nginx负载均衡的session共享问题
- 解决nginx负载均衡的session共享问题
- 第2周项目3-小试循环
- git的使用 - 团队开发
- Maven教程
- 海量数据处理
- 第五周项目一-三角形类
- 单机session共享问题的解决
- 第五周项目3
- Hadoop基础教程之搭建开发环境及编写Hello World
- hdoj 3501
- 内存泄漏查找c++ new delete
- 初识commonjs
- FragmentPagerAdapter与FragmentStatePagerAdapter区别
- HDU 1181
- 第五周项目1-三角形类雏形(2)