分布式应用中session会话管理-基于redis

在分布式应用中,session会话管理成为一个挑战。本文介绍了多种解决方案,包括基于cookie、数据库、服务器复制、Nginx绑定IP以及NoSql存储(如memcache和redis)。重点讨论了使用redis作为session存储的实现,包括使用spring-session框架和自定义Shiro的SessionDao。还解释了HTTP请求无状态的特性,以及如何通过拦截请求并在Redis中操作session来实现会话共享。
摘要由CSDN通过智能技术生成

session会话在单台服务器的情况下不会出现共享问题,然而在集群或者分布式应用中,则会出现session共享问题。

解决方案

  1. 基于cookie存储,但是存在安全问题;
  2. 基于数据库存储,用户量大的情况下对db压力大;
  3. 服务器内置的session复制,如was提供复制功能,但是会损耗服务器内存;
  4. 采用Nginx请求分发,绑定ip,只能访问用户第一次访问的服务器,不能支持负载均衡;
  5. 基于noSql,如memcache,redis等;
  6. 使用框架的会话管理工具 spring-session(使用了spring-data-redis连接池,项目使用spring framework时才可以);
  7. 如果项目中使用shiro这种自带session(非httpsession)的权限框架,需要重写shiro的SessionDao将session存入redis(或其他)来实现session共享,可以自己重写(也不是很麻烦)或者找现成的(shiro-redis)。

HTTP请求是无状态的

客户端首次访问时,会创建一个session对象,并生成一个sessionId,在此次响应中将sessionId以响应报文的方式些回客户端浏览器内存或以重写url方式送回客户端,来保持整个会话。
也就是说客户端request请求时候,如果获取了session,就默认分配一个jessionid,然后通过response响应到客户端cookie,然后客户端下一次请求,默认会携带这个jessionid请求到服务端,服务端拿到这个jessionid来区分不同的客户端。

具体实现

1)原理:写一个Session过滤器拦截每一次请求,在这里检查由Cookie生成的SessionID,进行创建或获取。核心是实现使用装饰类,实现Session在Redis中的存取操作。
2)此处存取方式为 sessionID+sessionKey作为Redis的key ==== sessionValue作为Redis的value,这样保存了每次存取都从Redis中操作,效率更高。
3)注意:序列化方式推荐使用Apache下Commons组件——SerializationUtils 或 org.springframework.util.SerializationUtils

//定义请求经过的Session过滤器
public class SessionFilter extends OncePerRequestFilter implements Filter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        // 从cookie中获取sessionId,如果此次请求没有sessionId,重写为这次请求设置一个sessionId
        String sid &
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值