2021年你还不会Shiro?----9.Shiro利用缓存存储权限信息

本文涉及的产品
云原生内存数据库 Tair,内存型 2GB
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Redis 版,经济版 1GB 1个月
简介: 前面的学习以及清楚,我们每调用一次权限的判断,就会默认调用一次自定义Realm中的doGetAuthorizationInfo方法进行过权限验证,但是当用户量与并发量比较高时,再按照这种方式去查询数据库,就会给系统带来很大的压力,让系统的响应变得很慢很,容易降低用户体验。这时候我们就需要使用缓存来存储已经登录的用户信息和用户的权限信息,缓存都是基于内存实现的比数据库快了很多,这样用户进来,直接从缓存中获取信息就行,不用去争抢有限的数据库资源了。

前言:


前面的学习以及清楚,我们每调用一次权限的判断,就会默认调用一次自定义Realm中的doGetAuthorizationInfo方法进行过权限验证,但是当用户量与并发量比较高时,再按照这种方式去查询数据库,就会给系统带来很大的压力,让系统的响应变得很慢很,容易降低用户体验。这时候我们就需要使用缓存来存储已经登录的用户信息和用户的权限信息,缓存都是基于内存实现的比数据库快了很多,这样用户进来,直接从缓存中获取信息就行,不用去争抢有限的数据库资源了。


一.思考



上面已经解释了权限信息为什么需要缓存。那么哪些信息适合放入缓存呢


1.哪些信息适合放入缓存?


放入缓存中的信息应该满足一个基本的条件,这些数据不应频繁变动,如果频繁变动了,就不应该被放入缓存中,这样并不能提升系统的性能,而且还会降低性能。


2.可以使用哪些缓存?


在Shiro的使用中,我们可以使用ehCache进行缓存管理,也可以使用市场主流的redis进行缓存管理。其实真实的项目中进本都是使用redis实现缓存,至少笔者做过的四五个使用缓存的项目无论大小,使用的都是redis。所以redis也是我们必须精通的一项技能。


3.Shiro中利用缓存存储认证授权的信息


当Shiro使用缓存进行存储认证与授权的信息时,用户的请求就会变成下图这种,如果使用了缓存就会先去检查缓存中是否有当前用户的缓存信息,如果没有,才会去数据库查询。


20210329221956277.png


二.使用enCache缓存权限信息



首先看下使用ehCache怎么实现对认证和授权进行缓存管理。


1.导入shiro与ehcache的整合依赖包


这里Shiro使用的版本是1.5.3,shiro-ehcache整合包与Shiro的版本一致,这里也选择1.5.3版本。

  <dependency>
          <groupId>org.apache.shiro</groupId>
          <artifactId>shiro-ehcache</artifactId>
          <version>1.5.3</version>
      </dependency>


2.开启缓存


那么在哪开启缓存使用呢?未使用缓存时,Realm的数据获取来源只有是数据库,开启后Realm的数据来源就变成了数据库和缓存。所以既然是Realm来管理数据,肯定是在Realm中开启了。我们在注入自定义Realm中这样开启缓存。如下:

@Bean
    public FirstRealm getRealm(){
        FirstRealm firstRealm = new FirstRealm();
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        hashedCredentialsMatcher.setHashAlgorithmName("MD5");
        hashedCredentialsMatcher.setHashIterations(2048);
//        下面的写法也是正常的,不过现在都是使用上面的写法,下面的写法已经是不推荐使用的了。
//        Md5CredentialsMatcher md5CredentialsMatcher = new Md5CredentialsMatcher();
//        md5CredentialsMatcher.setHashIterations(2048);
        firstRealm.setCredentialsMatcher(hashedCredentialsMatcher);
        //开启缓存
        firstRealm.setCachingEnabled(true);//开启全局的缓存管理
        firstRealm.setAuthenticationCachingEnabled(true);//开启认证缓存
        firstRealm.setAuthorizationCachingEnabled(true);//开启授权缓存
        firstRealm.setAuthenticationCacheName("authenticationCache");//设置缓存名称--认证
        firstRealm.setAuthorizationCacheName("authorizationCache");//设置缓存名称--授权
        firstRealm.setCacheManager(new EhCacheManager());
        return firstRealm;
    }


就像上方代码这样,我们首先需要为自定义Realm设置启用缓存,然后再分别为认证和授权开启缓存。后面又设置了缓存名称,这个其实可以省略。最后告诉自定义Realm使用哪种缓存实现。这里是使用的EhCacheManager。


3.验证缓存效果


我们知道,我们在未使用缓存时每调用一次授权的判断就会触发doGetAuthorizationInfo方法。如下所示刷新页面调用了多次授权方法。


image.gif


我们使用缓存就是为了防止重复调用,假如开启缓存后,只调用一次授权操作就是我们理想的状态了。验证如下:


image.gif


可以看到即使我们多次刷新页面,后台依然只调用了一次授权的操作,这样我们就实现了授权信息的缓存管理,当然了这里只是一个入门的展示。要是想要使用encache,还需要为ehcahe增加很多的配置,失效时间什么的。不过shiro的缓存集成真正会使用的还是redis进行,下一篇会总结redis的集成,并结合笔者正在做的一个shiro项目进行解读。


三.总结



这篇主要是总结了如何初步使用缓存实现授权的管理,其实经笔者验证

授权的缓存默认就是开启的,所以其实我们只使用一行代码就是可以实现授权的缓存功能如图所示,只需要为自定义Realm设置一个缓存管理器即可。仅仅使用了一行下面的代码:

