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

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 淘东电商项目(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
目录
相关文章
|
6月前
|
NoSQL Java 应用服务中间件
大厂面试必备:如何轻松实现分布式Session管理?
这篇文章介绍三种分布式Session的实现方案:基于JWT的Token、基于Tomcat的Redis和基于Spring的Redis。JWT方案通过生成Token存储用户信息,实现无状态、可扩展的会话管理,但可能增加请求负载且数据安全性较低。Tomcat与Redis结合,通过配置Tomcat和Redis,实现Session集中管理和高性能存储,但配置相对复杂。Spring整合Redis适用于SpringBoot和SpringCloud项目,集成方便,扩展性强,但同样依赖外部Redis服务。每种方法有其优缺点,适用场景不同。作者小米是一个技术爱好者,欢迎关注其微信公众号“软件求生”获取更多技术内容
267 4
|
2月前
|
存储 缓存 NoSQL
分布式架构下 Session 共享的方案
【10月更文挑战第15天】在实际应用中,需要根据具体的业务需求、系统架构和性能要求等因素,选择合适的 Session 共享方案。同时,还需要不断地进行优化和调整,以确保系统的稳定性和可靠性。
|
3月前
|
NoSQL Java Redis
面试官:项目中如何实现分布式锁?
面试官:项目中如何实现分布式锁?
100 6
面试官:项目中如何实现分布式锁?
|
3月前
|
存储 NoSQL Java
使用springSession完成分布式session
本文介绍了如何使用 `spring-session` 实现分布式 Session 管理,并提供了将 Session 存储在 Redis 中的具体配置示例。通过配置相关依赖及 Spring 的配置文件,可以轻松实现 Session 的分布式存储。示例中详细展示了所需的 Maven 依赖、Spring 配置及过滤器配置,并给出了启动项目后在 Redis 中查看 Session 数据的方法。
|
4月前
|
存储 NoSQL Java
一天五道Java面试题----第十一天(分布式架构下,Session共享有什么方案--------->分布式事务解决方案)
这篇文章是关于Java面试中的分布式架构问题的笔记,包括分布式架构下的Session共享方案、RPC和RMI的理解、分布式ID生成方案、分布式锁解决方案以及分布式事务解决方案。
一天五道Java面试题----第十一天(分布式架构下,Session共享有什么方案--------->分布式事务解决方案)
|
4月前
|
资源调度 Java 调度
项目环境测试问题之Schedulerx2.0通过分布式分片任务解决单机计算瓶颈如何解决
项目环境测试问题之Schedulerx2.0通过分布式分片任务解决单机计算瓶颈如何解决
项目环境测试问题之Schedulerx2.0通过分布式分片任务解决单机计算瓶颈如何解决
|
4月前
|
Oracle Java 关系型数据库
分布式锁设计问题之由于GC导致的Client同时操作共享资源的问题如何解决
分布式锁设计问题之由于GC导致的Client同时操作共享资源的问题如何解决
|
4月前
|
存储 缓存 开发框架
看看 Asp.net core Webapi 项目如何优雅地使用分布式缓存
看看 Asp.net core Webapi 项目如何优雅地使用分布式缓存
|
5月前
|
SQL NoSQL Java
如何在Java项目中实现分布式锁
如何在Java项目中实现分布式锁
|
5月前
|
消息中间件 Java 中间件
如何在Java项目中实现分布式事务管理
如何在Java项目中实现分布式事务管理
下一篇
DataWorks