单点登录架构中Redis怎么实现?有哪些优化策略?

文章导读
单点登录架构中,Redis 主要通过集中存储会话信息(Session)或令牌(Token)来实现。用户登录后,服务端生成唯一 Token 存入 Redis 并设置过期时间,客户端携带 Token 访问其他子系统,子系统通过 Redis 验证 Token 有效性。优化策略包括:缩短 Key/Value 长度以减少内存和网络开销;使用 Hash 结构存储用户信息;启用 Lazy Free 避免删除大键
📋 目录
  1. A 单点登录 redis 实现 单点登录 redis 解决方案
  2. B 单点登录中 redis 作用 单点登录 redis 解决方案
  3. C Redis 实现安全可靠的单点登录 (redis 解决单点登录)
  4. D 《吐血整理》Redis 性能优化的 13 条军规!史上最全
  5. E Redis 性能优化 18 招
  6. F FAQ
A A

单点登录架构中,Redis 主要通过集中存储会话信息(Session)或令牌(Token)来实现。用户登录后,服务端生成唯一 Token 存入 Redis 并设置过期时间,客户端携带 Token 访问其他子系统,子系统通过 Redis 验证 Token 有效性。优化策略包括:缩短 Key/Value 长度以减少内存和网络开销;使用 Hash 结构存储用户信息;启用 Lazy Free 避免删除大键阻塞;使用 Pipeline 批量操作降低网络延迟;部署 Redis 集群防止单点故障;合理设置过期时间避免缓存穿透。

单点登录 redis 实现 单点登录 redis 解决方案

