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

分布式Session管理
本文介绍了一种基于Redis的分布式Session管理方案,通过生成唯一token并存储于Redis,实现在多服务器环境下的用户会话状态共享。

当存在多台服务器时,因为接口不一定映射到哪台服务器,所以利用本机原生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 {
	public static String uuid() {
		return UUID.randomUUID().toString().replace("-", "");
	}
}
  1. 将token与用户信息存入Redis中

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

package com.liuyang.seckill.redis;

public class SeckillUserKey extends BasePrefix {


    public static final int TOKEN_EXPIRE = 3600*24 * 2;

    public SeckillUserKey(int expireSeconds, String prefix) {
        super(expireSeconds, prefix);
    }
    public static SeckillUserKey token = new SeckillUserKey(TOKEN_EXPIRE, "tk");
}

在登陆时将token添加到redis中

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

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

	addCookie(response,user);
	public boolean addCookie(HttpServletResponse response,SeckillUser user){
		String token = UUIDUtil.uuid();
		redisService.set(SeckillUserKey.token, token, user);
		Cookie cookie = new Cookie(COOKI_NAME_TOKEN,token);
		cookie.setMaxAge(SeckillUserKey.TOKEN_EXPIRE);
		cookie.setPath("/");
		response.addCookie(cookie);
		return true;
	}

测试,请求中设置了cookie
在这里插入图片描述
跳转下一列表页面是也携带了cookie
在这里插入图片描述
4. 在Controller中返回该cookie指向的用户
知识点:利用@RequestParam,@CookieValue这两个注解接收参数
由于我们不知道请求可能传输cookie的方式,所以我们用两种方式都接收,
required=false表示该参数可以没有

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

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

	public SeckillUser getByToken(HttpServletResponse response, String token) {
		//注意判断非法情况!!!
		if(StringUtils.isEmpty(token)) {
			return null;
		}
		SeckillUser user = redisService.get(SeckillUserKey.token, token, SeckillUser.class);
		//延长有效期
		if(user != null) {
			addCookie(response, user);
		}
		return user;
	}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值