使用Redis+AOP优化查询性能

应用场景

在某些场景下,我们会经常查询某些特定数据,例如用户跳转各种页面都会查询用户具备该页面权限。
这种需求在流量较小的情况下没有什么问题,但如果出现大流量进行各种页面跳转的花,频繁IO对系统性能是有着非常严重的影响的。

解决方案

思路分析

由于用户具备的权限变化较少,我们完全可以将数据缓存在内存中,从而减少与磁盘的IO,提高查询效率

解决步骤

编写切面

注意笔者编码的特殊处理,由于查询时添加了中间件,为了避免redis宕机等情况导致业务查询不能正常走完流程,我们必须使用try catch进行相应捕获处理,以便后续根据情况解决问题。

package com.macro.mall.tiny.component;import com.macro.mall.tiny.Annotation.CacheException;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;import java.lang.reflect.Method;@Aspect
@Component
public class RedisCacheAspect {private static Logger logger = LoggerFactory.getLogger(RedisCacheAspect.class);@Pointcut("execution(public * com.macro.mall.tiny.controller.*.*(..)) ")public void cacheAspect() {}@Around("cacheAspect()")public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {Signature signature = joinPoint.getSignature();MethodSignature methodSignature = (MethodSignature) signature;Method method = methodSignature.getMethod();Object result = null;logger.info("通过缓存优化接口获取数据");try {result = joinPoint.proceed();} catch (Throwable throwable) {logger.error(throwable.getMessage());}return result;}}

修改请求接口

笔者这里编码思路很简单,先去redis查,若没有再去数据查询,并存储到redis中。

@RequestMapping(value = "listAll", method = RequestMethod.GET)@ResponseBodypublic CommonResult<List<JSON>> getAll() throws Exception {List<Object> redisPmsBrandList = redisService.lRange("listAll", 0, -1);List<JSON> resultList = new ArrayList();if (null != redisPmsBrandList && redisPmsBrandList.size() > 0) {for (Object cacheValue : redisPmsBrandList) {JSON json = JSONUtil.parse(cacheValue);resultList.add(json);}return CommonResult.success(resultList);}List<PmsBrand> pmsBrands = brandService.ListAll();for (int i = 0; i < pmsBrands.size(); i++) {redisService.lPush("listAll", JSONUtil.parse(pmsBrands.get(i)));}return CommonResult.success(resultList);}

优化切面

现存隐患

我们一味的去捕获问题不是对错误的最佳处理,我们应该对错误进行相应归类若是业务问题导致的错误,我们需要抛出进行处理,而其他非业务的错误我们则可以进行捕获处理。所以为了能够对错误进行分类,我们可以对可能发生业务错误的方法添加一个注解标记一下。

定义标记注解
package com.macro.mall.tiny.Annotation;import java.lang.annotation.*;@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CacheException {
}
修改切面
@Aspect
@Component
public class RedisCacheAspect {private static Logger logger = LoggerFactory.getLogger(RedisCacheAspect.class);@Pointcut("execution(public * com.macro.mall.tiny.controller.*.*(..)) ")public void cacheAspect() {}@Around("cacheAspect()")public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {Signature signature = joinPoint.getSignature();MethodSignature methodSignature = (MethodSignature) signature;Method method = methodSignature.getMethod();Object result = null;logger.info("通过缓存优化接口获取数据");try {result = joinPoint.proceed();} catch (Throwable throwable) {if (method.isAnnotationPresent(CacheException.class)) {logger.error("业务异常,需要排查处理");} else {logger.error(throwable.getMessage());}}return result;}}

参考文献

使用Redis+AOP优化权限管理功能,这波操作贼爽!

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

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

相关文章

Vue3-18-侦听器watch()、watchEffect() 的基本使用

什么是侦听器 个人理解&#xff1a;当有一个响应式状态&#xff08;普通变量 or 一个响应式对象&#xff09;发生改变时&#xff0c;我们希望监听到这个改变&#xff0c;并且能够进行一些逻辑处理。那么侦听器就是来帮助我们实现这个功能的。侦听器 其实就是两个函数&#xff…