每个 web 应用都有自己的 session,那如何在分布式或者集群环境下统一 session,即如何实现单点登录,如下图 解决方案:把 session 数据存放在 redis,统一管理,向外提供服务接口,redis 可以设置过期时间,对应 session 的失效时间 优点:存取速度快,效率高;无单点故障,可以部署集群;自定义登录页面 (即每个应用都可以设计自己的登录页面) 缺点:必须部署 redis;所有程序自行开发,例如:登录、登出等。系统架构,只关注 Taotao-sso 和 redis 缓存即可,如下图:基于 redis 实现的单点登录这套方案比 SSO CAS 来说比较简单,容易上手,主要是依赖每个应用的拦截器和 redis 实现单点登录 SSO 需要提供的接口如下:登录,根据用户名和密码查询数据库,如存在则生成 token 保存在 redis,token 作为 key,用户信息作为 value,设置过期时间,然后把 token 保存到 cookie,固定 key,token 作为 value; 根据 token 查询用户信息,根据 token 作为 key 查询 redis 的值,如存在重新设置过期时间 (即已登录),不存在即未登录 登出,根据 token 作为 key 删除 redis 的值 拦截器流程图如下:拦截器代码如下:public class OrderInterceptor implements HandlerInterceptor { @Autowired private UserService userService; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //取用户 token String token = CookieUtils.getCookieValue(request, "TT_TOKEN"); //判断是否为空 if (StringUtils.isBlank(token)) { //如果为空就是未登录状态 //跳转到登录页面 response.sendRedirect(userService.getLoginUrl() + "?redirect=" + getBaseURL(request)); return false; } else { //如果能取到 token 说明用户可能已经登录 //从 sso 中取用户信息,判断用户是否登录 TbUser user = userService.getUserByToken(token); //判断用户是否过期 if (user == null) { //跳转到登录页面 response.sendRedirect(userService.getLoginUrl() + "?redirect=" + getBaseURL(request)); return false; } else { //用户已经登录,把用户信息放到 request 中 request.setAttribute("user", user); } } //放行 return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { // TODO Auto-generated method stub } @Override public void afterCompletion(HttpServlet(撰于 2023 年 7 月 28 日)

单点登录中 redis 作用 单点登录 redis 解决方案

三种常见方式:1.1 第一种:session 广播机制实现 (已淘汰) 概念:就是 session 复制,一个模块登录后,该模块 session 存放用户登录信息,再把该 session 复制到其它模块中,实现 session 广播,让所有的模块都能共享 session; 缺点:当模块很多时,session 需要需要复制多次,造成资源和内存的浪费 1.2 第二种:使用 cookie+redis 实现 概念:在项目中的任意一个模块进行登录,登录之后把数据放在 redis 和 cookie 中。1.2.1 redis+cookie 存放用户数据 第一步:redis key:唯一随机值 (ip、用户 id 等) value:存放用户登录数据 cookie 把 redis 里面的唯一 key 值放到 cookie 里面 第二步:访问项目中的其他模块时,发送请求携带 cookie 进行发送,服务器接收到请求,获取 cookie 值,从 cookie 中获取 redis 存放的主键,通过 redis key 去查询对应用户数据,如果结果不为空,那么说明就已经登录了。1.3 第三种:使用 token 实现 在项目某个模块进行登录,登录之后按照一定的规则生成字符串 (token 令牌 - 包含用户信息),再将这个字符串返回。返回方式可以通过 cookie 返回,也可以通过地址栏返回。再去访问项目其他模块,每次访问都携带 token 令牌 (地址栏里面带上 token 参数),服务器从地址栏中获取字符串 (token 令牌),根据 token 获取用户信息,如果结果不为空,那么就已经登录过了。2 JWT(Json Web Token) 传统的登录鉴权方式:2.1 session 认证 概念:因为 http 协议本身是无状态的协议,那就意味着当有用户向系统使用账号和密码进行用户认证之后,下一次登录请求还要再进行一次用户认证才行。因为我们不能通过 http 协议知道是哪个用户发出的请求,所以如果要知道是哪个用户发出的请求,那就需要在服务器保存一份用户信息 (保存至 session),然后在认证成功后返回 cookie 值传递给浏览器,那么用户在下一次请求时就可以带上 cookie 值,服务器就可以识别是哪个用户发送的请求,是否已认证,是否登录过期等等。缺点:因为 session 是保存在服务器里面的,所以对于分布式应用来说,由于 session 不共享,所以造成每一块微服务都需要进行用户认证… 2.2 token 认证 概念:这种方式跟 session 的方式流程差不多,不同的地方在于保存的是一个 token 值到 redis,token 一般是一串随机的字符 (比如 UUID),value 一般是用户 ID,并且设置一个过期时间。每次请求服务的时候带上 token 在请求头,后端接收到 token 则根据 token 查一下 redis 是否存在,如果存在则表示用户已认证,如果 token 不存在则跳到登录界面让用户重新登录,登录成功后返回一个 token 值给客户端。(2023 年 10 月 22 日)

Redis 实现安全可靠的单点登录 (redis 解决单点登录)

Redis 是一个开源的内存数据结构存储系统,具有高性能、稳定可靠等特点,非常适合用作单点登录系统的存储引擎。本文将介绍如何使用 Redis 实现一个安全可靠的单点登录系统。1.登录流程 单点登录系统的流程如下:1) 用户在客户端输入用户名和密码,提交给认证中心。2) 认证中心验证用户名和密码的合法性,如果验证通过,生成一个全局唯一的 token,并将 token 和用户的登录信息存储在 Redis 中。3) 认证中心把 token 返回给客户端,客户端将 token 存储在本地。4) 用户使用 token 来访问其他应用系统,其他应用系统需要向认证中心验证 token 的有效性,并获取用户的登录信息。2.实现细节 下面主要介绍单点登录系统的实现细节。1) 存储用户信息 在 Redis 中可以使用 Hash 类型存储用户信息。使用用户名作为 Key,用户信息作为 Value 存储在 Hash 中。示例代码如下:// 存储用户信息 redisClient.hset("user:username", "username", "password"); // 获取用户信息 redisClient.hget("user:username", "username"); 2) 生成 token 生成 token 可以通过 Redis 的自增功能来实现。使用一个全局计数器作为 Key,每次自增后作为 token 返回。示例代码如下:// 生成 token redisClient.incr("token:count"); long token = redisClient.get("token:count"); 3) 存储 token 存储 token 可以使用 Redis 的 String 类型。使用 token 作为 Key,存储用户信息的 Hash 作为 Value。并设置过期时间,保证 token 的安全性。示例代码如下:// 存储 token redisClient.setex(token, 3600, "user:username"); // 获取 token 对应的用户信息 redisClient.get(token); 4) 验证 token 验证 token 需要查询 Redis 中是否存在该 token,并获取用户信息进行验证。示例代码如下:// 验证 token String user_info = redisClient.get(token); if (user_info != null) { // 验证通过,返回用户信息 return user_info; } else { // 验证失败 return null; } 3.安全性考虑 单点登录系统需要保证数据的安全性。下面列举一些安全性考虑。1) 加密存储用户密码 用户密码需要进行加密存储,防止敏感数据泄露。可以使用加密算法如 SHA256 进行加密,存储加密后的 hash 值即可。示例代码如下:// 加密用户密码 String password = "123456"; MessageDigest messageDigest = MessageDigest.getInstance("SHA-256"); byte[] encodedhash = messageDigest.digest(password.getBytes(StandardCharsets.UTF_8));(发布时间是 2025 年 5 月 15 日)

单点登录架构中Redis怎么实现?有哪些优化策略?

《吐血整理》Redis 性能优化的 13 条军规!史上最全

