redis命令Incr做计数器 + 切点切面
Redis Incr 命令将 key 中储存的数字值增一。
如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作。
package com.example.apidemo.config.aspect; import com.example.apidemo.redis.LocalCache;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Objects;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import java.util.Date;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; @Aspect
@Component
public class DoneTimeAspect { @Autowired
private LocalCache localCache; /**
* 当方法符合切点规则不符合环绕通知的规则时候,执行的顺序如下
* @Before → @After→ @AfterRunning (如果有异常→@AfterThrowing)
*
* 当方法符合切点规则并且符合环绕通知的规则时候,执行的顺序如下
* @Around → @Before → @Around → @After执行 ProceedingJoinPoint.proceed() 之后的操作→@AfterRunning(如果有异常→@AfterThrowing)
*/ @Before("execution (* com.example.apidemo.controller.*.*(..))")
public void before(JoinPoint joinPoint) throws Exception {
System.out.println("======前置通知--拦截配置的package的controller:" + Arrays.toString(joinPoint.getArgs()) + LocalDateTime.now()); //最简单的接口重复请求处理方法
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
String sessionId = attributes.getSessionId(); // 用户请求唯一标识sessionId
String uri = attributes.getRequest().getServletPath(); // 用户请求的uri
String key = sessionId + "-" + uri; // 针对用户对应接口的唯一key
System.out.println("key==="+ key + LocalDateTime.now());
Object object = localCache.getCache(key); // 将生成的key存储在redis中,每次请求一次就增加一次
System.out.println("object==="+ object + "==" + LocalDateTime.now());
if (Objects.isNull(object) || Integer.parseInt(object.toString()) <=2 ) {
localCache.putIncrKey(key, 1L); //设置2分钟 过期
return;
}
if (Integer.parseInt(object.toString()) >2) {
throw new Exception("接口在2分钟内重复请求超过2次"); //再写一个全局ExceptionHandler,返回给前端 }
} @Around("execution (* com.example.apidemo.controller.*.*(..)) && @annotation(doneTime))")
public Object around(ProceedingJoinPoint joinPoint, DoneTime doneTime) throws Throwable { System.out.println("======环绕通知--:"+ Arrays.toString(joinPoint.getArgs()));
if (doneTime.param().equals("IndexController")) {
return "切面直接拦截==IndexController";
}
Object o = joinPoint.proceed(); //joinPoint.proceed()会继续走切面所在的方法
System.out.println("切面走proceed方法结束时间是:"+new Date()) ;
return o;
} }
@Component
@Slf4j
public class LocalCache { @Autowired
private StringRedisTemplate stringRedisTemplate;
public void putIncrKey(String key, Long value) {
Long num = stringRedisTemplate.opsForValue().increment(key, value);
log.info("increment===key|{},num|{},time|{}", key, num, LocalDateTime.now());
//increment 命令传入value 为1就加1, 为5就加5
if (num != null) {
stringRedisTemplate.expire(key,2, TimeUnit.MINUTES);
}
}
}
redis命令Incr做计数器 + 切点切面的更多相关文章
- Redis SWAPDB 命令背后做了什么
Redis SWAPDB 命令背后做了什么 目录 Redis SWAPDB 命令背后做了什么 0x00 摘要 0x01 SWAPDB 基础 1.1 命令说明 1.2 演示 0x02 预先校验 0x03 ...
- Redis详细讲解(Redis原理,Redis安装,Redis配置,Redis使用,Redis命令)
一.Redis介绍 Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API.从2010年3月15日起,Redis的开发 ...
- Redis命令大全&中文解释&在线测试命令工具&在线中文文档
在线测试命令地址:http://try.redis.io/ 官方文档:http://redis.io/commands http://redis.io/documentation Redis 命令参考 ...
- Redis命令
redis的常用命令主要分为两个方面.一个是键值相关命令.一个是服务器相关命令(redis-cli进入终端) 1.键值相关命令 keys * 取出当前所有的key exists name 查看n是否有 ...
- 最全面的Redis命令行查阅手册(收藏查看)
Redis是用C语言实现的,一般来说C语言实现的程序“距离”操作系统更近,执行速度相对会更快. Redis使用了单线程架构,预防了多线程可能产生的竞争问题. 作者对于Redis源代码可以说是精打细磨, ...
- 基于Redis的INCR实现一个限流器
模式:计数器 计数器是 Redis 的原子性自增操作可实现的最直观的模式了,它的想法相当简单:每当某个操作发生时,向 Redis 发送一个 INCR 命令. 比如在一个 web 应用程序中,如果想知道 ...
- redis命令大全参考手册
redis功能强大,支持数据类型丰富,以下是redis操作命令大全,基本上涵盖了redis所有的命令,并附有解释说明,大家可以收藏.参考,你一定要知道的是:redis的key名要区分大小写,在redi ...
- redis实战笔记(3)-第3章 Redis命令
第3章 Redis命令 本章主要内容 字符串命令. 列表命令和集合命令 散列命令和有序集合命令 发布命令与订阅命令 其他命令 在每个不同的数据类型的章节里, 展示的都是该数据类型所独有的. 最 ...
- redis命令_INCR
INCR key 将 key 中储存的数字值增一. 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作. 如果值包含错误的类型,或字符串类型的值不能表示为数字,那 ...
- 深入Redis命令的执行过程
深入Redis命令的执行过程 Redis 服务器: Redis 服务器实现与多个客户端的连接,并处理这些客户端发送过来的请求,同时保存客户端执行命令所产生的数据到数据库中.Redis 服务器依靠资源管 ...
随机推荐
- 深入解析C# List<T>的源码
前面的文章中解释了Array的初始化和元素插入,以及数组整体的存储结构(<深度分析C#中Array的存储结构>).这里我们再来详细的了解另一种存储结构List<T>, List ...
- Linux中execl函数详解与日常应用!
Linux中execl函数详解与日常应用 execl是Linux系统中的一个系统调用,用于执行指定路径下的可执行文件.本文将详细介绍execl函数的使用方法和参数含义,并探讨其在日常开发中的常见应用场 ...
- 本地部署modelscope-agent
本地部署modelscope-agent 部署流程 在modelscope社区创建一个自己的空间(假设name是LocalAgent),clone空间到本地(或云服务器如魔搭Notebook) git ...
- ubuntu安装opencv的正确方法
本文介绍的是如何安装ubuntu下C++接口的opencv 1.安装准备: 1.1安装cmake sudo apt-get install cmake 1.2依赖环境 sudo apt-get ins ...
- 华企盾DSC远程桌面、实时监控连接不上常见处理方法
1.检测策略是否勾选了远程桌面需要客户端确认或者勾选了客户端显示"允许远程维护"选项 2.检查客户端5097目录是否有MgrDll.dll.uvnserver.exe文件(是否被杀 ...
- ElasticSearch之cat indices API
命令样例如下: curl -X GET "https://localhost:9200/_cat/indices?v=true&pretty" --cacert $ES_H ...
- Python——第五章:shutil模块
复制文件 把dir1的文件a.txt 移动到dir2内 import shutil shutil.move("dir1/a.txt", "dir2") 复制两个 ...
- Kafka 万字精讲|工作五年这些你都知道吗?
目录 前言 一.Kafka 简介 1.1 事件流平台 1.2 Kafka 主要概念和术语 1.3 Zookeeper 二.Kafka 集群搭建和使用 2.1 使用 Docker Compose 搭建 ...
- 牛刀小试基本语法,Go lang1.18入门精炼教程,由白丁入鸿儒,go lang基本语法和变量的使用EP02
书接上回,Go lang1.18首个程序的运行犹如一声悠扬的长笛,标志着并发编程的Go lang巨轮正式开始起航.那么,在这艘巨轮之上,我们首先该做些什么呢?当然需要了解最基本的语法,那就是基础变量的 ...
- react+echarts出现“There is a chart instance already initialized on the dom.”
写了一个关于echatrs组件,报错dom重复 配置信息从props拿 let chart; useEffect(() => { if (chart) { updateChartView(); ...