如果让你统计每个接口每分钟调用次数怎么统计?

Sherwin.Wei Lv7

如果让你统计每个接口每分钟调用次数怎么统计?

最简单的可以使用 ConcurrentHashMap + AtomicInteger + 定时任务实现内存中的统计。

ConcurrentHashMap 的 key 为方法的名称、value 为 AtomicInteger 类型,记录调用次数,可以通过 aop 切面实现每个方法调用都记录到 ConcurrentHashMap 中,然后利用定时任务每 60 s 统计一次所有方法的数量,再清空 ConcurrentHashMap。

ConcurrentHashMap 保证多方法并发统计时线程安全,AtomicInteger 保证每次累计时线程安全。

看下代码就很清晰了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

@Aspect
@Component
public class ApiCallAspect {

private ConcurrentHashMap<String, AtomicInteger> apiCallCounts = new ConcurrentHashMap<>();

@Before("execution(* com.example.controller.*.*(..))")
public void recordApiCall(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();
apiCallCounts.computeIfAbsent(methodName, k -> new AtomicInteger(0)).incrementAndGet();
}

public ConcurrentHashMap<String, AtomicInteger> getApiCallCounts() {
return apiCallCounts;
}

public void reset() {
apiCallCounts.clear();
}

}


//每分钟
@Scheduled(fixedRate = 60000)
public void reportApiCallCounts() {
ConcurrentHashMap<String, AtomicInteger> apiCallCounts = apiCallAspect.getApiCallCounts();
apiCallCounts.forEach((apiName, count) -> {
// 记录到 redis 或其他介质中
});
//清空记录
apiCallCounter.reset();
}

优点:简单。

缺点:不准确,因为定时任务记录时候,ConcurrentHashMap 也一直在统计,所以最终的结果不一定是一分钟内的,而是超过一分钟的数据。且数据存储到内存中,如果意外宕机,数据就丢失了。

可以采用日志记录实现接口的统计。每次接口调用都用日志记录:接口名、时间戳等信息。

利用日志采集工具将日志统一发送并存储至 es 中(或者其他 NoSQL 中),利用 es 即可统计每分钟每个接口的调用量。

也可以利用 MQ,每次接口调用时都将接口名、时间戳封装发送消息,消费端可以将这些信息存储至 NoSQL 中,最终进行统计分析。

因为存储了时间戳,所以接口的调用次数是准确的。

Comments
On this page
如果让你统计每个接口每分钟调用次数怎么统计?