SpringBoot秒杀系统:7.分布式Session设计

冷不防 2023-02-19 10:30 83阅读 0赞

当存在多台服务器时,因为接口不一定映射到哪台服务器,所以利用本机原生Session是不可行的。本节将通过以下三步实现分布式Session
1.为用户生成token作为该用户唯一标识
2.将token与用户信息存入Redis中
3.将此token存入用户cookie中,用户每次访问时携带进入

  1. 生成token
    利用UUIDUUID.randomUUID().toString().replace("-", "")随机生成token

    package com.liuyang.seckill.util;
    import java.util.UUID;
    public class UUIDUtil {

    1. public static String uuid() {
    2. return UUID.randomUUID().toString().replace("-", "");
    3. }

    }

  2. 将token与用户信息存入Redis中

首先设计好Redis中存入的UserKey对象包括前缀和过期时间
并在类中声明一个静态对象方便直接使用

  1. package com.liuyang.seckill.redis;
  2. public class SeckillUserKey extends BasePrefix {
  3. public static final int TOKEN_EXPIRE = 3600*24 * 2;
  4. public SeckillUserKey(int expireSeconds, String prefix) {
  5. super(expireSeconds, prefix);
  6. }
  7. public static SeckillUserKey token = new SeckillUserKey(TOKEN_EXPIRE, "tk");
  8. }

在登陆时将token添加到redis中

  1. String token = UUIDUtil.uuid();
  2. redisService.set(SeckillUserKey.token, token, user);
  1. 将此token存入用户cookie中

设计addCookie函数,在response中令浏览器设置cookie
注意一定要设置有效期cookie.setMaxAge(SeckillUserKey.TOKEN_EXPIRE);否则无法使用

  1. addCookie(response,user);
  2. public boolean addCookie(HttpServletResponse response,SeckillUser user){
  3. String token = UUIDUtil.uuid();
  4. redisService.set(SeckillUserKey.token, token, user);
  5. Cookie cookie = new Cookie(COOKI_NAME_TOKEN,token);
  6. cookie.setMaxAge(SeckillUserKey.TOKEN_EXPIRE);
  7. cookie.setPath("/");
  8. response.addCookie(cookie);
  9. return true;
  10. }

测试,请求中设置了cookie
在这里插入图片描述
跳转下一列表页面是也携带了cookie
在这里插入图片描述

  1. 在Controller中返回该cookie指向的用户
    知识点:利用@RequestParam,@CookieValue这两个注解接收参数
    由于我们不知道请求可能传输cookie的方式,所以我们用两种方式都接收,
    required=false表示该参数可以没有

    @RequestMapping(“/to_list”)

    1. public String list(HttpServletResponse response, Model model,
    2. @RequestParam(value=SeckillUserService.COOKI_NAME_TOKEN,required=false)String parmaToken,
    3. @CookieValue(value=SeckillUserService.COOKI_NAME_TOKEN,required=false)String cookieToken) {
    4. if(StringUtils.isEmpty(parmaToken)&&StringUtils.isEmpty(cookieToken)){
    5. return "login";
    6. }
    7. //由于我们不知道请求可能传输cookie的方式,所以我们用两种都接收,,required=false为非必须
    8. String token = StringUtils.isEmpty(parmaToken)?cookieToken:parmaToken;
    9. SeckillUser user = seckillUserService.getByToken(response,token);
    10. model.addAttribute("user", user);
    11. return "goods_list";
    12. }

访问该用户后,我们为用户的cookie在此延长有效期

  1. public SeckillUser getByToken(HttpServletResponse response, String token) {
  2. //注意判断非法情况!!!
  3. if(StringUtils.isEmpty(token)) {
  4. return null;
  5. }
  6. SeckillUser user = redisService.get(SeckillUserKey.token, token, SeckillUser.class);
  7. //延长有效期
  8. if(user != null) {
  9. addCookie(response, user);
  10. }
  11. return user;
  12. }

测试:我们访问发现可以通过cookie拿到用户信息
在这里插入图片描述

发表评论

表情:
评论列表 (有 0 条评论,83人围观)

还没有评论,来说两句吧...

相关阅读

    相关 SpringBoot系统

    秒杀系统库存 > 今天带来一套秒杀库存扣减 > > 涉及到单体架构和集群架构 希望能给你们带来帮助 我也不想学 但是bgs不教 > 首先讲一下大致的扣减库存的思路

    相关 springboot 系统(一)

    秒杀系统应该是很检验一个人的能力的项目。包括从前端 到运营商到nginx到后端等等,很多地方可以优化。 前端的页面控制,运营商的CDN加速,nginx的动静分离等 下面我

    相关 设计一个系统-方案分析

    学习使用,老鸟飞过,欢迎交流 秒杀系统应该考虑哪些因素 高可用:秒杀系统最大的特点就是并发高,在极短的时间内, 瞬间用户量大。试想一下双11的时候可能会有几十万的用户去