RateLimiter 예제

2021. 8. 22. 01:26SpringBoot 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 설정

RateLimiter Test Plan 설정

→ Thread Group 설정

RateLimiter Thread Group 설정

하나의 스레드가 주문 서비스를 10번 호출하도록 설정

 

→ HTTP Request 설정

RateLimiter HTTP Request 설정

→ 테스트 결과

RateLimiter 테스트 결과

예상대로 1초에 5개의 요청만 처리하도록 하여서 10개의 요청을 했지만 5개만 성공한 것을 확인할 수 있다.

 

→ application.yml 에서 timeoutDuration 값을 25ms 설정 후 테스트

timeoutDuration 설정 후 테스트

timeoutDuration 을 25ms 설정 후 테스트한 결과 주문 요청을 좀 더 처리한 것을 확인할 수 있다.

 

소스는 아래 사이트에서 받을 수 있습니다.

https://github.com/roopy1210/spring-boot-resilience4j

 

GitHub - roopy1210/spring-boot-resilience4j

Contribute to roopy1210/spring-boot-resilience4j development by creating an account on GitHub.

github.com

 

반응형

'SpringBoot Monitoring > SpringBoot Resilience4j' 카테고리의 다른 글

Bulkhead 예제  (0) 2021.08.15
Retry 예제  (0) 2021.08.07
CircuitBreaker 예제  (0) 2021.07.31
CircuitBreaker 개념  (0) 2021.07.31