有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Resilience4J Ratelimiter不限制对带注释方法的访问

我正在使用resilience4j-spring-boot2库(io.github.resilience4j:resilience4j-spring-boot2,版本1.5.0)和Spring Boot版本2.3.1.RELEASE。 我创建了一个RateLimiter,它应该只允许一个线程每30秒执行一个特定的方法。然而,线程调用该方法似乎没有边界(除了Tomcat服务器中运行的已配置线程数)

我实现了一个简单的服务,它等待给定的时间,然后返回“Hello!”:

@RequestMapping("/")
@RestController
public class ResilientService {

    @RateLimiter(name = "hello-rl")
    @GetMapping("/hello/{timeout}")
    public String hello(@PathVariable int timeout) throws InterruptedException {
        Thread.sleep(timeout);
        return "Hello!";
    }

}

并将速率限制器配置如下

resilience4j.ratelimiter:
  instances:
    hello-rl:
      limitForPeriod: 1  # The number of permissions available during one limit refresh period
      limitRefreshPeriod: 30s  # The period of a limit refresh. After each period the rate limiter sets its permissions count back to the limitForPeriod value
      timeoutDuration: 30s  # The default wait time a thread waits for a permission

我用八个线程调用了该服务:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@RunWith(SpringRunner.class)
@Slf4j
public class CircuitBreakerTest {

    @Autowired
    TestRestTemplate testRestTemplate;

    @LocalServerPort
    private int port;

    @Value("${server.address}")
    private String serverAddress;

    @Test
    public void t() throws InterruptedException {
        final ExecutorService executorService = Executors.newFixedThreadPool(8);

        for (int i : IntStream.rangeClosed(1, 8).toArray()) {
            executorService.execute(() -> log.error(callService()));
        }

        executorService.shutdown();
        executorService.awaitTermination(1, TimeUnit.MINUTES);
    }

    private String callService() {
        return testRestTemplate.getForObject(
                "http://" + serverAddress + ":" + port + "/hello/5000",
                String.class
        );
    }

结果如下:

2020-08-07 10:41:10,095 ERROR [pool-1-thread-7] CircuitBreakerTest: Hello!
2020-08-07 10:41:10,095 ERROR [pool-1-thread-1] CircuitBreakerTest: Hello!
2020-08-07 10:41:10,095 ERROR [pool-1-thread-8] CircuitBreakerTest: Hello!
2020-08-07 10:41:10,095 ERROR [pool-1-thread-2] CircuitBreakerTest: Hello!
2020-08-07 10:41:10,095 ERROR [pool-1-thread-5] CircuitBreakerTest: Hello!
2020-08-07 10:41:15,104 ERROR [pool-1-thread-3] CircuitBreakerTest: Hello!
2020-08-07 10:41:15,121 ERROR [pool-1-thread-4] CircuitBreakerTest: Hello!
2020-08-07 10:41:15,121 ERROR [pool-1-thread-6] CircuitBreakerTest: Hello!

一次似乎只允许五个线程执行该方法,但我不知道为什么。Tomcat服务器正在使用>;8条线。 我做错了吗?还是我误解了限速器的工作原理


共 (1) 个答案

  1. # 1 楼答案

    resilience4j-spring-boot2在内部使用方面,因此需要将spring-boot-starter-aop依赖项添加到项目中,注释才能工作:

            <dependency>
                <!  for rate limiting  >
                <groupId>io.github.resilience4j</groupId>
                <artifactId>resilience4j-spring-boot2</artifactId>
                <version>${resilience4j.version}</version>
            </dependency>
            <dependency>
                <!  needed for Resilience4j  >
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-aop</artifactId>
            </dependency>
    

    如开头右边的official documentation(“设置”)所述。。。完全错过了