1、session是啥?
常用于购物车和登录状态保存。
2、分布式环境下的问题
用户登录将数据写到一台机器的session,但是其他机器没有这个数据。
3、方案一:tomcat + redis
基于tomcat原生的session支持。Tomcat RedisSessionManager,让tomcat都将session数据存储到redis
在tomcat的配置文件中,配置如下:
<Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />
<Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"
host="{redis.host}"
port="{redis.port}"
database="{redis.dbnum}"
maxInactiveInterval="60"/>
指定了redis的host和 port就ok了。
如果redis是哨兵架构,可以如下配置:
<Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />
<Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"
sentinelMaster="mymaster"
sentinels="<sentinel1-ip>:26379,<sentinel2-ip>:26379,<sentinel3-ip>:26379"
maxInactiveInterval="60"/>
4、方案二:spring session + redis
上面tomcat + redis好用,但严重依赖web容器,不好移植到其他web容器。所以最好是基于java一站式解决方案,spring。sping session是一个很好的选择。
1)pom.xml
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
<version>1.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.8.1</version>
</dependency>
2)spring配置文件
<bean id="redisHttpSessionConfiguration"
class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
<property name="maxInactiveIntervalInSeconds" value="600"/>
</bean>
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxTotal" value="100" />
<property name="maxIdle" value="10" />
</bean>
<bean id="jedisConnectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" destroy-method="destroy">
<!-- 这里是配置怎么去连redis -->
<property name="hostName" value="${redis_hostname}"/>
<property name="port" value="${redis_port}"/>
<property name="password" value="${redis_pwd}" />
<property name="timeout" value="3000"/>
<property name="usePool" value="true"/>
<property name="poolConfig" ref="jedisPoolConfig"/>
</bean>
3)web.xml
<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>
4)示例代码
@Controller
@RequestMapping("/test")
public class TestController {
@RequestMapping("/putIntoSession")
@ResponseBody
public String putIntoSession(HttpServletRequest request, String username){
request.getSession().setAttribute("name", “leo”);
return "ok";
}
@RequestMapping("/getFromSession")
@ResponseBody
public String getFromSession(HttpServletRequest request, Model model){
String name = request.getSession().getAttribute("name");
return name;
}
}
5)总结:
给sping session配置基于redis来存储session数据,并配置了一个spring session的过滤器,这样,session相关操作都会交给spring session。
在代码中,用原生的session操作,就是直接基于spring sesion从redis中获取数据。在大公司一般都是自研分布式session框架,因为要支持pb级的海量数据,高并发。