RateLimiter 仅适用于某些方法

问题描述

我的方法需要两个 API 调用,并用 Spring Boot 的 @Cacheable 和 Resilience4j 的 @RateLimiter (link to doc) 装饰:

    @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 注释移动到 getFileNamegetProjectFileFromFileName 或两者 - 但突然它停止工作(代码编译,但请求太频繁)。

为什么 @RateLimiter 对第一个函数起作用,而对第二个或第三个函数不起作用?以及如何在缓存函数获取速率限制器?

解决方法

因为当你从同一个类(bean)本地调用一个被注释的方法时,因为 Spring AOP 注释不起作用,因为这样就绕过了代理。

由于 Spring AOP 方面的顺序,同一方法上的

@Cacheable@RateLimiter 可能不起作用。请参阅: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