解决分布式环境下session共享问题

在分布式环境下,session会存在两个问题

第一个问题:不同域名下,浏览器存储的jsessionid是没有存储的。比如登录时认证服务auth.gulimall.com存储了session,但是搜索服务search.gulimall.com是没有这个session的;

第二个问题:即使域名相同,但是分布式的服务在相同的服务里面有多个服务集群部署的,用户每次访问的时候,不能总是访问同一个服务,可能到了其他的服务,由于采用了负载均衡,有可能这次请求分发给node1服务处理,下次请求分发给node2处理,node2是没存储有node1的session的。

解决办法:

第一种方式:配置tomcat

这种的只适用于3-5个tomcat服务的时候,可以使用,在分布式情况下不适合的。

存在的问题:带宽问题,相互同步需要消耗网络传输时间。tomcat内存问题,每一个tomcat都要存储其他tomcat对应的数据消耗内存。

第二种方式:

在客户端将所有的数据存储到cookie中,但是这是存在安全隐患的对应的数据可以被修改,而且cookie存储的数据是有限的只有4K。这种一般不用。

第三种方案:

选择hash一致性,也就是用户访问的时候,总是访问同一个服务。这里是修改nginx的配置,也可以结合业务字段,sid是456就到另一台服务器,其他的到另外一台服务器。

第四种方式:

使用公共的区域进行存储session,比如redis,数据库或者存储的更快的非关系型数据库。

下面是解决问题一的问题

解决子域共享问题

用户通过浏览器登录会员服务,会员服务会将其对应的用户信息存储到内存session中,但是这里我们不将其用户的信息存储内存session中,我们将其对应的用户的信息存储到redis。接下来给浏览器发卡,我们将其对应的域名放大,这样对应的子域名也可以可以访问对应的域名放大jessionid里面的数据。

解决方案:

引入SpringSession和使用:

需要注意:1.SpringSession有自动延期:redis中的数据也是有过期时间

2.哪里需要SpingSesson,哪里就需要配置。都要配置。

实现步骤:

1.添加依赖
XML 复制代码
<dependency>
	<groupId>org.springframework.session</groupId>
	<artifactId>spring-session-data-redis</artifactId>
</dependency>
2.配置文件中添加配置
bash 复制代码
spring.session.store-type=redis # Session store type.


#下面的是配置可以不加,这里可以添加一个过期时间
server.servlet.session.timeout= # Session timeout. If a duration suffix is not specified, seconds is used.
spring.session.redis.flush-mode=on-save # Sessions flush mode.
spring.session.redis.namespace=spring:session # Namespace for keys used to store sessions.
3.开启EnableRedisHttpSession注解:
4.添加配置类,默认使用jdk序列化,可读性差,这里系统化转成Json, 方便阅读
java 复制代码
@Configuration
public class GulimallSessionConfig {
    @Bean
    public CookieSerializer cookieSerializer(){
        DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
        //放大整个系统域的作用域,使用主域名,这样带这个的二级域名也能读取到session
        cookieSerializer.setDomainName("gulimall.com");
        cookieSerializer.setCookieName("GULISESSION");
        return cookieSerializer;
    }

    /**
     * 序列化机制
     * @return
     */
    @Bean
    public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
        return new GenericJackson2JsonRedisSerializer();
    }
}
5.在业务代码中使用session存储用户信息
java 复制代码
session.setAttribute(AuthServerConstant.LOGIN_USER,data);

注意:存储到session的实体类一定要系列化,否则会报异常

java 复制代码
public class MemberRespVo implements Serializable{}
6.前端引用:${user.nickname}

总结:需要使用SpringSession的服务依照上面的步骤实现:pom添加依赖,-->application配置类指定spring.session.story.type=redis-->添加config配置类,-->在启动类或配置类添加注解@EnableRedisHttpSession,然后在前端中进入引用即可。

相关推荐
这周也會开心2 分钟前
RabbitMQ知识点
分布式·rabbitmq
岁岁种桃花儿1 小时前
Kafka从入门到上天系列第三篇:基础架构推演+基础组件图形推演
分布式·kafka
qq_124987075312 小时前
基于Hadoop的信贷风险评估的数据可视化分析与预测系统的设计与实现(源码+论文+部署+安装)
大数据·人工智能·hadoop·分布式·信息可视化·毕业设计·计算机毕业设计
Coder_Boy_14 小时前
基于Spring AI的分布式在线考试系统-事件处理架构实现方案
人工智能·spring boot·分布式·spring
袁煦丞 cpolar内网穿透实验室16 小时前
远程调试内网 Kafka 不再求运维!cpolar 内网穿透实验室第 791 个成功挑战
运维·分布式·kafka·远程工作·内网穿透·cpolar
人间打气筒(Ada)16 小时前
GlusterFS实现KVM高可用及热迁移
分布式·虚拟化·kvm·高可用·glusterfs·热迁移
xu_yule16 小时前
Redis存储(15)Redis的应用_分布式锁_Lua脚本/Redlock算法
数据库·redis·分布式
難釋懷20 小时前
分布式锁的原子性问题
分布式
ai_xiaogui21 小时前
【开源前瞻】从“咸鱼”到“超级个体”:谈谈 Panelai 分布式子服务器管理系统的设计架构与 UI 演进
服务器·分布式·架构·分布式架构·panelai·开源面板·ai工具开发