SpringBoot-使用-Redis-实现-Session-共享

SpringBoot 使用 Redis 实现 Session 共享使用 Redis 实现 Session 共享1 什么是 Session由于 HTTP 协议是无状态的协议,因而服务端需要记录用户的状态时,就需要用某种机制来识具体的用户。Session 是另一种记录客户状态的机制,不同的是 Cookie 保存在客户端浏览器中,而 Session 保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上,这就是 Session。客户端浏览器再次访问时只需要从该 Session 中查找该客户的状态就可以了。 2 为什么需要同步session ?当用户量比较大时候一个tomcat可能无法处理更多的请求,超过单个tomcat的承受能力,可能会出现用户等待,严重的导致tomcat宕机。 这时候我们后端可能会采用多个tomcat去处理请求,分派请求,不同请求让多个tomcat分担处理。登录的时候可能采用的是tomca1,下单的时候可能采用的是tomcat2 等等等。 若没有session共享同步,可能在tomcat1登录了,下一次请求被分派到tomcat2上,这时候用户就需要重新登录。 在实际工作中我们建议使用外部的缓存设备来共享 Session,避免单个节点挂掉而影响服务,使用外部缓存 Session 后,我们的共享数据都会放到外部缓存容器中,服务本身就会变成无状态的服务,可以随意的根据流量的大小增加或者减少负载的设备。目前主流的分布式 Session 管理有两种方案。 1 Session 复制部分 Web 服务器能够支持 Session 复制功能,如 Tomcat。用户可以通过修改 Web 服务器的配置文件,让 Web 服务器进行 Session 复制,保持每一个服务器节点的 Session 数据都能达到一致。 这种方案的实现依赖于 Web 服务器,需要 Web 服务器有 Session 复制功能。当 Web 应用中 Session 数量较多的时候,每个服务器节点都需要有一部分内存用来存放 Session,将会占用大量内存资源。同时大量的 Session 对象通过网络传输进行复制,不但占用了网络资源,还会因为复制同步出现延迟,导致程序运行错误。 在微服务架构中,往往需要 N 个服务端来共同支持服务,不建议采用这种方案。 ...

July 1, 2019 · 2 min · jiezi

分布式并发场景下SpringSession(Redis) 的数据脏读问题

问题现象问题来源于一个临时订单重复提交管控场景,通过在Session中写入本次提交的临时订单ID防止同个表单的重复提交。但在用户使用某些浏览器(如QQ浏览器、微信内置浏览器)时,仍有偶发性的重复提交现象。相关核心代码如下:原因分析该问题主要原因是因为当有A、B两个一样的请求时,如果在A还没响应完毕的时候SpringMvc又接收了B请求,B请求在获取Session中的值时,会获取到A请求改写之前的数据。其根本原因在于SpringSession在写入或删除Session属性时,会根据配置中的FlushMode决定在什么时候序列化到Redis,而默认的FlushMode为ON_SAVE,API原文是这样的:也就是说,在默认情况下只有在Response被提交时Session内容才会序列化到Redis。所以导致了并发场景下的Session数据脏读问题解决方案目前我们采取将RedisFlushMode改为IMMEDIATE,修改方法为在@EnableRedisHttpSession注解中指定flushMode:如此修改后,在每次调用removeAttribure后,都能正确的观察到Redis中相应的属性被置为空,问题也就基本得到了解决。

April 15, 2019 · 1 min · jiezi