Redis的实战常用一、验证码登录(解决session共享问题)(思路、意识)

一、基于session实现登录功能

  • 第一步:发送验证码:

    • 用户在提交手机号后,会校验手机号是否合法:
      • 如果不合法,则要求用户重新输入手机号
      • 如果手机号合法,后台此时生成对应的验证码,同时将验证码进行保存(存到session里面),然后再通过短信的方式将验证码发送给用户
  • 第二步:短信验证码登录、注册:

    • 用户输入刚刚获取到的验证码,而后台则从session中拿到当前验证码,然后和用户输入的验证码进行校验
      • 如果不一致,则无法通过校验(提示验证码错误)
      • 如果一致,则后台根据手机号查询用户:
        • 如果用户不存在,则为用户创建账号信息,保存到数据库,再将用户信息保存到session中
        • 如果存在,则直接存入到session中取。
      • 无论是否存在,都会将用户信息(这个用户信息可以创建个UserDTO对象,把想要暴露的信息存储到session中去,这样就可以减少数据暴露的风险)保存到session中,方便后续获得当前登录信息。
  • 第三步:校验登录状态(登录时的逻辑):

    • 用户在请求登录的时候,会从cookie中携带者JsessionId到后台,后台通过JsessionId从session中拿到用户信息
      • 如果没有session信息,则进行拦截,无法进行登录。
      • 如果有session信息,则将用户信息保存到threadLocal中,并且放行。
  • 使用拦截器:当每个业务都需要进行用户信息的验证时,不可能每个业务都写一次登录校验的逻辑,这就需要使用到拦截器了(拦截器是在所有的业务执行之前执行的)。我们把这个登录校验的逻辑写到拦截器里面去,这样每次用户无论访问哪个业务都需要经过拦截器,然后让拦截器判断是否放行该用户访问业务。

在这里插入图片描述

  • tomcat运行原理:
    在这里插入图片描述

  • 当用户发起请求时,会访问我们向tomcat注册的端口:

  • 任何程序想要运行,都需要有一个线程对当前端口号进行监听,tomcat也不例外。

  • 当监听线程知道用户想要和tomcat进行连接时,那会由监听线程创建socket连接。

    • socket都是成对出现的,用户通过socket互相传递数据,当tomcat端的socket接收到数据后,此时监听线程会从tomcat的线程池中取出一个线程执行用户请求。
  • 当我们的服务部署到tomcat后,线程会找到用户想要访问的工程,然后用这个线程转发到工程中的controller,service,dao中,并且访问对应的DB,在用户执行完请求后,再统一返回,再找到tomcat端的socket,再将数据写回到用户端的socket,完成请求和响应

  • 结论:每个用户其实对应都是去找tomcat线程池中的一个线程来完成工作的, 使用完成后再进行回收,既然每个请求都是独立的,所以在每个用户去访问我们的工程时,我们可以使用threadlocal来做到线程隔离,每个线程操作自己的一份数据(Threadlocal的基本使用)

    • 在threadLocal中,无论是它的put方法和他的get方法, 都是先从获得当前用户的线程,然后从线程中取出线程的成员变量map,只要线程不一样,map就不一样,所以可以通过这种方式来做到线程隔离。

二、集群的session共享问题(使用redis代替)

  1. session共享问题:其实就是多台tomcat服务器并不共享session存储空间(每个tomcat有自己的session),当请求切换到不同的tomcat服务时导致数据丢失的问题。

思路分析:

  • 每个tomcat中都有一份属于自己的session,假设用户第一次访问第一台tomcat,并且把自己的信息存放到第一台服务器的session中;
  • 但是第二次这个用户访问到了第二台tomcat,那么在第二台服务器上,肯定没有第一台服务器存放的session,所以此时 整个登录拦截功能就会出现问题,我们能如何解决这个问题呢?
    • 早期的方案是session拷贝,就是说虽然每个tomcat上都有不同的session,但是每当任意一台服务器的session修改时,都会同步给其他的Tomcat服务器的session,这样的话,就可以实现session的共享了,但是这种方案具有两个大问题:
      • 1、每台服务器中都有完整的一份session数据,·服务器压力过大·。
      • 2、session拷贝数据时,可能会出现延迟

解决方法:

  • 基于redis来完成,我们把session换成redis,redis数据本身就是共享的,就可以避免session共享的问题了。
    在这里插入图片描述