firstRealm.setCacheManager(new EhCacheManager());


我们并没有去设置开启全局缓存,也未设置开启授权缓存这些都是开启了的。


image.png


我们验证下授权缓存有没有正常生效:


20210329233421342.gif


登录进入系统后,点击了多次的刷新后台只调用了一次授权的验证,显然缓存是生效的,到这里如果就确定的就说授权缓存是默认开启的其实也是不严谨的。我们注释掉这一样代码。自定义Realm不对授权的信息做任何操作,我们再来看下是否开启了授权缓存,如下图


image.png


很显然是开启了的,因此授权的缓存是默认开启的。我们若是只是为授权实现缓存其实一行代码就可以实现,但是现实是不可能只为授权提供缓存的。不过我们可以确定的是上方示例中开启全局缓存的代码肯定是多可以省略的,我们已经验证全局缓存和授权缓存默认都是开启的,因此若是想要偷懒,那么我们至少还是要开启认证的缓存的。这样就可以正常使用缓存了,代码就可以精简为如下:


@Bean
    public FirstRealm getRealm(){
        FirstRealm firstRealm = new FirstRealm();
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        hashedCredentialsMatcher.setHashAlgorithmName("MD5");
        hashedCredentialsMatcher.setHashIterations(2048);
//        下面的写法也是正常的,不过现在都是使用上面的写法,下面的写法已经是不推荐使用的了。
//        Md5CredentialsMatcher md5CredentialsMatcher = new Md5CredentialsMatcher();
//        md5CredentialsMatcher.setHashIterations(2048);
        firstRealm.setCredentialsMatcher(hashedCredentialsMatcher);
        //开启缓存
//        firstRealm.setCachingEnabled(true);//开启全局的缓存管理
        firstRealm.setAuthenticationCachingEnabled(true);//开启认证缓存
//        firstRealm.setAuthorizationCachingEnabled(true);//开启授权缓存
        firstRealm.setAuthenticationCacheName("authenticationCache");//设置缓存名称--认证
        firstRealm.setAuthorizationCacheName("authorizationCache");//设置缓存名称--授权
        firstRealm.setCacheManager(new EhCacheManager());
        return firstRealm;
    }


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
1月前
|
存储 缓存 关系型数据库
InnoDB 引擎底层存储和缓存原理
InnoDB 引擎底层存储和缓存原理
|
1月前
|
存储 缓存 Java
干翻Mybatis源码系列之第八篇:Mybatis二级缓存的创建和存储
干翻Mybatis源码系列之第八篇:Mybatis二级缓存的创建和存储
|
3天前
|
存储 缓存
使用tp5内cache缓存,存储手机短信验证码
使用tp5内cache缓存,存储手机短信验证码
12 1
|
1月前
|
存储 缓存 运维
【Docker 专栏】Docker 镜像的分层存储与缓存机制
【5月更文挑战第8天】Docker 镜像采用分层存储,减少空间占用并提升构建效率。每个镜像由多个层组成,共享基础层(如 Ubuntu)和应用层。缓存机制加速构建和运行,通过检查已有层来避免重复操作。有效管理缓存,如清理无用缓存和控制大小,可优化性能。分层和缓存带来资源高效利用、快速构建和灵活管理,但也面临缓存失效和层管理挑战。理解这一机制对开发者和运维至关重要。
【Docker 专栏】Docker 镜像的分层存储与缓存机制
|
23天前
|
存储 缓存 NoSQL
了解Redis,第一弹,什么是RedisRedis主要适用于分布式系统,用来用缓存,存储数据,在内存中存储那么为什么说是分布式呢?什么叫分布式什么是单机架构微服务架构微服务的本质
了解Redis,第一弹,什么是RedisRedis主要适用于分布式系统,用来用缓存,存储数据,在内存中存储那么为什么说是分布式呢?什么叫分布式什么是单机架构微服务架构微服务的本质
|
1月前
|
存储 缓存 前端开发
开发指南015-前端缓存的信息
平台前端架构启动后,在store里存储了很多信息,可以通过getter取到
|
1月前
|
存储 缓存 小程序
【微信小程序3】本地缓存:一次性存储多个对象值
【微信小程序3】本地缓存:一次性存储多个对象值
55 0
|
1月前
|
缓存 NoSQL Apache
Shiro - 缓存管理与CacheManagerAware接口
Shiro - 缓存管理与CacheManagerAware接口
66 0
|
8月前
|
存储 缓存 NoSQL
Redis第一讲:相关的基础知识/数据类型/缓存的过期策略/双写一致性/内存存储和持久化
Redis第一讲:相关的基础知识/数据类型/缓存的过期策略/双写一致性/内存存储和持久化
|
10月前
|
存储 消息中间件 缓存
使用 Docker Compose 部署单机版 Redis:简单高效的数据缓存与存储
家人们啦!今天我们来介绍如何使用 docker-compose 部署单机版 Redis,这是一个简单高效的数据缓存与存储解决方案,广泛应用于Web应用、移动应用以及各类数据处理场景。我们过后几篇文章了将会介绍cluster和sentinel集群的部署。通过本文的指导,你将能够快速上手并体验 Redis 在你的应用中所带来的便捷性与高性能。废话不多说,让我们开始吧!
2887 1
使用 Docker Compose 部署单机版 Redis:简单高效的数据缓存与存储