Redis 是基于单线程模型实现的,也就是 Redis 是使用一个线程来处理所有的客户端请求的,尽管 Redis 使用了非阻塞式 IO,并且对各种命令都做了优化 (大部分命令操作时间复杂度都是 O(1)),但由于 Redis 是单线程执行的特点,因此它对性能的要求更加苛刻,本文我们将通过一些优化手段,让 Redis 更加高效的运行。本文我们将使用以下手段,来提升 Redis 的运行速度:缩短键值对的存储长度; 使用 lazy free(延迟删除) 特性; 设置键值的过期时间; 禁用长耗时的查询命令; 使用 slowlog 优化耗时命令; 使用 Pipeline 批量操作数据; 避免大量数据同时失效; 客户端使用优化; 使用物理机而非虚拟机安装 Redis 服务; 检查数据持久化策略; 禁用 THP 特性; 1.缩短键值对的存储长度 键值对的长度是和性能成反比的,比如我们来做一组写入数据的性能测试,执行结果如下:从以上数据可以看出,在 key 不变的情况下,value 值越大操作效率越慢,因为 Redis 对于同一种数据类型会使用不同的内部编码进行存储,比如字符串的内部编码就有三种:int(整数编码)、raw(优化内存分配的字符串编码)、embstr(动态字符串编码),这是因为 Redis 的作者是想通过不同编码实现效率和空间的平衡,然而数据量越大使用的内部编码就越复杂,而越是复杂的内部编码存储的性能就越低。这还只是写入时的速度,当键值对内容较大时,还会带来另外几个问题:内容越大需要的持久化时间就越长,需要挂起的时间越长,Redis 的性能就会越低; 内容越大在网络上传输的内容就越多,需要的时间就越长,整体的运行速度就越低; 内容越大占用的内存就越多,就会更频繁的触发内存淘汰机制,从而给 Redis 带来了更多的运行负担。因此在保证完整语义的同时,我们要尽量的缩短键值对的存储长度,必要时要对数据进行序列化和压缩再存储,以 Java 为例,序列化我们可以使用 protostuff 或 kryo,压缩我们可以使用 snappy。2.使用 lazy free 特性 lazy free 特性是 Redis 4.0 新增的一个非常使用的功能,它可以理解为惰性删除或延迟删除。意思是在删除的时候提供异步延时释放键值的功能,把键值释放操作放在 BIO(Background I/O) 单独的子线程处理中,以减少删除删除对 Redis 主线程的阻塞,可以有效地避免删除 big key 时带来的性能和可用性问题。(2020 年 3 月 28 日的资料)

Redis 性能优化 18 招

redis 性能优化的方法有哪些?如何提高 redis 的响应速度?redis 内存管理如何优化?前言 redis 作为一个高性能的键值存储系统,在现代应用中扮演着越来越重要的角色。无论是在 web 应用,移动应用,游戏还是 大数据分析 等领域,redis 都能提供快速的数据访问速度和优秀的性能。然而,随着数据量的不断增长,如何优化 redis 的性能成为了一个重要的课题。这篇文章将分享 redis 性能优化的 18 招,希望对你会有所帮助。选择合适的数据结构 redis 支持多种 数据结构,包括字符串,哈希,列表,集合,有序集合等。选择合适的数据结构可以提高性能和存储效率。例如,如果要存储用户信息,使用哈希结构而不是多个字符串可以更高效地存储和访问多个属性:代码语言:javascript ai 代码解释 jedis . hset ( "user:1001" , "name" , "alice" ) ; jedis . hset ( "user:1001" , "age" , "30" ) ; 这样可以减少内存的使用,并且提高数据操作的效率。避免使用过大的 key 和 value 过长的 key 和 value 会占用更多的内存空间,并且可能影响性能。保持 key 简短,并使用简洁的命名约定。例如,将"user:1001:profile"简化为"u:1001:p"。此外,还可以考虑对 value 进行压缩,以减少存储空间的占用。使用 redis pipeline 对多个命令的批量操作,使用 pipeline 可以显著降低 网络延迟,提升性能。pipeline 允许客户端一次发送多个命令,服务器 端集中处理后一次性返回结果,减少了网络往返次数。例如,批量设置 key 可以这样做:代码语言:javascript ai 代码解释 pipeline p = jedis . pipelined ( ) ; for ( int i = 0 ; i < 1000 ; i ++ ) redis 性能优化的 18 招(截至 2024 年 12 月 10 日)

FAQ

单点登录中 Redis 存储 Token 过期了怎么办?

单点登录架构中Redis怎么实现?有哪些优化策略?

Token 过期意味着用户会话失效,系统应拦截请求并重定向到登录页,用户重新认证后生成新 Token 存入 Redis。

Redis 集群如何保障 SSO 高可用?

单点登录架构中Redis怎么实现?有哪些优化策略?

通过 Redis Sentinel 哨兵模式或 Redis Cluster 集群模式,实现主从复制和自动故障转移,避免单点故障导致无法登录。

SSO 架构中 Redis key 设计有什么讲究?

Key 应简短且有意义,如"token:用户 ID",避免过长占用内存,同时设置合理的过期时间防止内存泄漏。