编写Redis缓存操作工具类

一、思路

1、在实际开发中,我们需要对多个业务进行数据的缓存,并且要处理缓存带来的缓存穿透、雪崩、击穿问题,所以我们将这些缓存操作以及缓存的解决方案通过编写一个Redis工具类进行封装起来,提高代码的复用性,降低代码的耦合。

二、业务逻辑

1. 将任意java对象序列化成json并保存到Redis中,并设置TTL过期时间

public void set(String key, Object value, Long time, TimeUnit unit){
        stringRedisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(value),time,unit);
    }

2. 将任意java对象序列化成json并保存到Redis中,并设置逻辑过期时间,用于处理缓存击穿问题

public void setWithLogicalExpire(String key,Object value,Long time,TimeUnit unit){
        //设置逻辑过期时间,并封装数据
        RedisData redisData = new RedisData();
        redisData.setData(value);
        redisData.setExpireTime(LocalDateTime.now().plusSeconds(unit.toSeconds(time)));
        //写入Redsi中
        stringRedisTemplate.opsForValue().set(key,JSONUtil.toJsonStr(redisData));
    }

3. 根据指定的key查询缓存,并反序列化为指定类型,利用缓存空值来解决缓存穿透问题

public <R,ID> R saveWithPassThrough(String keyPrefix, ID id, Class<R> type, Function<ID,R> dbfollback,Long time,TimeUnit unit){
        //根据ID查询Redis中是否存在
        String key = keyPrefix+id;
        String json = stringRedisTemplate.opsForValue().get(key);
        //Redis有,则直接返回
        //isNotBlank:不为null、不为""、length!=0
        if (StringUtils.isNotBlank(json)){
            //将json数据转为java对象
            return JSONUtil.toBean(json, type);
        }
        //判断查询到的是否为空值""
        if ("".equals(json)){
            return null;
        }
        //不存在,则查询数据库
        R r = dbfollback.apply(id);
        if (r == null){
            //数据库中没有,则缓存空值到Redis中
            stringRedisTemplate.opsForValue().set(key,"",CACHE_NULL_TTL,TimeUnit.MINUTES);
            return null;
        }
        //数据库有,则将查询到的数据保存到Redis中
        this.set(key,r,time,unit);
        //返回给前端
        return r;
    }

4. 根据指定的key查询缓存,并反序列化为指定类型,利用逻辑过期来解决缓存击穿问题

    //创建线程池
    private static final ExecutorService CACHE_REBUILD_EXECUTOR = Executors.newFixedThreadPool(10);

    public <R,ID> R saveWithLogicalExpire(String keyPrefix,ID id,Class<R> type,Function<ID,R> dbfollback,Long time,TimeUnit unit){
        //从Redis中查询商铺信息
        String key = keyPrefix + id;
        String json = stringRedisTemplate.opsForValue().get(key);
        //判断是否存在
        if (StrUtil.isBlank(json)){
            //不存在
            return null;
        }

        //存在,则需要先将json反序列化为java对象
        RedisData redisData = JSONUtil.toBean(json, RedisData.class);
        R r = JSONUtil.toBean((JSONObject) redisData.getData(), type);
        //判断缓存是否过期
        LocalDateTime expireTime = redisData.getExpireTime();
        if (expireTime.isAfter(LocalDateTime.now())){
            //未过期,则直接返回信息
            return r;
        }
        //已过期,则重建缓存
        //获取互斥锁
        String lockKey = CACHE_SHOP_KEY + id;
        boolean isLock = tryLock(lockKey);
        //判断是否获取成功
        if (isLock){
            //成功,则开启独立线程,进行缓存重建
            CACHE_REBUILD_EXECUTOR.submit(() -> {
                //查询数据库
                R rnew = dbfollback.apply(id);
                //写入缓存,并设置逻辑过期
                this.setWithLogicalExpire(key,rnew,time,unit);
                //释放锁
                unLock(lockKey);
            });
        }
        //失败,则返回过期的数据
        return r;
    }

    //获取互斥锁
    public boolean tryLock(String key){
        //设置互斥锁
        Boolean flag = stringRedisTemplate.opsForValue().setIfAbsent(key, "lock", LOCK_SHOP_TTL, TimeUnit.SECONDS);
        return BooleanUtil.isTrue(flag);
    }

    //释放锁
    public void unLock(String key){
        stringRedisTemplate.delete(key);
    }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
包含了web开发中常用的功能,如:缓存redis)、日志、事务、JPA、shiro、安全、常用工具类、swagger2在线接口文档、跨域支持等,可以基于该项目快速进行公司内部的项目开发。 开发工具在软件开发生命周期中扮演着至关重要的角色,它们旨在简化和加速从概念设计到产品部署的各个环节。以下是开发工具的主要作用: 代码编写与编辑: 提供集成开发环境(IDE),如Visual Studio、Eclipse、Android Studio和Sublime Text等,这些工具集成了文本编辑器,支持语法高亮、自动补全、代码片段管理和版本控制等功能,有助于开发者高效编写和维护代码。 项目管理: 支持项目创建、组织、构建自动化以及依赖管理,确保不同模块和组件之间的协调一致。 编译与构建: 包括编译器、构建工具(如Make、Gradle、Maven)等,用于将源代码转换为可执行文件或库,并进行资源打包、优化等处理。 调试与测试: 集成调试器允许开发者逐行执行代码,设置断点、查看变量值、跟踪调用堆栈等,帮助定位并修复代码中的错误。 测试框架和工具则协助开发者编写和运行单元测试、集成测试及性能测试,确保软件质量。 版本控制与协作: 通过集成Git、SVN等版本控制系统,支持团队成员间的代码共享、分支管理、合并请求和冲突解决。 可视化设计与原型制作: 对于UI/UX设计,有界面设计工具,如Sketch、Adobe XD,可以帮助设计师快速构建应用程序界面模型,并生成规范的设计稿供开发人员参考实现。 跨平台支持: 跨平台开发工具如Xamarin、React Native和Flutter,让开发者使用一种语言或框架编写可以在多个操作系统上运行的应用程序。 文档编写与API管理: 文档生成工具可以自动生成代码注释文档,便于团队内外理解和使用项目代码。 API管理工具则方便开发者创建、测试、发布和维护API接口。 持续集成与持续部署(CI/CD): Jenkins、Travis CI、GitHub Actions等工具负责自动化构建、测试和部署流程,提高交付效率和可靠性。 数据库管理与ORM工具: 数据库客户端工具用于连接、查询、更新数据库,ORM(对象关系映射)工具简化了数据操作和持久化层的开发工作。 总之,开发工具极大地提升了软件工程师的工作效率,保证了开发过程中的准确性与一致性,同时也促进了团队合作,使得软件开发更系统化、规范化和工业化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值