ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • JMeter를 사용한 API호출 부하 테스트 에러 수정 -1
    spring 2024. 2. 5. 17:46
    반응형

     

    • 도입

     

    OpenAPI 호출을 이용한 프로젝트를 만들며 서버 부하 테스트를 적용해 보고자 하였다.

     

    서버 부하 테스트를 위한 프로그램으로 JMeter를 사용하기로 하였다.

     

    • 서버 부하 테스트 실행 이유

     

    내가 생각한 서버 부하 테스트를 하는 이유는 다음과 같다.

    개발단계에서 고려해야 할 요인에는 여러가지가 있는데, 그 중에서 실제 배포 환경에 대한 고민이 필요하다 느꼈다.

    혼자서 개발할 때는 호출 건수도 적고 한정적이기 때문에 대부분 안정적인 결과가 나온다.

    하지만 실제 배포를 하게 된다면 예측할 수 없었던 수많은 호출과 에러가 생기는 것이 당연하다.

    서버 부하 테스트는 실제 배포 환경에서 일어날 여러 변수들을 미리 겪어보고 성능을 최적화 하기 위해 실행하게 되었다.

     

    • 설치 및 실행

    mac 사용 환경에서 HomeBrew를 사용할 경우 JMeter 설치는 간편하다.

    터미널에서 brew install jmeter를 통해 설치를 한 후, Jmeter 또는 ./Jmeter 또는 open Jmeter 등을 이용해 실행할 수 있다.

     

     

    실행 후 옵션- language에서 한국어로 설정한 후 Test Plan에서 우클릭 - 추가 -쓰레드들- 쓰레드 그룹을 누르면 쓰레드 그룹이 생긴다.

     

    쓰레드 그룹 설정

    쓰레드 그룹의 설정에서 쓰레드들의 수는 사용자 수를 의미하고, Ramp-up 시간은 해당 요청을 몇초 동안 할 것인지, 루프 카운트는 사용자가 몇번 호출을 할 것인지를 의미한다.  위의 사진의 경우 10명의 사용자가 1초동안 10번씩 총 100번의 호출을 한다는 것을 의미한다.

     

    이후 쓰레드그룹에서 우클릭 - 추가 - 리스너 - 1.요약보고서, 2.결과들의 트리보기, 3. 결과 그래프 를 추가하여 반환되는 데이터를 확인 할 수 있다.

     

    마지막으로 쓰레드그룹에서 우클릭 - 표본추출기 -http요청으로 들어가 apI 호출의 기본내용을 설정할 수 있다.

    http요청 기본설정

     

    아직 https가 아닌 http프로토콜을 사용하기 때문에 http, 로컬 환경에서 사용하기 때문에 localhost, 포트번호 8080 , 엔드포인트 등을 적어주고 파라미터들의 값도 넣어주었다.

     

    • 에러 발생

    이후 테스트를 돌렸을 때 intelij에서 아래와 같은 에러 로그가 나왔다.

    api 호출 제한 에러

    넥슨 openApI는 개발 환경에서 최대 호출 건수를 5건/초, 1,000건/일 으로 설정하고 있다.

    즉, 내가 호출한 호출 방식은 이러한 제한을 두지 않고 1초에 100건의 요청을 호출했기 때문에 문제가 발생했다.

     

    • 1차 코드 수정

    초당 호출되는 API 건수를 제한 하는 방법으로Rate limit 방법을 사용했다.

     

    우선 build.gradle의

    dependencies에 implementation 'com.google.guava:guava:30.1-jre' 를 추가하여 build한 후

     

    Controller class에 

    private final RateLimiter rateLimiter = RateLimiter.create(5.0); 를 추가하였다.
    이는 초당 5회의 제한을 주겠다는 의미이다.
    @GetMapping("/maplestory/v1/character/basic")

    public ResponseEntity<CharacterInfo> getCharacterInfo(@RequestParam String name, String date) {

    if (rateLimiter.tryAcquire()) { //초당 5회 미만인 경우 기존 호출 코드 실행
    //기존 호출 코드
    else {
    System.err.println("호출 제한 초과");
    return ResponseEntity.status(HttpStatus.TOO_MANY_REQUESTS).build();
    위의 코드로 수정한 결과
    먼저 사용자수 1일때는, 루프카운트가 늘어나도 호출 제한 에러가 생기지 않았다.
    그러나 사용자수가 늘어날 경우 호출 에러가 생겼다.
    • 2차 코드 수정

    private final RateLimiter rateLimiter = RateLimiter.create(50.0) 코드를 수정하여 초당 50건의 제한으로 하였더니 부분적으로 에러가 발생하였다. 초당 5회의 제한보다 제한을 느슨히 했는데 오히려 에러가 줄어들었다.

    하지만 이 역시 적절한 해결방안은 아니다.

     

    • 3차 코드 수정

    RateLimt에 대해 더 알아보던 중 이 방법은 스레드당 토큰을 발급하여 제한하는 방식이므로 다수의 스레드(사용자)의 환경에서는 제대로 동작할 수 없다는 것을 알게 되었다. 따라서 다른 방법을 알아보기로 하였다.

     

    다음 오류 개선에는 우선 쓰레드 풀 방식을 적용해볼 생각이다. 

     

     

    반응형

    댓글

Designed by Tistory.