我的方法需要两个API调用,并装饰与Spring Boot的@Cacheable
以及Resilience4j的@RateLimiter
(链接到文档):
@Cacheable(value = "getProjectFile")
@RateLimiter(name = "getProjectFile")
public Optional<String> getProjectFile(String projectName) {
return getFileName(projectName).flatMap(this::getProjectFileFromFileName);
}
private Optional<String> getFileName(String projectName) {
String url = getUrlFromProjectName(projectName);
return Optional.ofNullable(restTemplate.getForObject(url, String.class));
}
private Optional<String> getProjectFileFromFileName(String fileName) {
String url = getUrlFromFileName(fileName);
return Optional.ofNullable(restTemplate.getForObject(url, String.class));
}
两个注释都工作得很好-但是即使在访问缓存值时速率限制器也会打开,这不必要地减慢了我的程序。
为了解决这个问题,我尝试将@RateLimiter
注释移动到getFileName
,getProjectFileFromFileName
或两者-但突然它停止工作(代码编译,但请求太频繁)。
为什么@RateLimiter
在第一个函数上工作,而不是第二个或第三个?如何在缓存函数中获得速率限制器?
因为Spring AOP注解不能在你从同一个类(bean)调用本地注解过的方法时工作,因为那样会绕过PROXY。
@Cacheable
和@RateLimiter
在同一个方法上可能不工作,因为Spring AOP方面顺序。见:https://docs.spring.io/spring-framework/docs/4.3.15.RELEASE/spring-framework-reference/html/aop.html aop-ataspectj-advice-ordering
可以全局配置RateLimiter的顺序,但是最好将方法getFileName
移到另一个Bean中,而只使用@RateLimiter
。