Redis学习笔记<一>
一、ThreadLocal解耦Sessoin
当tomcat端的socket接受到数据后,此时监听线程会从tomcat的线程池中取出一个线程执行用户请求,在我们的服务部署到tomcat后,线程会找到用户想要访问的工程,然后用这个线程转发到工程中的controller,service,dao中,并且访问对应的数据库,即可以将每次请求当作一个独立线程。ThreadLocal可以做到线程隔离, 保存每个请求自己独立的数据,并且能够做到线程隔离;
ThreadLocal一般和登陆拦截器一起搭配使用, 每次请求时通过拦截器从Session域中获取数据, 存入ThreadLocal中。需要额外注意的是: 每次请求完毕之后,得清空ThreadLocal中的数据,防止缓存泄漏问题;具体方法是在拦截器的afterCompletion方法中添加ThreadLocal.remove()方法。不要拦截器的话,每次新的请求threadLocal中不会有任何数据,必须得搭配拦截器使用。
二、Redis数据库解决Session共享问题
Session共享问题:多台Tomcat服务器不共享session存储空间,当切换到不同Tomcat服务器时,造成数据丢失问题。
利用token作为key将数据存入redis
访问流程
当注册完成后,用户去登录会去校验用户提交的手机号和验证码,是否一致,如果一致,则根据手机号查询用户信息,不存在则新建,最后将用户数据保存到redis,生成token作为redis的key并且返回给前端,当我们校验用户是否登录时(拦截器),会去携带着token进行访问,从redis中取出token对应的value,判断是否存在这个数据,如果没有则拦截,如果存在则将其保存到threadLocal中,并且放行。
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);
String code = loginForm.getCode();
if (cacheCode == null || !cacheCode.equals(code)) {