springboot项目,现在统计所有接口每天,每小时,每分钟,每秒请求次数并保存数据中
时间: 2023-12-23 12:06:32 浏览: 88
可以使用 AOP 和 Redis 实现该功能。具体实现步骤如下:
1. 创建一个切面类,使用 @Aspect 注解标注该类为切面类,并使用 @Around 注解标注需要统计请求次数的接口方法。
2. 在切面类中使用 @Pointcut 注解定义切入点,指定需要统计请求次数的接口方法。
3. 在切面类中使用 @Around 注解定义环绕通知,在接口方法执行前后分别记录当前时间戳,并计算出请求耗时。
4. 在切面类中使用 RedisTemplate 将统计结果存储到 Redis 中,使用 Redis 的有序集合数据结构来存储请求次数,以时间戳作为成员,以请求次数作为分值。
5. 在需要查看统计结果的地方,从 Redis 中获取有序集合数据,并根据时间戳进行排序。同时,可以将统计结果保存到数据库中。
6. 可以使用定时任务来定时清理 Redis 中过期的统计结果,避免数据过于庞大。
示例代码如下:
```java
@Aspect
@Component
public class RequestCountAspect {
private final static String KEY_PREFIX = "request_count:";
private final static long EXPIRE_TIME = 24 * 60 * 60; // 统计结果过期时间为24小时
private final RedisTemplate<String, Object> redisTemplate;
private final RequestCountRepository requestCountRepository;
@Autowired
public RequestCountAspect(RedisTemplate<String, Object> redisTemplate, RequestCountRepository requestCountRepository) {
this.redisTemplate = redisTemplate;
this.requestCountRepository = requestCountRepository;
}
@Pointcut("execution(public * com.example.controller.*.*(..))")
public void requestCount() {}
@Around("requestCount()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
String method = joinPoint.getSignature().toShortString();
String key = KEY_PREFIX + method;
long currentTime = System.currentTimeMillis();
long currentSecond = currentTime / 1000;
long currentMinute = currentSecond / 60;
long currentHour = currentMinute / 60;
long currentDay = currentHour / 24;
// 记录当前时间戳
redisTemplate.opsForZSet().incrementScore(key, currentSecond, 1);
// 设置统计结果过期时间
redisTemplate.expire(key, EXPIRE_TIME, TimeUnit.SECONDS);
// 执行目标方法
Object result = joinPoint.proceed();
// 计算请求耗时
long costTime = System.currentTimeMillis() - currentTime;
// 输出请求耗时
System.out.println(method + " cost " + costTime + "ms");
// 保存统计结果到数据库中
RequestCount requestCount = new RequestCount();
requestCount.setMethod(method);
requestCount.setRequestTime(currentTime);
requestCount.setRequestCount(1);
requestCountRepository.save(requestCount);
return result;
}
}
```
在需要查看统计结果的地方,可以使用以下代码:
```java
public void showRequestCount() {
String method = "com.example.controller.UserController.getUser";
String key = "request_count:" + method;
long currentTime = System.currentTimeMillis();
long currentSecond = currentTime / 1000;
long currentMinute = currentSecond / 60;
long currentHour = currentMinute / 60;
long currentDay = currentHour / 24;
// 获取统计结果
Set<Object> seconds = redisTemplate.opsForZSet().rangeByScore(key, currentSecond - 59, currentSecond);
Set<Object> minutes = redisTemplate.opsForZSet().rangeByScore(key, currentMinute - 59, currentMinute);
Set<Object> hours = redisTemplate.opsForZSet().rangeByScore(key, currentHour - 23, currentHour);
Set<Object> days = redisTemplate.opsForZSet().rangeByScore(key, currentDay - 6, currentDay);
// 输出统计结果
System.out.println("Current second request count: " + (seconds == null ? 0 : seconds.size()));
System.out.println("Current minute request count: " + (minutes == null ? 0 : minutes.size()));
System.out.println("Current hour request count: " + (hours == null ? 0 : hours.size()));
System.out.println("Current day request count: " + (days == null ? 0 : days.size()));
// 将统计结果保存到数据库中
RequestCount requestCount = new RequestCount();
requestCount.setMethod(method);
requestCount.setRequestTime(currentTime);
requestCount.setRequestCount(seconds == null ? 0 : seconds.size());
requestCountRepository.save(requestCount);
}
```
阅读全文