• 使用Spring-Session共享使用Session


    前言:

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

    测试项目结构:

    项目结构很简单:
    这里写图片描述

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

    @Controller
    public class Test {
        @RequestMapping("/test")
        public String test(HttpSession session, HttpServletRequest request) {
            request.setAttribute("id", session.getId());
            return "index";
        }
    
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    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" %>   --%>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
    <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'TestUpload.jsp' starting page</title>
    
    <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 增加依赖
    <!-- 使用Spring Session来解决Session共享问题  -->
            <dependency>
                <groupId>org.springframework.session</groupId>
                <artifactId>spring-session-data-redis</artifactId>
                <version>1.3.0.RELEASE</version>
                <type>pom</type>
            </dependency>
            <dependency>
                <groupId>biz.paluch.redis</groupId>
                <artifactId>lettuce</artifactId>
                <version>3.5.0.Final</version>
            </dependency>
    • 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>
            <dispatcher>REQUEST</dispatcher>
            <dispatcher>ERROR</dispatcher>
        </filter-mapping>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • Spring.xml增加配置
      作用是导入redis配置redis.properties,导入新建的一个配置文件spring-session.xml
    <context:property-placeholder location="classpath:db.properties,classpath*:redis.properties" ignore-unresolvable="true"/>
    ...
    <import resource="classpath:spring-session.xml"/>
    • 1
    • 2
    • 3
    • 新增配置spring-session.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <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">
    
        <!-- 创建名为springSessionRepositoryFilter 的Spring Bean,继承自Filter。 springSessionRepositoryFilter替换容器默认的HttpSession支持为Spring 
            Session, 将Session实例存放在Redis中 -->
        <bean id="redisHttpSessionConfiguration"
            class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration" />
    
        <!-- 使用LettuceConnectionFactory -->
        <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>
    
        <!-- 也可以将使用LettuceConnectionFactory改成使用JedisConnectionFactory,两者保留其一就好 -->
        <!--<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"> -->
        <!--<property name="hostName" value="${redis.ip}"/> -->
        <!--<property name="port" value="${redis.port}"/> -->
        <!--<property name="password" value="${redis.password}"/> -->
        <!--</bean> -->
    
        <!-- 让Spring Session不再执行config命令 -->
        <!-- <util:constant
            static-field="org.springframework.session.data.redis.config.ConfigureRedisAction.NO_OP" /> -->
    
    </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客户端查看

    这里写图片描述

    刚好有个seession一致。

    原理:

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

  • 相关阅读:
    排序算法-Java实现
    Linux-文件内容的查阅
    Linux-文件权限概念
    Linux-awk和sort处理字符串
    面试题-总结(二)
    面试题-总结(一)
    程序员的其他技能:股票-ROE解释
    程序员的其他技能:基金初识-基金名称的秘密
    tp框架表单验证 及ajax
    tp框架做留言板
  • 原文地址:https://www.cnblogs.com/jpfss/p/10894364.html
Copyright © 2020-2023  润新知