问:集群环境下Session共享,说四招?

在单服务器环境下,Session的管理相对简单,因为所有的访问都会到达唯一的服务器上。然而,在集群环境下,多台服务器共同处理用户的请求,这就引出了Session共享存储的问题。如果用户的请求被不同的服务器处理,而这些服务器之间没有共享Session的机制,就会导致用户每次请求都可能需要重新登录,严重影响用户体验,并增加服务器的运行压力。

粘性Session(Sticky Session)

原理

粘性Session是指负载均衡器(如Nginx)将特定用户的后续请求始终发送到同一个服务器上。这样,用户的Session数据就可以保存在该服务器上,避免了跨服务器传输Session数据的问题。

示例

以Nginx为例,可以通过添加ip_hash配置来实现粘性Session。假设集群中有两台服务器A和B,配置如下:

upstream myserver {ip_hash;server 127.0.0.1:8080;server 127.0.0.1:8081;
}server {listen 81;server_name www.bproject.com;location / {proxy_pass http://myserver;}
}

在上述配置中,ip_hash指令确保了同一个IP的请求会被发送到同一个服务器。例如,用户的第一次请求被转发到服务器A,那么该用户的后续请求都会被转发到服务器A,从而保证了Session的一致性。

服务器Session复制

原理

服务器Session复制是指每次Session发生变化时(如创建或修改),就将这个变化广播给集群中的所有服务器,使所有服务器上的Session数据保持一致。

示例

以Tomcat为例,可以通过配置Tomcat的Cluster功能来实现Session复制。在server.xml文件中添加如下配置:

<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>

此外,还需要确保集群中的所有Tomcat服务器都能够相互通信,并且配置了相同的Manager和Replicator组件。这样,当一个Tomcat服务器上的Session发生变化时,就会将这个变化复制到其他Tomcat服务器上。

Session共享(缓存Session)

原理

Session共享是指将Session数据存储在一个集中的缓存系统中,如Redis或Memcached。所有服务器都从这个缓存系统中读取和写入Session数据,从而实现了Session的共享。

示例

以Spring Boot和Redis为例,可以通过以下步骤实现Session共享:

  1. 引入依赖

    pom.xml文件中添加Spring Boot和Redis的依赖:

    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-redis</artifactId>
    </dependency>
    <dependency><groupId>org.springframework.session</groupId><artifactId>spring-session-data-redis</artifactId>
    </dependency>
    
  2. 配置Redis

    application.properties文件中配置Redis的连接信息:

    spring.redis.host=localhost
    spring.redis.port=6379
    
  3. 创建Session配置类

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
    import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;@Configuration
    @EnableRedisHttpSession
    public class SessionConfig {@Beanpublic JedisConnectionFactory connectionFactory() {JedisConnectionFactory connectionFactory = new JedisConnectionFactory();connectionFactory.setHostName("localhost");connectionFactory.setPort(6379);return connectionFactory;}
    }
    
  4. 初始化Session

    import org.springframework.session.web.http.AbstractHttpSessionApplicationInitializer;public class SessionInitializer extends AbstractHttpSessionApplicationInitializer {public SessionInitializer() {super(SessionConfig.class);}
    }
    
  5. 编写控制器

    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpSession;@RestController
    public class SessionController {@Value("${server.port}")private String PORT;@RequestMapping("/setSession")public String setSession(HttpServletRequest request, String sessionKey, String sessionValue) {HttpSession session = request.getSession(true);session.setAttribute(sessionKey, sessionValue);return "success,port:" + PORT;}@RequestMapping("/getSession")public String getSession(HttpServletRequest request, String sessionKey) {HttpSession session = request.getSession(false);String value = null;if (session != null) {value = (String) session.getAttribute(sessionKey);}return "sessionValue:" + value + ",port:" + PORT;}
    }
    

通过上述步骤,Spring Boot应用就可以将Session数据存储在Redis中,实现了集群环境下的Session共享。

Session持久化(存储至数据库)

原理

Session持久化是指将Session数据存储到数据库中,像操作数据一样操作Session。这样,即使服务器重启或发生故障,Session数据也不会丢失。

示例

以Spring Boot和MySQL为例,可以通过以下步骤实现Session持久化:

  1. 引入依赖

    pom.xml文件中添加Spring Boot和MySQL的依赖:

    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId>
    </dependency>
    
  2. 配置数据库连接

    application.properties文件中配置MySQL的连接信息:

    spring.datasource.url=jdbc:mysql://localhost:3306/sessiondb
    spring.datasource.username=root
    spring.datasource.password=root
    spring.jpa.hibernate.ddl-auto=update
    
  3. 创建Session实体类

    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;@Entity
    public class SessionEntity {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String sessionId;private String sessionData;// Getters and Setters
    }
    
  4. 创建SessionRepository

    import org.springframework.data.jpa.repository.JpaRepository;public interface SessionRepository extends JpaRepository<SessionEntity, Long> {SessionEntity findBySessionId(String sessionId);
    }
    
  5. 编写Session管理逻辑

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpSession;
    import javax.servlet.http.HttpSessionEvent;
    import javax.servlet.http.HttpSessionListener;@Service
    public class SessionManager implements HttpSessionListener {@Autowiredprivate SessionRepository sessionRepository;@Overridepublic void sessionCreated(HttpSessionEvent se) {HttpSession session = se.getSession();SessionEntity sessionEntity = new SessionEntity();sessionEntity.setSessionId(session.getId());sessionEntity.setSessionData(session.getAttributeNames().toString());sessionRepository.save(sessionEntity);}@Overridepublic void sessionDestroyed(HttpSessionEvent se) {HttpSession session = se.getSession();SessionEntity sessionEntity = sessionRepository.findBySessionId(session.getId());if (sessionEntity != null) {sessionRepository.delete(sessionEntity);}}
    }
    
  6. 注册SessionListener

    applicationContext.xml文件中注册SessionManager作为SessionListener:

    <bean id="sessionManager" class="com.example.SessionManager"/>
    <listener><listener-class>com.example.SessionManager</listener-class>
    </listener>
    

通过上述步骤,Spring Boot应用就可以将Session数据持久化到MySQL数据库中,实现了集群环境下的Session持久化。

结尾

集群环境下的Session共享存储是一个重要的问题,它关系到用户体验和服务器性能。笔者总结了四种解决方案:粘性Session、服务器Session复制、Session共享(缓存Session)和Session持久化(存储至数据库)。每种方案都有其优缺点和适用场景,可以根据实际需求选择合适的方案进行实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/4318.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

如何才能实时监测Mac的运行状态

实时监测Mac的运行状态&#xff0c;能够让我们更好的了解Mac的情况&#xff0c;因此如何才能监测Mac的运行状态很重要 State&#xff0c;实时监测你的Mac运行状态&#xff0c;能够直观的展示当前Mac的CPU、内存、硬盘、温度、风扇、网络信息以及开机时间等重要信息 除此之外&a…

强化学习介绍

目录标题 一、什么是强化学习二、强化学习的环境三、强化学习的目标四、强化学习中的数据从哪里来五、强化学习的独特性 一、什么是强化学习 强化学习是机器通过与环境交互来实现目标的一种计算方法。 机器和环境的一轮交互是指&#xff0c;机器在环境的一个状态下做一个动作决…

【算法】【优选算法】滑动窗口(上)

目录 一、滑动窗口简介二、209.⻓度最⼩的⼦数组2.1 滑动窗口2.2 暴力枚举 三、3.⽆重复字符的最⻓⼦串3.1 滑动窗口3.2 暴力枚举 四、1004.最⼤连续1的个数III4.1 滑动窗口4.2 暴力枚举 五、1658.将x减到0的最⼩操作数5.1 滑动窗口5.2 暴力枚举 一、滑动窗口简介 其实就是利用…

软考高级之系统架构师系列之构件开发模型

如标题所述&#xff0c;本文面向于软考高级&#xff0c;具体来说是系统架构师。 有些概念&#xff0c;如生命周期&#xff0c;开发的几个阶段&#xff0c;不同的教程有些许出入。 本文偏理论&#xff0c;要在理解的基础上加以记忆&#xff0c;用于应付软考&#xff0c;有些地…

机器人零位、工作空间、坐标系及其变换,以UR5e机器人为例

机器人中的主要坐标系 在机器人中&#xff0c;常用的坐标系包括&#xff1a; 基坐标系&#xff08;Base Frame&#xff09;&#xff1a;固定在机器人基座上的坐标系&#xff0c;用于描述机器人的整体位置和方向&#xff0c;是其他所有坐标系的参考点。 连杆坐标系&#xff08…

VMWARE ESXI VMFS阵列故障 服务器数据恢复

1&#xff1a;河南用户一台DELL R740 3块2.4T硬盘组的RAID5&#xff0c;早期坏了一个盘没有及时更换&#xff0c;这次又坏了一个&#xff0c;导致整组RAID5处于数据丢失的状态&#xff0c; 2&#xff1a;该服务器装的是VMware ESXI 6.7&#xff0c;用户把3块硬盘寄过来进行数据…

程序员开发速查表

作为一名苦逼的程序员&#xff0c;在开发的过程中&#xff0c;我们总是在各种编程语言中来回穿梭&#xff0c;忙完后端整前端&#xff0c;还得做一部分的运维工作&#xff0c;忙的我们有时候忘记语法&#xff0c;忘记编写规则&#xff0c;甚至混淆。这时候我们就希望有一个综合…

「Mac畅玩鸿蒙与硬件30」UI互动应用篇7 - 简易计步器

本篇将带你实现一个简易计步器应用&#xff0c;用户通过点击按钮增加步数并实时查看步数进度&#xff0c;目标步数为 10000 步。该项目示例展示了如何使用 Progress 组件和 Button 组件&#xff0c;并结合状态管理&#xff0c;实现交互式应用。 关键词 UI互动应用计步器Button…

直播系统搭建教程安装说明

需要安装的软件(宝塔【软件商店】中查找安装): 1.PHP7.0 ~ PHP7.3 需要安装的扩展:(宝塔【PHP管理】【安装扩展】中安装) *PDO PHP Extension * MBstring PHP Extension * CURL PHP Extension * Mylsqi PHP Extension * Redis PHP Extension * fileinfo PHP Extension …

@Async注解提升Spring Boot项目中API接口并发能力

文章目录 同步调用异步调用1: 启用异步支持2: 修改 Task 类异步回调基本概念使用 Future<String>使用 CompletableFuture<String>Future<String> 和 CompletableFuture<String>区别1. 基本概念2. 主要区别同步调用 同步调用是最直接的调用方式,调用方…

对齐自治 Aligned autonomy

对于有效的产品开发&#xff0c;我们想要的自主权不是 “随心所欲” &#xff0c;而是一种自主权&#xff0c;使团队能够自由行动&#xff0c;利用他们所有的能力朝着集体成果前进。这也称为“对齐自治”。 Aligned autonomy 2x2&#xff0c;来自 Spotify 的 Henrik Kniberg 工…

Spring Boot 与 Vue 共筑二手书籍交易卓越平台

作者介绍&#xff1a;✌️大厂全栈码农|毕设实战开发&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。 &#x1f345;获取源码联系方式请查看文末&#x1f345; 推荐订阅精彩专栏 &#x1f447;&#x1f3fb; 避免错过下次更新 Springboot项目精选实战案例 更多项目…

物理验证Calibre LVS Debug案例之通过deleteEmptyModule解决LVS问题

上周帮助T12nm A55训练营学员debug一个Calibre LVS问题&#xff0c;小编觉得挺好的一个问题。这个问题之前没有遇到过&#xff0c;今天分享给大家。 数字IC后端先进工艺设计实现之TSMC 12nm 6Track工艺数字IC后端实现重点难点盘点 下图所示为Calibre LVS的报告。从报告中看到…

【系统面试篇】进程与线程类(2)(笔记)——进程调度、中断、异常、用户态、核心态

目录 一、相关面试题 1. 进程的调度算法有哪些&#xff1f; 调度原则 &#xff08;1&#xff09;先来先服务调度算法 &#xff08;2&#xff09;最短作业优先调度算法 &#xff08;3&#xff09;高响应比优先调度算法 &#xff08;4&#xff09;时间片轮转调度算法 &am…

这下热闹了:电商巨头粗暴杀入物流自动化领域

导语 大家好&#xff0c;我是社长&#xff0c;老K。专注分享智能制造和智能仓储物流等内容。 在全球物流行业竞争日趋白热化的今天&#xff0c;一向以互联网和电商见长的阿里巴巴集团旗下菜鸟&#xff0c;突然以一记重拳杀入物流自动化设备领域。 其自主研发的直线窄带分拣机不…

新安装的Ubuntu 24.04.1安装Python模块报错?(error: externally-managed-environment)

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 文章内容 📒📝 错误现象及原因📝 解决方案1. **创建虚拟环境**创建虚拟环境的步骤:2. **使用 pipx 管理应用**安装 `pipx`:3. **直接覆盖安装(不推荐)**4. **使用 `apt` 安装系统级包**📝 总结⚓️ 相关链接 ⚓️�…

前后端分离,Jackson,Long精度丢失

案例:后端接口放回一个Long数据 GetMapping("/testForLong")public Map<String, Object> testForLong() {Map<String, Object> map new HashMap<>();map.put("aaa", 1234567890123456789L);return map;}实际前端接收的数据 前后端数据…

【主机游戏】森林之子游戏介绍

《森林之子》是一款开放世界恐怖生存模拟游戏&#xff0c;玩家被派到孤岛上寻找失踪的亿万富翁&#xff0c;却陷入被食人生物占领的炼狱之地。他一经上线不仅饱受好评&#xff0c;还被玩家开发出来众多奇奇怪怪的玩法 https://pan.quark.cn/s/f903c978b071 当然他里边包含不限…

解线性方程组(一)

实验类型&#xff1a;●验证性实验 ○综合性实验 ○设计性实验 实验目的&#xff1a;进一步熟练掌握高斯顺序消去法解线性方程组的算法并编写程序&#xff0c;进一步熟练掌握高斯列主元消去法解线性方程组的算法并编写程序&#xff0c;提高编程能力和解算线性方程组问题的实践…

Ubuntu使用Qt虚拟键盘,支持中英文切换

前言 ​最近领导给了个需求&#xff0c;希望将web嵌入到客户端里面&#xff0c;做一个客户端外壳&#xff0c;可以控制程序的启动、停止、重启&#xff0c;并且可以调出键盘在触摸屏上使用(我们的程序虽然是BS架构&#xff0c;但程序还是运行在本地工控机上的)&#xff0c;我研…