使用Spring-Session共享使用Session

前言:

session共享策略有很多,常见的有粘性复制,高并发下效率查。tomcat-redis-session-manager无疑是一个挺好的方案,缺点要配置tomcat,有点复杂。最优的方案莫过于使用Spring-Session无缝整合redis,只要项目修改即可。

测试项目结构:

项目结构很简单:
使用Spring-Session共享使用Session_第1张图片

Test.java 就是一个页面跳转,传输一下sessionid

@Controller
public class Test {
    @RequestMapping("/test")
    public String test(HttpSession session, HttpServletRequest request) {
        request.setAttribute("id", session.getId());
        return "index";
    }

}

index.jsp 单纯的打印一下sessionid

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme() + "://"
            + request.getServerName() + ":" + request.getServerPort()
            + path + "/";
%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%-- <%@ page isELIgnored ="false" %>   --%>

<html>
<head>
<base href="<%=basePath%>">

<title>My JSP 'TestUpload.jsp' starting pagetitle>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
head>

<body>
我的session:${id}
    <br> sessionid=<%=session.getId()%>

body>
html>

当项目部署到nginx上的两个tomcat上时,每次访问地址,打印出来的sessionId都发生变化,这样在一些登录的操作中,用户明明在tomcatA上登录了,但是用户的其他操作负载到了TomcatB中,然而B不知道用户已经在A登录了,又让用户登录一次,这样用户体验极差。使用Spring-Session就是把用户的session缓存到redis中,让大家都从redis中获取用户session,这样就保证了session的共享。

使用Spring-Session

  • pom.xml 增加依赖

        <dependency>
            <groupId>org.springframework.sessiongroupId>
            <artifactId>spring-session-data-redisartifactId>
            <version>1.3.0.RELEASEversion>
            <type>pomtype>
        dependency>
        <dependency>
            <groupId>biz.paluch.redisgroupId>
            <artifactId>lettuceartifactId>
            <version>3.5.0.Finalversion>
        dependency>
  • web.xml增加配置

    <filter>
        <filter-name>springSessionRepositoryFilterfilter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxyfilter-class>
    filter>
    <filter-mapping>
        <filter-name>springSessionRepositoryFilterfilter-name>
        <url-pattern>/*url-pattern>
        <dispatcher>REQUESTdispatcher>
        <dispatcher>ERRORdispatcher>
    filter-mapping>
  • Spring.xml增加配置
    作用是导入redis配置redis.properties,导入新建的一个配置文件spring-session.xml
"classpath:db.properties,classpath*:redis.properties" ignore-unresolvable="true"/>
...
"classpath:spring-session.xml"/>
  • 新增配置spring-session.xml

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd   http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

    
    <bean id="redisHttpSessionConfiguration"
        class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration" />

    
    <bean
        class="org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory">
        <property name="hostName" value="${redis.ip}" />
        <property name="port" value="${redis.port}" />
        <property name="password" value="${redis.password}" />
    bean>

    
    
    
    
    
    

    
    

beans>
  • 增加redis.properties

redis.ip=193.112.76.194
redis.port=6379
redis.password=xxxxxx
redis.pool.maxTotal=10
redis.pool.minIdle=4
redis.pool.maxIdle=8
redis.pool.testOnBorrow=true

发布到服务器上。访问index页面。无论刷新多少次结果都一样。session没变

我的session:a4b2fe35-aaa5-40c2-a7de-b1d60180ca04
sessionid=a4b2fe35-aaa5-40c2-a7de-b1d60180ca04

使用redis客户端查看

使用Spring-Session共享使用Session_第2张图片

刚好有个seession一致。

原理:

DelegatingFilterProxy拦截器拦截, springSessionRepositoryFilter替换容器默认的HttpSession支持为SpringSession每个请求都会访问它。

你可能感兴趣的:(Linux,SpringMVC)