SpringSession实现分布式系统session共享案例实战

Posted 北溟溟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringSession实现分布式系统session共享案例实战相关的知识,希望对你有一定的参考价值。

引言

本节我们主要使用SpringSession实现分布式应用系统中数据共享问题的一个案例。在开发中我们最常见的应用案例就是我们的sso单点登录系统,号称为一处登录处处访问。我们知道在单应用系统中实现数据共享我们可以通过session来实现,session存储于我们的服务端,但是应用之间是隔离的,session中存储的信息只能在应用内部共享,要想实现共享就需要一些特殊的处理,如部署在tomcat中的应用,不同应用通过修改tomcat服务器配置实现session的共享,这样虽然能够实现session共享,但是对于我们的分布式微服务来讲,上百个服务都要配置这些服务,对于运维来说工作量巨大,也不容易管理的。SpringSession却可以轻松解决分布式应用中数据共享的问题,核心原理就是通过filter拦截器将我们的session实现替换为SpringSession实现,将我们的共享数据存储在所有应用都能够访问到的位置。本小节我们依然使用我们的非关系性数据库redis存储我们的共享数据,从而实现不同应用间的数据共享。

正文

  • pom中引入SpringSession的redis依赖
<!-- https://mvnrepository.com/artifact/org.springframework.session/spring-session-data-redis -->
<dependency>
	<groupId>org.springframework.session</groupId>
	<artifactId>spring-session-data-redis</artifactId>
	<version>2.4.3</version>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
  • yml中配置SpringSession以及redis的参数,可参考前面博客有关于redis哨兵模式的配置
server:
  port: 9000
spring:
  redis:
    #默认数据分区
    database: 0
    #redis集群节点配置
    cluster:
      nodes:
        - 192.168.23.134:6379
        - 192.168.23.134:6380
        - 192.168.23.134.6381
      max-redirects: 3
    #超时时间
    timeout: 10000
    #哨兵节点配置
    sentinel:
      master: mymaster
      nodes:
        - "192.168.23.134:26379"
        - "192.168.23.134:26380"
        - "192.168.23.134:26381"
    #redis密码
    password: root
    #redis 客户端工具
    lettuce:
      pool:
        # 连接池最大连接数(使用负值表示没有限制) 默认为8
        max-active: 8
        # 连接池中的最小空闲连接 默认为 0
        min-idle: 1
        # 连接池最大阻塞等待时间(使用负值表示没有限制) 默认为-1
        max-wait: 1000
        # 连接池中的最大空闲连接 默认为8
        max-idle: 8
  #spring session配置
  session:
    #数据存储方式
    store-type: redis
    redis:
	  #redis持久化策略
      flush-mode: on_save
	  #名称空间
      namespace: spring:session:atp

  • 创建SpringSession配置类

说明:在CookieSerializer 序列化器配置中配置我们分布式应用中的父级域名atp.com,以及CookieName名称:ATPSESSION。实现同一域名下应用的session共享。

package com.yundi.atp.platform.config;

import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
import org.springframework.session.web.http.CookieSerializer;
import org.springframework.session.web.http.DefaultCookieSerializer;

/**
 * @Author: yanp
 * @Description: 使用springsession+redis实现全局session共享
 * @Date: 2021/5/19 20:33
 * @Version: 1.0.0
 */
@EnableRedisHttpSession
@Configuration
public class GlobalSessionConfig {
    /**
     * 生成Cookie
     * @return
     */
    @Bean
    public CookieSerializer cookieSerializer() {
        DefaultCookieSerializer defaultCookieSerializer = new DefaultCookieSerializer();
        defaultCookieSerializer.setDomainName("atp.com");
        defaultCookieSerializer.setCookieName("ATPSESSION");
        return defaultCookieSerializer;
    }

    /**
     * spring-session序列化
     *
     * @return
     */
    @Bean(value = "springSessionDefaultRedisSerializer")
    public RedisSerializer<Object> redisSerializer() {
        return new GenericFastJsonRedisSerializer();
    }
}

  • 创建session测试接口
package com.yundi.atp.platform.module.sys;

import com.yundi.atp.platform.common.Result;
import com.yundi.atp.platform.module.sys.entity.User;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpSession;
import java.time.LocalDateTime;

/**
 * @Author: yanp
 * @Description:
 * @Date: 2021/5/19 19:57
 * @Version: 1.0.0
 */
@Api(tags = "SpringSession测试")
@Slf4j
@Controller
public class IndexController {

    @ApiOperation(value = "获取session")
    @GetMapping(value = "/getSession")
    @ResponseBody
    public Result getSession(HttpSession httpSession) {
        User user = (User) httpSession.getAttribute("user");
        log.info("httpSession:{}",httpSession.getAttribute("user"));
        return Result.success(user);
    }

    @ApiOperation(value = "创建session")
    @GetMapping(value = "/session")
    @ResponseBody
    public Result session(HttpSession httpSession) {
        User user = new User();
        user.setId("1");
        user.setName("xiaoming");
        user.setPass("xiaoming");
        httpSession.setAttribute("user", user);
        return Result.success();
    }
}

  • 配置域名

说明:位置为C:\\Windows\\System32\\drivers\\etc

  • 启动俩个atp应用实例,端口分别为9000和9001

  • 验证

①访问atp.com域名地址,9000端口,访问地址/session接口生成共享Cookie

②访问test.atp.com域名地址,端口9001,访问路径/getSession获取到了共享的session数据,从而证明了我们的session数据在不同应用间可以实现共享。

结语

ok,关于SpringSession实现分布式系统session共享案例实战到这里就结束了,我们下期见。。。

以上是关于SpringSession实现分布式系统session共享案例实战的主要内容,如果未能解决你的问题,请参考以下文章

使用idea,springboot,springsession,redis实现分布式微服务的session 共享

SpringSession和Redis实现Session跨域

Day424.SpringSession&SSO单点登录 -谷粒商城

Day424.SpringSession&SSO单点登录 -谷粒商城

Spring Session解决分布式Session问题的实现原理

如何使用Spring Session实现分布式Session管理