第一步:设计redis的value的结构

  • 利用redis来存储数据,那么到底使用哪种结构呢?
    • 如果存入的数据比较简单,我们可以考虑使用String,或者是使用哈希
      • 当存入的数据是一个对象时,value如果使用String结构时,会把java对象序列化成一个json字符串然后存储。(使用string结构时,会有一些额外的数据存储,比如json的格式等等,而且每次修改都要修改整个字符串)
      • 当存入的数据是一个对象时,value如果使用哈希,则它的value中只会存储数据本身,修改可以直接修改单个字段。
      • 如果不是特别在意内存,其实使用String就可以啦。
        在这里插入图片描述

第二步:redis的key的设计

  • 1、key要具有唯一性
  • 2、key要方便携带

第三步:设置redis的key的存活时间

  • 就好比你使用百度等其它的软件时,你每次登录进去之后,在一段时间之内,退出来再进去都不需要再重新进行登录(只要不是退出登录),过了特定的时间之后,就需要重新登录了。(原因就可以理解为存储你登录信息的数据的key过期了,存储在redis的登录数据没了)
  • 具体设计:只要用户还在操作,无论在访问哪个服务都需要重新刷新key的存活时间只有当用户不再操作的时候,才会计算key的存活时间,直到时间过去之后才会销毁key

整体访问流程

  • 用户去登录时,会去校验用户提交的手机号和验证码,是否一致,如果一致,则根据手机号查询用户信息,并将用户数据保存到redis,并且生成token作为redis的key。
    • 如果用户不存在则新建一个用户,然后将新建用户的数据保存到数据库中,然后再保存到redis,并且生成token作为redis的key,
  • 当我们校验用户是否登录时,会去携带着token进行访问,从redis中取出token对应的value,判断是否存在这个数据
    • 如果不存在这个数据则拦截登录
    • 如果存在则将其保存到threadLocal中,并且放行。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/32285.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端路线指导(4):前端春招秋招经验分享

春招/秋招经验分享(前端) 哈喽大家好,我是小粉,双一流本科,自学前端一年,收获腾讯,字节等多家大厂offer,一半以上ssp~ 今天给大家分享一下我的春招(暑期实习)、秋招经历,…

【Gradio】如何设置 Gradio 数据框的样式

简介 数据可视化是数据分析和机器学习的关键方面。Gradio DataFrame 组件是一种流行的方式,在网络应用程序中显示表格数据(特别是以 pandas DataFrame 对象的形式)。 本文将探讨 Gradio 的最新增强功能,这些功能允许用户整合 pand…

Linux下静态IP地址的配置

Linux下一切皆文件!必然通过修改配置文件生效! 1.方法1:直接修改网卡配置文件 配置静态IP地址 [rootheima ~]# cd /etc/sysconfig/network-scripts/ [rootheima network-scripts]# ls ifcfg-ens160 [rootheima network-scripts]# cat ifcfg-ens160 TY…

Spring的启动扩展点机制详解

在Java的世界中,我们知道Spring是当下最主流的开发框架,没有之一。而在使用Dubbo、Mybatis等开源框架时,我们发现可以采用和Spring完全一样的使用方式来使用它们。 可能你在平时的使用过程中并没有意识到这一点,但仔细想一想&…

飞机大战java

"飞机大战"是一种经典的射击游戏,通常在各种平台上都有实现,包括Java。如果你想要开发一个Java版本的飞机大战游戏,你可能需要考虑以下几个方面: 游戏设计:确定游戏的基本规则,比如玩家控制的飞机…

代码随想录第四十五天打卡

198.打家劫舍 视频讲解&#xff1a;动态规划&#xff0c;偷不偷这个房间呢&#xff1f;| LeetCode&#xff1a;198.打家劫舍_哔哩哔哩_bilibili 代码随想录 class Solution { public:int rob(vector<int>& nums) {vector<vector<int>>dp(nums.size(),ve…

通用大模型VS垂直大模型

通用大模型VS垂直大模型&#xff0c;你更青睐哪一方&#xff1f; 在当前AI大模型的竞争环境中&#xff0c;通用大模型和垂直大模型各有其独特的优势和挑战&#xff0c;选择哪一方更有前景需要考虑多方面因素。 通用大模型的优势与挑战 通用大模型如GPT-3、BERT等在自然语言处理…

解决js打开新页面百度网盘显示不存在方法:啊哦,你所访问的页面不存在了。

用js打开新页面open或window.location.href打开百度网盘后都显示&#xff1a;啊哦&#xff0c;你所访问的页面不存在了。 window.open(baidu_url); window.location.href baidu_url;在浏览器上&#xff0c;回车后网盘资源是可以打开的&#xff0c;刷新也是打开的。这是很奇怪…

深入分析并可视化城市轨道数据