〖大前端 - 基础入门三大核心之JS篇(54)〗- 原型和原型链

说明&#xff1a;该文属于 大前端全栈架构白宝书专栏&#xff0c;目前阶段免费&#xff0c;如需要项目实战或者是体系化资源&#xff0c;文末名片加V&#xff01;作者&#xff1a;哈哥撩编程&#xff0c;十余年工作经验, 从事过全栈研发、产品经理等工作&#xff0c;目前在公司…

Android之Apk相关操作,以32位或64位运行apk,区分apk支持CPU架构的办法

一、以32位或64位安装运行apk 连接手机&#xff0c;准备好apk文件&#xff0c;打开cmd 32位&#xff1a; adb install --abi armeabi-v7a 打包的Apk路径64位 adb install --abi arm64-v8a 打包的apk路径二、区分32位和64位包 参考链接&#xff1a; https://blog.51cto.com/…

JavaScript算法46- 最长连续序列(leetCode:128middle)

128. 最长连续序列 一、题目 给定一个未排序的整数数组 nums &#xff0c;找出数字连续的最长序列&#xff08;不要求序列元素在原数组中连续&#xff09;的长度。 请你设计并实现时间复杂度为 O(n) 的算法解决此问题。 示例 输入&#xff1a;nums [100,4,200,1,3,2] 输出…

曹操出行集成:无代码API连接广告推广与用户运营

曹操出行集成的必要性 随着科技的不断进步&#xff0c;无代码API集成已经成为企业提升效率、优化营销策略的重要手段。对于新能源汽车共享服务领导者曹操出行而言&#xff0c;将其服务集成至企业营销系统中&#xff0c;不仅可以提升客户体验&#xff0c;还能加强品牌的市场竞争…

微信小程序 全局共享数据 mobx

前言 全局数据共享&#xff08;又叫做&#xff1a;状态管理&#xff09;是为了解决组件之间数据共享的问题。开发中常用的全局数据共享方案有&#xff1a;Vuex、Redux、MobX 等。 一. 安装 npm install --save mobx-miniprogram4.13.2 mobx-miniprogram-bindings2.1.5 安装完…

基于主动安全的AIGC数据安全建设

面对AIGC带来的数据安全新问题&#xff0c;是不是就应该一刀切禁止AIGC的研究利用呢&#xff1f;答案是否定的。要发展AIGC&#xff0c;也要主动积极地对AIGC的数据安全进行建设。让AIGC更加安全、可靠的为用户服务。为达到此目的&#xff0c;应该从三个方面来开展AIGC的数据安…

【WebRTC】用WebRTC做即时视频聊天应用

【配套项目源码】 打开即用,设置一个免费的Agora账户就可以实现视频电话。非常好的WebRTC学习和应用项目。 用VSCode打开即可。 https://download.csdn.net/download/weixin_41697242/88630069 【什么是WebRTC?】 WebRTC是一套基于JS的API,能够建立端对端的直接通信,实…

后端接口开发-web前台请求接口对后台数据库增删改查-实例

一、后端接口开发的逻辑是&#xff1a; 1.Application项目启动 2.前台接口Url请求后台 3.Controller控制拿到前台请求参数&#xff0c;传递给中间组件Service 4.Service调用Mapper.java 5. mapper.java映射到mapper.xml中的mybatis语句&#xff0c;类似Sql语句操作数据库 6.其…

携程英语测评(已offer)

携程英语测评大概有这么几种题型&#xff1a;读出屏幕上的句子&#xff0c;读出他说过一遍的句子&#xff0c;长对话听力&#xff0c;给题目临场说一段小作文&#xff0c;语法语义判断。大概就是这五个部分吧&#xff0c;我这里主要介绍一下临场作文题 临场作文我搜集了下网上…

GDPU 数据结构 天码行空14

实验十四 查找算法的实现 一、【实验目的】 1、掌握顺序排序&#xff0c;二叉排序树的基本概念 2、掌握顺序排序&#xff0c;二叉排序树的基本算法&#xff08;查找算法、插入算法、删除算法&#xff09; 3、理解并掌握二叉排序数查找的平均查找长度。 二、【实验内容】 …

