一、前言
在做电商项目时,很多同学会遇到这个问题:
1.单实例登录正常,部署多台服务器后,用户一会登录、一会未登录
2.用 Nginx 负载均衡,请求落到不同实例,Session 不共享,登录状态丢失
3.用 JWT 无状态方案,但 token 无法主动失效,退出登录要等过期
今天给你一套企业级通用的分布式 Session 共享方案,用 Redis 存储 Session,所有实例共享登录状态,解决多节点部署问题,代码直接复制就能用。
二、引入依赖
<!--SpringSession+Redis--><dependency><groupId>org.springframework.session</groupId><artifactId>spring-session-data-redis</artifactId></dependency><!--Redis客户端--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>三、Redis 配置(application.yml)
spring:redis:host:127.0.0.1port:6379password:database:0session:store-type:redis timeout:1800#Session超时时间,单位秒(30分钟)四、开启 Redis Session(启动类加注解)
importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;importorg.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;@SpringBootApplication@EnableRedisHttpSession(maxInactiveIntervalInSeconds=1800)publicclassShopApplication{publicstaticvoidmain(String[]args){SpringApplication.run(ShopApplication.class,args);}}五、登录接口(和原来一样,不用改业务代码)
@PostMapping("/login")publicResultlogin(Stringusername,Stringpassword,HttpSessionsession){// 1. 校验用户名密码Useruser=userService.getByUsername(username);if(user==null||!passwordEncoder.matches(password,user.getPassword())){returnResult.fail("用户名或密码错误");}// 2. 登录成功,存入 Sessionsession.setAttribute("userId",user.getId());session.setAttribute("username",user.getUsername());returnResult.success("登录成功");}六、登录校验拦截器(Session 方式)
@ComponentpublicclassLoginInterceptorimplementsHandlerInterceptor{@OverridepublicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler)throwsException{HttpSessionsession=request.getSession();ObjectuserId=session.getAttribute("userId");if(userId==null){response.setContentType("application/json;charset=UTF-8");response.getWriter().write(JSON.toJSONString(Result.fail(401,"请先登录")));returnfalse;}returntrue;}}七、拦截器注册
@ConfigurationpublicclassWebConfigimplementsWebMvcConfigurer{@OverridepublicvoidaddInterceptors(InterceptorRegistryregistry){registry.addInterceptor(newLoginInterceptor()).addPathPatterns("/**").excludePathPatterns("/login","/register","/error");}}八、效果演示
1.多台服务器部署,Session 存在 Redis 中,所有实例共享
2.用户在实例 A 登录,请求落到实例 B 也能识别登录状态
3.调用 session.invalidate() 直接清掉 Redis 中的 Session,实现主动登出
4.超时自动失效,和单机 Session 体验完全一致
九、适用场景
1.电商系统集群部署
2.前后端分离项目多实例
3.需要主动失效登录状态的场景
4.不想改业务代码,从单机平滑升级到分布式
十、优点对比
十一、总结
分布式 Session 共享是电商项目从单机走向集群的关键一步,也是面试高频考点。这套方案完全兼容传统 Session API,不用改业务代码,就能实现分布式部署,解决登录状态丢失问题,毕设和企业项目都非常加分。
互动引导
你现在的电商项目是单机部署还是准备做集群?评论区说说你的部署方式,我帮你优化成分布式架构!
有用点赞 + 收藏,关注我持续更新 SpringBoot 电商项目实战干货!