系列博客目录
文章目录
1.使用 Redis 解决集群模式下的 Session 共享问题
集群的session共享问题
session共享问题:多台Tomcat并不共享session存储空间,当请求切换到不同tomcat服务时导致数据丢失的问题。
session的替代方案应该满足:
- 数据共享
- 内存存储
- key、value结构
如下图所示,以前是保存到session现在是Redis。
如下图所示,之前是请求并携带cookie,从session中获取用户。
@PostMapping("code")
public Result sendCode(@RequestParam("phone") String phone, HttpSession session) {
// 发送短信验证码并保存验证码
return userService.sendCode(phone,session);
}
@PostMapping("/login")
public Result login(@RequestBody LoginFormDTO loginForm, HttpSession session){
// 实现登录功能
return userService.login(loginForm, session);
}
@Override
public Result sendCode(String phone, HttpSession session) {
// 1.校验手机号
if (!RegexUtils.isCodeInvalid(phone)) {
// 2.如果不符合,返回错误信息。
return Result.fail("手机号格式错误");
}
// 3.符合,生成验证码
String code = RandomUtil.randomNumbers(6);
// 4.保存验证码到redis
stringRedisTemplate.opsForValue().set(LOGIN_CODE_KEY + phone,code,LOGIN_CODE_TTL, TimeUnit.MINUTES);
// session.setAttribute("code", code);
// 5.发送验证码,这里不调用第三方了,不是讲解的重点
log.debug("发送短信验证码成功,验证码{}", code);
// 6.返回ok
return Result.ok();
}
@Override
public Result login(LoginFormDTO loginForm, HttpSession session) {
// 1.校验手机号
String phone = loginForm.getPhone();
if(RegexUtils.isPhoneInvalid(phone)){
// 2.如果不符合,返回错误信息
return Result.fail("手机号格式错误");
}
// 3.从redis获取验证码并校验
String cacheCode = stringRedisTemplate.opsForValue().get(LOGIN_CODE_KEY + phone);
// Object cacheCode = session.getAttribute("code");
String code = loginForm.getCode();
if(cacheCode == null || !cacheCode.equals(code)){
// 3.不一致
return Result.fail("验证码错误");
}
// 4.一致
User user = query().eq("phone",phone).one();
// 5.判断用户是否存在
if(user == null){
// 6.不存在,创建新用户并保存
user = createUserWithPhone(phone);
}
// 7.保存用户信息到redis中
// 7.1.随机生成Token
String token = UUID.randomUUID().toString(true);
// 7.2.将User对象转为HashMap存储
UserDTO userDTO = BeanUtil.copyProperties(user, UserDTO.class);
Map<String, Object