2021. 8. 22. 01:26ㆍSpringBoot Monitoring/SpringBoot Resilience4j
소개
아래 글은 https://resilience4j.readme.io/docs/ratelimiter 사이트의 Introduction 원문입니다.
Rate limiting is an imperative technique to prepare your API for scale and establish high availability and reliability of your service. But also, this technique comes with a whole bunch of different options of how to handle a detected limits surplus, or what type of requests you want to limit. You can simply decline this over limit request, or build a queue to execute them later or combine these two approaches in some way.
Rate limiting 은 API 확장에 대비하고 서비스의 고가용성과 안정성을 확보하기 위해서는 꼭 필요한 기술이다.
또한 제한값을 초과한 것을 감지했을 때 어떻게 처리할지 또는 어떠한 요청 타입을 제한할지 다양한 옵션을 제공합니다. 간단히 초과 요청에 대해서 거부하거나 큐를 설정하여서 나중에 처리하거나 두 가지 방법을 적적하게 조합하여서 처리할 수 있는 방법도 있습니다.
위의 내용을 보았을 때 특정 서비스에 부하가 걸리는 경우 설정을 통하여서 서비스의 부하를 개선할 수 있다고 볼 수 있습니다.
예제
예제 작성 전에 속성에 대해 살펴보도록 하겠습니다.
Config property | Default value | Description |
timeoutDuration | 5 [s] | 스레드가 권한 획득을 기다리는 기본 시간 |
limitRefreshPeriod | 500 [ns] | limitForPeriod 값이 갱신되는 시간 |
limitForPeriod | 50 | limitRefreshPeriod 에 설정된 시간동안 허용되는 요청 수 |
application.yml
spring:
application.name: order-service
output.ansi.enabled: always
server:
port: 7070
management.endpoints.web.exposure.include: '*'
management.endpoint.health.show-details: always
#-----------------------------------------------
# RateLimiter Configuration
#-----------------------------------------------
ratelimiter:
instances:
orderService:
limitForPeriod: 5
limitRefreshPeriod: 1s
timeoutDuration: 0
위의 설정은 1초에 5개의 요청만 처리하도록 하는 설정입니다.
RateLimiterServiceImpl.java
package com.roopy.service.impl;
import com.roopy.service.OrderService;
import io.github.resilience4j.ratelimiter.annotation.RateLimiter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
@Qualifier("rateLimiterService")
public class RateLimiterServiceImpl implements OrderService {
Logger logger = LoggerFactory.getLogger(OrderService.class);
@Autowired
private RestTemplate restTemplate;
@Override
@RateLimiter(name = "orderService", fallbackMethod = "rateLimiterFallback")
public ResponseEntity<String> makeOrder() {
return new ResponseEntity<>(restTemplate.getForObject("http://localhost:7071/pay", String.class), HttpStatus.OK);
}
public ResponseEntity<String> rateLimiterFallback(Throwable t) {
logger.error("Fallback Execution For RateLimiter, cause - {}", t.toString());
return ResponseEntity.status(HttpStatus.TOO_MANY_REQUESTS)
.body("결제 처리 중 오류가 발생하였습니다.");
}
}
JMeter를 이용한 테스트
→ Test Plan 설정
→ Thread Group 설정
하나의 스레드가 주문 서비스를 10번 호출하도록 설정
→ HTTP Request 설정
→ 테스트 결과
예상대로 1초에 5개의 요청만 처리하도록 하여서 10개의 요청을 했지만 5개만 성공한 것을 확인할 수 있다.
→ application.yml 에서 timeoutDuration 값을 25ms 설정 후 테스트
timeoutDuration 을 25ms 설정 후 테스트한 결과 주문 요청을 좀 더 처리한 것을 확인할 수 있다.
소스는 아래 사이트에서 받을 수 있습니다.
https://github.com/roopy1210/spring-boot-resilience4j
'SpringBoot Monitoring > SpringBoot Resilience4j' 카테고리의 다른 글
Bulkhead 예제 (0) | 2021.08.15 |
---|---|
Retry 예제 (0) | 2021.08.07 |
CircuitBreaker 예제 (0) | 2021.07.31 |
CircuitBreaker 개념 (0) | 2021.07.31 |