SpringBoot秒杀系统:7.分布式Session设计
当存在多台服务器时,因为接口不一定映射到哪台服务器,所以利用本机原生Session是不可行的。本节将通过以下三步实现分布式Session
1.为用户生成token作为该用户唯一标识
2.将token与用户信息存入Redis中
3.将此token存入用户cookie中,用户每次访问时携带进入
生成token
利用UUIDUUID.randomUUID().toString().replace("-", "")
随机生成tokenpackage com.liuyang.seckill.util;
import java.util.UUID;
public class UUIDUtil {public static String uuid() {
return UUID.randomUUID().toString().replace("-", "");
}
}
将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);
- 将此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
在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拿到用户信息
还没有评论,来说两句吧...