介绍 中国城市化进程加速中&#xff0c;城市轨道交通的迅速扩张成为提升城市运行效率和居民生活品质的关键。这一网络从少数大城市延伸至众多大中型城市&#xff0c;映射了经济飞跃和城市管理现代化。深入分析并可视化城市轨道数据&#xff0c;对于揭示网络特性、评估效率、理…

进程、线程的区别

进程、线程的关系 开工厂生产手机&#xff0c;制作一条生产线&#xff0c;这个生产线上有很多的器件以及材料。一条生产线就是一个进程。 只有生产线是不够的&#xff0c;使用找五个工人来进行生产&#xff0c;这个工人能够利用这些材料最终一步步的将手机做出来&#xff0c;这…

Ansible 自动化运维实践

随着 IT 基础设施的复杂性不断增加&#xff0c;手动运维已无法满足现代企业对高效、可靠的 IT 运维需求。Ansible 作为一款开源的自动化运维工具&#xff0c;通过简洁易用的 YAML 语法和无代理&#xff08;agentless&#xff09;架构&#xff0c;极大简化了系统配置管理、应用部…

护理实训室:为职业院校制定一个完善的护理实训室建设方案

建设一个护理实训室对于职业院校来说是非常重要的&#xff0c;因为这个实训室将直接影响学生的实践能力和未来的职业发展。在编写完整的建设计划时&#xff0c;需要考虑多个方面&#xff0c;包括实训室的设备、布局、教学方法等。以下是一个详细的护理实训室建设计划&#xff1…

LuxTrust、契约锁联合启动中欧两地跨境电子签服务

6月18日&#xff0c;欧洲领先的数字身份和电子签名厂商-LuxTrust、全球领先的数字化技术和服务的提供商-浩鲸科技一行莅临契约锁上海总部&#xff0c;并于当日下午联合举行“跨境签战略合作”现场签约仪式。 三方将以此次合作为契机&#xff0c;发挥各自领域专业优势&#xff…

SVG 参考手册

SVG 参考手册 1. 简介 SVG(可缩放矢量图形)是一种基于XML的图形格式,用于描述二维图形和图形应用程序。SVG图像在放大或缩小时不会失真,因为它们是由直线、曲线、点和多边形等数学对象定义的,而不是由像素组成的。这使得SVG非常适合网页设计、打印图形和动画。 2. 基础…

笔记-Python—redis

一、redis redis是一个key-value存储系统。和Memcached类似&#xff0c;它支持存储的value类型相对更多&#xff0c;包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash&#xff08;哈希类型&#xff09;。这些数据类型都支持push/pop、add/remov…

docker的缓存机制

docker文档 docker的缓存机制 镜像层缓存(Image Layer Cache) Docker 镜像是分层构建的,每一个 Dockerfile 指令都会生成一个新的镜像层。 Docker 会缓存每一个镜像层,当构建新的镜像时,如果检测到某个层之前已经构建过,就会直接复用该层,而不需要重新构建。 FROM ubuntu:18…

DS知识点总结--线性表定义及顺序表示

数据结构知识点汇总(考研C版) 文章目录 数据结构知识点汇总(考研C版)二、线性表2.1 线性表的定义和操作2.1.1 线性表的定义2.1.2 线性表的基本操作 2.2 线性表的顺序表示2.2.1 顺序表的定义2.2.2 顺序表上的基本操作的实现 二、线性表 2.1 线性表的定义和操作 2.1.1 线性表的…

消防设施操作员(中级)题库

31.消防水带按内口径可分为&#xff08; &#xff09;类。 A.2 B.4 C.6 D.8 答案:D 解析:消防水带按内径可分为8类&#xff0c;分别是25mm、50mm、65mm&#xff0c;、80mm、100mm、125mm、150mm、300mm。&#xff08;详见教材172页&#xff09; 32.消防水带按&#xff0…

区块链会议投稿资讯CCF A--WINE 2024 截止7.15 附录用率 附录用的区块链文章

Conference&#xff1a;The Conference on Web and Internet Economics (WINE) CCF level&#xff1a;CCF A Categories&#xff1a;Cross-cutting/comprehensive/emerging Year&#xff1a;2024 Conference time&#xff1a; December 2-5, 2024 录用率&#xff1a; sele…

MSPM0G3507——PWM

在sysconfig中&#xff0c;左侧可以选择MCU的外设&#xff0c;我们找到并点击TIMER-PWM选项卡&#xff0c;在TIMER-PWM中点击ADD&#xff0c;就可以添加定时器下的PWM外设。 这里设置通道0为100Hz的频率&#xff0c;0%占空比的PWM&#xff0c;周期计数值为1000&#xff0c;比较…