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

引言

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

正文

  • pom中引入SpringSession的redis依赖


	org.springframework.session
	spring-session-data-redis
	2.4.3


	org.springframework.boot
	spring-boot-starter-data-redis
  • 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实现分布式系统session共享案例实战_第1张图片

  • 创建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 redisSerializer() {
        return new GenericFastJsonRedisSerializer();
    }
}

SpringSession实现分布式系统session共享案例实战_第2张图片

  • 创建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();
    }
}

SpringSession实现分布式系统session共享案例实战_第3张图片

  • 配置域名

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

SpringSession实现分布式系统session共享案例实战_第4张图片

SpringSession实现分布式系统session共享案例实战_第5张图片

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

SpringSession实现分布式系统session共享案例实战_第6张图片

  • 验证

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

SpringSession实现分布式系统session共享案例实战_第7张图片

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

SpringSession实现分布式系统session共享案例实战_第8张图片

结语

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

你可能感兴趣的:(JAVA,spring,integration,session,spring,boot)