群晖(Synology)云备份的方案是什么

群晖云备份方案就是在本地的 NAS 如果出现问题&#xff0c;或者必须需要重做整列的时候&#xff0c;保证数据不丢失。 当然&#xff0c;这些是针对有价值的数据&#xff0c;如果只是电影或者不是自己的拍摄素材文件&#xff0c;其实可以不使用云备份方案&#xff0c;因为毕竟云…

Ubuntu如何安装KVM

环境&#xff1a; 联想E14笔记本 Ubuntu20.04 问题描述&#xff1a; Ubuntu如何安装KVM 解决方案&#xff1a; 1.验证CPU是否支持硬件虚拟化 rootst-ThinkPad-E14:~# grep -Eoc (vmx|svm) /proc/cpuinfo 162.检查 VT 是否在 BIOS 中启用 安装 apt install cpu-checker …

PHP中的依赖注入是怎样的?

依赖注入&#xff08;Dependency Injection&#xff0c;DI&#xff09;是一种设计模式&#xff0c;它用于解耦组件之间的依赖关系&#xff0c;提高代码的可维护性、可测试性和灵活性。在 PHP 中&#xff0c;依赖注入通常通过构造函数注入、方法注入或属性注入来实现。 以下是依…

微服务组件Sentinel的学习(1)

Sentinel学习笔记&#xff08;1&#xff09; Sentinel基本概念Sentinel功能和设计理念流量控制熔断降级系统负载保护 Sentinel基本概念 资源 资源是Sentinel的关键概念。它可以是 ava应用程序中的任何内容&#xff0c;例如&#xff0c;由应用程序提供的服务&#xff0c;或由应…

stm32F407-GPIO的使用——点亮LED并且讲解各个寄存器

stm32F407-GPIO的使用——点亮LED并且讲解各个寄存器 本文为stm32GPIO的介绍与使用&#xff0c;例子是简单的LED点亮。 一、 GPIO GPIO&#xff08;General Purpose I/O Ports&#xff09;意思为通用输入/输出端口&#xff0c;通俗地说&#xff0c; 就是一些引脚&#xff0c;可…

Elasticsearch 8.10之前同义词最佳实践

1、同义词在搜索引擎领域用途 同义词在搜索引擎领域的用途可概括如下: 增强搜索的准确性——当用户输入一个关键词时,可能与他们实际意图相关的文档使用了一个不同的关键词或短语。同义词允许搜索引擎理解和识别这些情况,返回更准确的结果。如:“遥遥领先”和“华为Meta60…

QT学习(20):QTcpSocket和QAbstractSocket

目录 QAbstractSocket建立连接的函数和信号阻塞功能QTcpSocket QAbstractSocketPrivateQAbstractSocketEngine和QNativeSocketEngine QAbstractSocket QAbstractSocket 是QTcpSocket和QUdpSocket的基类&#xff0c;并且包含这两个类的所有通用功能。如果需要套接字&#xff0c…

WT588F02B-8S语音芯片:灵活应用的语音播放利器,实现多重优势

在智能语音交互领域&#xff0c;唯创知音WT588F02B-8S可重复擦写&#xff08;Flash型&#xff09;语音芯片声音播放提示IC凭借其出色的特性&#xff0c;为用户提供了更灵活、高效的语音解决方案。本文将聚焦于该芯片的应用优势&#xff0c;包括实现用户自主更新语音文件、节约打…

WTN6xxx系列OTP语音芯片:智能语音解决方案的可靠之选

在智能语音交互领域&#xff0c;唯创知音的WTN6xxx系列OTP语音芯片以其独特的特性成为声音播放提示IC的可靠之选。本文将深入探讨WTN6xxx系列OTP语音芯片的应用优势&#xff0c;展示其在各个方面的卓越性能。 一、低成本、高性能 1.经济实惠&#xff1a; WTN6xxx系列OTP语音芯…