分布式的几件小事(十一)分布式session如何实现

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: 分布式session如何实现

1.分布式会话是什么?

首先,我们知道浏览器有个cookie,在一段时间内这个cookie都存在,然后每次发请求过来都带上一个特殊的jsessionid cookie,就根据这个东西,在服务端可以维护一个对应的session域,里面可以放点儿数据。


其次,单系统的时候session是不存在问题的。


分布式系统出现session问题的场景:

比如系统部署了3台机器,用户登录的时候,负载均衡到了其中的一台机器上面,登录成功在这台机器上面创了session,保存了用户的登录信息,然后用户进行了两外一个操作,这时候通过负载均衡到了另外一台机器上面去,这台机器上面是没有客户的session的,那么就会出现用户没有登录的情况,又会让用户去登陆,这样就会造成系统无法使用。

18.png

2.如何解决

tomcat+redis方案

这个其实还挺方便的,就是使用session的代码跟以前一样,还是基于tomcat原生的session支持即可,然后就是用一个叫做Tomcat RedisSessionManager的东西,让所有我们部署的tomcat都将session数据存储到redis即可。


在tomcat的配置文件中,配置一下

<ValveclassName="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve"/><ManagerclassName="com.orangefunction.tomcat.redissessions.RedisSessionManager"host="{redis.host}"port="{redis.port}"database="{redis.dbnum}"maxInactiveInterval="60"/>

还可以用基于redis哨兵支持的redis高可用集群来保存session数据,都是ok的.

<ValveclassName="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve"/><ManagerclassName="com.orangefunction.tomcat.redissessions.RedisSessionManager"sentinelMaster="mymaster"sentinels="<sentinel1-ip>:26379,<sentinel2-ip>:26379,<sentinel3-ip>:26379"maxInactiveInterval="60"/>


spring session+redis方案

分布式会话的东西和容器耦合在一起,比如要将tomcat容器迁移成jetty,就需要修改session同步的配置,这样会比较麻烦。


可以使用spring的解决方案spring session,使用方法如下

1.在pom中引入依赖

<dependency><groupId>org.springframework.session</groupId><artifactId>spring-session-data-redis</artifactId><version>1.2.1.RELEASE</version></dependency><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.8.1</version></dependency>

2.配置spring配置文件

<beanid="redisHttpSessionConfiguration"class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration"><propertyname="maxInactiveIntervalInSeconds"value="600"/></bean><beanid="jedisPoolConfig"class="redis.clients.jedis.JedisPoolConfig"><propertyname="maxTotal"value="100"/><propertyname="maxIdle"value="10"/></bean><beanid="jedisConnectionFactory"class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"destroy-method="destroy"><propertyname="hostName"value="${redis_hostname}"/><propertyname="port"value="${redis_port}"/><propertyname="password"value="${redis_pwd}"/><propertyname="timeout"value="3000"/><propertyname="usePool"value="true"/><propertyname="poolConfig"ref="jedisPoolConfig"/></bean>

3.修改web.xml

<filter><filter-name>springSessionRepositoryFilter</filter-name><filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class></filter><filter-mapping><filter-name>springSessionRepositoryFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>

使用示例:

@Controller@RequestMapping("/test")
publicclassTestController {
@RequestMapping("/putIntoSession")
@ResponseBodypublicStringputIntoSession(HttpServletRequestrequest, Stringusername){
request.getSession().setAttribute("name",  “leo”);
return"ok";
    }
@RequestMapping("/getFromSession")
@ResponseBodypublicStringgetFromSession(HttpServletRequestrequest, Modelmodel){
Stringname=request.getSession().getAttribute("name");
returnname;
    }
}

上面的代码就是ok的,给sping session配置基于redis来存储session数据,然后配置了一个spring session的过滤器,这样的话,session相关操作都会交给spring session来管了。接着在代码中,就用原生的session操作,就是直接基于spring sesion从redis中获取数据了。


实现分布式的会话,有很多种很多种方式,我说的只不过比较常见的两种方式,tomcat + redis早期比较常用;近些年,重耦合到tomcat中去,通过spring 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
相关文章
|
1月前
|
存储 缓存 负载均衡
分布式系统Session一致性问题
分布式系统Session一致性问题
32 0
|
4月前
|
负载均衡 算法 NoSQL
聊聊分布式应用中负载均衡技术和Session一致性
聊聊分布式应用中负载均衡技术和Session一致性
40 0
|
5月前
|
负载均衡 算法 NoSQL
分布式系列教程(15) - 解决分布式Session一致性问题
分布式系列教程(15) - 解决分布式Session一致性问题
54 0
|
7月前
|
存储 缓存 NoSQL
Shiro 解决分布式 Session
在分布式系统中,会话管理是一个重要的问题。Shiro框架提供了一种解决方案,通过其会话管理组件来处理分布式会话。本文演示通过RedisSessionManager解决分布式会话问题。
54 0
|
7月前
|
存储 NoSQL Java
Spring Session分布式会话管理
Spring Session分布式会话管理
50 0
|
5月前
|
负载均衡 NoSQL Java
淘东电商项目(30) -解决分布式Session共享问题
淘东电商项目(30) -解决分布式Session共享问题
38 0
|
5月前
|
NoSQL 应用服务中间件 Redis
面试官:分布式环境下,如何实现session共享
随着互联网公司的项目在微服务和分布式的环境下进行的搭建,导致一个项目可能分别部署在几个甚至很多的服务器集群下,此时就会出现一个问题:
|
6月前
|
存储 NoSQL Java
场景应用:利用Redis实现分布式Session
场景应用:利用Redis实现分布式Session
397 0
|
10月前
|
存储 负载均衡 算法
分布式session
1.什么是session HTTP是无状态的,session是一种会话保持技术,目的就是以一种方式来记录http请求之间需要传递、交互的数据。 不是每次http请求都会产生的新的session,而是在服务端手动创建的,例如HttpServletRequest.getSession(true)。 session创建后会返回给客户端sessionID,sessionID会以cookie的形式携带在后续的请求中,直到浏览器关闭,一次会话结束。
40 0
|
11月前
|
存储 JSON NoSQL
Spring Session - 使用Spring Session从零到一构建分布式session
Spring Session - 使用Spring Session从零到一构建分布式session
149 0

热门文章

最新文章