在说明Redis如何解决session共享问题之前,先要明白何为session共享问题?
什么是session共享问题?
多台服务器之间并不共享session的存储空间也就是多态服务器不能共享存储在session中的数据,当请求发送到不同的服务器时就会存在数据丢失问题。因为session存储是单点的存储在当前服务器的内存当中,并不能供其他服务器使用。
例如:用户身份登录验证,当用户登录请求被负载均衡到第一台服务器时,用户身份验证成功后。用户的一些基本信息就会被缓存在第一台服务的session中。如果当前用户的其他请求访问第一台之外的服务器时,需要用户基本信息或者进行身份验证就会因为session不共享而获取不到用户基本信息或者身份验证不通过。
public Result login(LoginFormDTO loginForm, HttpSession session) {
//1.获取信息
String phone = loginForm.getPhone();//手机号码
String code = loginForm.getCode();//验证码
Object catchCode = session.getAttribute("code");//缓存的验证码
//2.验证手机号码格式
if (RegexUtils.isPhone(phone)){
return Result.fail("手机号码格式错误");
}
//3.验证验证码
if (catchCode==null||!catchCode.toString().equals(code)){
return Result.fail("验证码错误");
}
//4.根据手机号码查询用户,用户不存在就添加
User user = query().eq("phone", phone).one();
if (user==null){
user = createUserByPhone(phone);
}
//5.将用户信息保存到session中
session.setAttribute("user", user);
return Result.ok();
}
上述代码就是将用户一些基本信息保存在session当中,而当用户访问其他服务器时就存在身份验证不通过的问题
如何解决session共享问题呢?
第一种方案就是session拷贝,在Tomcat服务器就提供了session拷贝的这种方案,当某一台Tomcat对session中的信息进行了修改都会同步给其他Tomcat,这样session就可以共享。但是session拷贝存在一些问题。
- 每一台服务器都会存储一份完整的session,服务器的压力就会增大,也会存在内存浪费的问题
- session拷贝数据时存在延迟就可能照成数据丢失问题。
第二种方案就是redis,选择redis的原因其实有很多,首先redis中存储的数据能够共享就解决了session不能共享的问题。其次session和redis的一些特性,session存储在服务器的内存当中而redis也具备内存存储并且具有数据持久化的功能。并且sesssion存储的时候是一种key-value结构而redis同样为key-value。