淘东电商项目(30) -解决分布式Session共享问题

本文涉及的产品
云原生内存数据库 Tair,内存型 2GB
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Redis 版,经济版 1GB 1个月
简介: 淘东电商项目(30) -解决分布式Session共享问题

引言

本文代码已提交至Github(版本号:3b2359205b2d49f9eae313d8cca119082dd7bc99),有兴趣的同学可以下载来看看:https://github.com/ylw-github/taodong-shop

本文主要解决分布式Session的问题。

本文目录结构:

l____引言

l____ 1. 分布式Session的问题

l____ 2. 解决方案

l____ 3. spring-session

l____ 4. 测试

l____总结

1. 分布式Session的问题

1.首先在「淘东电商」项目里复制一个portal-web,并修改端口号为8081,模拟门户集群,如下图:

2.项目新增controller,作为验证:

@RestController
public class TestSessionController {
    @Value("${server.port}")
    private Integer projectPort;// 项目端口
    @RequestMapping("/createSession")
    public String createSession(HttpSession session, String name) {
        session.setAttribute("name", name);
        return "当前项目端口:" + projectPort + " 当前sessionId :" + session.getId() + "在Session中存入成功!";
    }
    @RequestMapping("/getSession")
    public String getSession(HttpSession session) {
        return "当前项目端口:" + projectPort + " 当前sessionId :" + session.getId() + " 获取的姓名:" + session.getAttribute("name");
    }
}

3.Nginx负载均衡配置:

#user  nobody;
worker_processes  1;
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;
#pid        logs/nginx.pid;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    upstream  backServer{
      server 192.168.18.166:8080;
      server 192.168.18.166:8081;
  }
    server {
        listen       8099;
        server_name  192.168.166.137;
        location / {
           proxy_pass http://backServer;
           index  index.html index.htm;
        }      
    }
}

4.浏览器请求获取session,浏览器请求http://192.168.162.137:8099/getSession

请求一次 请求二次

可以看到两次Session的id不一致,并不是我们想要的。那该如何解决呢?下面来讲解决方案。

2. 解决方案

解决方案有如下几种:

  • 使用cookie来完成(缺点:不安全,操作不可靠)
  • 使用Nginx中的ip绑定策略,同一个ip只能在指定的同一个机器访问(缺点:不支持负载均衡)
  • 利用数据库同步session(缺点:效率不高)
  • 使用tomcat内置的session同步(缺点:同步可能会产生延迟)
  • 使用token代替session(已经有很好的解决方案了,使用spring-session)
  • 我们使用spring-session以及集成好的解决方案,存放在redis中(推荐)。

3. spring-session

step1:首先引入spring-session的maven依赖:

<!--spring session 与redis应用基本环境配置,需要开启redis后才可以使用,不然启动Spring boot会报错 -->
<dependency>
  <groupId>org.springframework.session</groupId>
  <artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-pool2</artifactId>
</dependency>
<dependency>
  <groupId>redis.clients</groupId>
  <artifactId>jedis</artifactId>
</dependency>

step2:配饰Redis:

spring:
  redis:
    host: 192.168.162.136
    port: 6379
    jedis:
      pool:
        max-idle: 100
        min-idle: 1
        max-active: 1000
        max-wait: -1

step3: 启动类声明允许使用Session共享:

//maxInactiveIntervalInSeconds为SpringSession的过期时间(单位:秒)
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800)
public class AppPortalWeb {
    public static void main(String[] args) {
        SpringApplication.run(AppPortalWeb.class, args);
    }
}

4. 测试

启动项目:

首先浏览器创建session并设置内容到session:http://192.168.162.137:8099/createSession?name=‘ylw’

浏览器请求:http://192.168.162.137:8099/getSession,可以看到两次的sessionid均为:f8b9a9ab-d285-4b04-8d98-66715cbdc132

请求8080 请求8081

打开Medis,可以看到redis已经保存了相关的redis的值:

总结

本文主要讲解分布式环境下,使用spring-session解决session共享的问题。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
2月前
|
NoSQL 调度 Redis
19- 你的项目中哪里用到了分布式锁
在一个项目中,为解决集群环境下SpringTask定时任务的重复执行问题,采用了Redis实现分布式锁来管理任务调度,防止资源浪费。后来因任务量和执行规则增加,以及单节点效率限制,系统改用XXL-JOB,分布式锁不再使用。
39 2
|
2月前
|
存储 负载均衡 NoSQL
分布式Session
分布式Session
22 0
|
2月前
|
存储 缓存 负载均衡
分布式系统Session一致性问题
分布式系统Session一致性问题
41 0
|
18天前
|
NoSQL Java 应用服务中间件
大厂面试必备:如何轻松实现分布式Session管理?
这篇文章介绍三种分布式Session的实现方案:基于JWT的Token、基于Tomcat的Redis和基于Spring的Redis。JWT方案通过生成Token存储用户信息,实现无状态、可扩展的会话管理,但可能增加请求负载且数据安全性较低。Tomcat与Redis结合,通过配置Tomcat和Redis,实现Session集中管理和高性能存储,但配置相对复杂。Spring整合Redis适用于SpringBoot和SpringCloud项目,集成方便,扩展性强,但同样依赖外部Redis服务。每种方法有其优缺点,适用场景不同。作者小米是一个技术爱好者,欢迎关注其微信公众号“软件求生”获取更多技术内容
24 4
|
2月前
|
缓存 NoSQL Java
分布式项目中锁的应用(本地锁-_redis【setnx】-_redisson-_springcache)-fen-bu-shi-xiang-mu-zhong-suo-de-ying-yong--ben-de-suo--redissetnx-springcache-redisson(一)
分布式项目中锁的应用(本地锁-_redis【setnx】-_redisson-_springcache)-fen-bu-shi-xiang-mu-zhong-suo-de-ying-yong--ben-de-suo--redissetnx-springcache-redisson
74 0
|
2月前
|
SpringCloudAlibaba Java 持续交付
【构建一套Spring Cloud项目的大概步骤】&【Springcloud Alibaba微服务分布式架构学习资料】
【构建一套Spring Cloud项目的大概步骤】&【Springcloud Alibaba微服务分布式架构学习资料】
300 0
|
17天前
|
存储 缓存 算法
分布式Session共享解决方案
分布式Session共享解决方案
15 0
|
2月前
|
供应链 算法
基于分布式优化的多产消者非合作博弈能量共享(Matlab代码)
基于分布式优化的多产消者非合作博弈能量共享(Matlab代码)
|
2月前
|
算法 安全
基于价值认同的需求侧电能共享分布式交易策略(matlab完全复现)
基于价值认同的需求侧电能共享分布式交易策略(matlab完全复现)
|
2月前
|
缓存 NoSQL Java
【亮剑】分布式锁是保证多服务实例同步的关键机制,常用于互斥访问共享资源、控制访问顺序和系统保护,如何使用注解来实现 Redis 分布式锁的功能?
【4月更文挑战第30天】分布式锁是保证多服务实例同步的关键机制,常用于互斥访问共享资源、控制访问顺序和系统保护。基于 Redis 的分布式锁利用 SETNX 或 SET 命令实现,并考虑自动过期、可重入及原子性以确保可靠性。在 Java Spring Boot 中,可通过 `@EnableCaching`、`@Cacheable` 和 `@CacheEvict` 注解轻松实现 Redis 分布式锁功能。

热门文章

最新文章