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 服务器依靠资源管 ...
随机推荐
- Mysql中的FOREIGN_KEY_CHECKS方法【外键约束作用】
一.命令行 首先FOREIGN_KEY_CHECKS方法的作用是用来启动和关闭外键约束的方法. 二.外键约束 即数据库中两个数据表之间的某个列建立的一种联系.MySQL通过外键约束的引入,可以使得数据 ...
- 聊一聊 .NET高级调试 中的一些内存术语
一:背景 1. 讲故事 在高级调试的旅程中,经常会有一些朋友问我什么是 工作集(内存),什么是 提交大小,什么是 Virtual Size, 什么是 Working Set ...截图如下: 既然有很 ...
- 0x06.HelloPHP
PHP基础 格式 最后一句可以不加分号 <?php echo "hello" ?> 可以不加结束标签,但是最后一句要加分号 <?php echo "he ...
- SpringBoot项目启动过程动态修改接口请求路径
背景 最近遇到一个技术需求,需要对其他多个已有的服务进行整合打包为一个整体的服务,项目启动过程发现一个问题,在controller层多个服务之间存在相同的RequestMapping接口请求路径,导致 ...
- [ABC278G] Generalized Subtraction Game
Problem Statement This is an interactive task (where your program interacts with the judge's program ...
- 数据仓库——Hive
数据仓库:是一个用于储存,分析,报告的数据系统 数据仓库的目的是构建面向分析的集成化数据环境,分析结果为企业提供决策支持 数仓专注分析 数据仓库仓库为何而来,解决什么问题的? 为了分析数据而来,分析结 ...
- docker 设计及源码分析
1.dockerd 是一个长期运行的守护进程(docker daemon).负责管理 docker 容器的生命周期.镜像和存储等.实际还是通过grpc 的协议调用 containerd 的 api 接 ...
- Codeforces-470 div2 C题
C. Producing Snow time limit per test 1 second memory limit per test 256 megabytes input standard in ...
- 云上攻防--云服务&&对象存储(域名接管)&&弹性计算(元数据泄露)
云上攻防--云服务&&对象存储(域名接管)&&弹性计算(元数据泄露) 对象存储 各个厂商对于对象存储的叫法不同,但是除了叫法基本没有其他区别. 对象存储各大云名词: 阿 ...
- 微服务网关限流&鉴权-wei-fu-wu-wang-guan-xian-liu--jian-quan
title: 微服务网关限流&鉴权 date: 2022-01-06 14:40:45.047 updated: 2022-01-06 14:40:45.047 url: https://ww ...