Я использую библиотеку 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 потоками. Я сделал ошибку? Или я неправильно понимаю, как должен работать RateLimiter?