Riot API Key Test

김머랭·2024년 5월 1일

문제점

  • Riot API를 사용한 프로젝트 중, 특정 시간 내 정해진 양을 초과한 API 호출로 인해 HTTP STUTS 429 Too Many Requests 로 실패하는 경우가 많았습니다.
  • 시간 텀을 두고 API를 호출하면 해결 할 수 있는 문제이지만, 이는 성능과 직결된 문제로 타협할 수 없었고 여러명을 조회해오는 프로젝트 특성 상 API 호출 양도 조절 할 수 없었습니다.

생각한 해결법

  • Riot에서 발급한 API key를 기준으로 호출 횟수를 카운트 한다면, 여러 개의 API key로 429 문제를 회피할 수 있지 않을까?

무엇을 테스트하려 했는가?

  • IP 별로 요청 횟수를 카운트하여 429 실패 처리를 하는지, API key를 기준으로 429 실패처리를 하는지 여부

테스트

  • 1개의 API key를 사용했을때와, 2개의 API key를 번갈아가면서 사용했을때 429가 발생하는 횟수와 시간을 측정
  • 테스트 사이 최소 2분 텀을 두고 진행(2분 이내로 빠르게 재요청을 할 경우 api키가 2개여도 429가 발생 하는 것을 확인)
	  
	  // API Key 2개
    @Test
    public void testWithApiKeyChange() {
        long beforeTime = System.currentTimeMillis();

        try {
            webClientTest(150, true);
        } catch (WebClientResponseException e) {
            System.out.println("Response body: " + e.getResponseBodyAsString());
        }

        long afterTime = System.currentTimeMillis();
        double secDiffTime = (double) (afterTime - beforeTime) / 1000.0;
        System.out.println("시간차이(s) : " + secDiffTime);
    }
    
    // API Key 1개
    @Test
    public void testWithSingleApiKey() {
        long beforeTime = System.currentTimeMillis();

        try {
            webClientTest(150, false);
        } catch (WebClientResponseException e) {
            System.out.println("Response body: " + e.getResponseBodyAsString());
        }

        long afterTime = System.currentTimeMillis();
        double secDiffTime = (double) (afterTime - beforeTime) / 1000.0;
        System.out.println("시간차이(s) : " + secDiffTime);
    }

    public void webClientTest(int count, boolean useBothKeys) {
        String key = key1;
        for (int i = 0; i < count; i++) {
            if (useBothKeys) {
                key = (i % 2 == 0) ? key1 : key2;
            }
            System.out.println(find("킴대세", "KR1", key));
            System.out.println(i + 1 + "번째");
        }
    }

    public Account find(String nickname, String tag, String riotApiKey) {
        Account account = webClient
                .get()
                .uri("https://asia.api.riotgames.com/riot/account/v1/accounts/by-riot-id/" + nickname + "/" + tag + "?api_key=" + riotApiKey)
                .retrieve()
                .bodyToMono(Account.class)
                .block();
        if (account == null) {
            throw new AccountNotFoundException();
        }
        return account;
    }

결과

100번 요청

  • key 1개 → 시간: 11초
  • key 2개 → 시간: 11초
  • 결과 → 2개 이상 API key 를 번갈아가면서 요청 했을 때도, 성능에 눈에 띄는 변화는 없음을 확인

101번 요청

  • key 1개 → 100번째 요청이 넘어가면서 429발생
  • key 2개 → 시간: 11초
  • 결과 → 100번째 요청이 임계점임을 확인 및 2개 이상 API key 를 번갈아가면서 요청한 경우 429 회피할 수 있음을 확인

200번 요청

  • key 1개 → 100번째 요청이 넘어가면서 429발생
  • key 2개 → 시간: 22초
  • 결과 → 2개 이상 API key 를 번갈아가면서 요청한 경우 직전 실패 케이스인 101번 요청의 약 2배 횟수를 커버할 수 있음을 확인

사용자 여러 명의 데이터를 조회하는 그룹 조회가 핵심 기능인 저희 프로젝트 처럼, API 요청 횟수가 많은 기능 요구사항을 가진 프로젝트라면 참고하실만한 방법이 아닐까 싶습니다.

최고의 방법은 아니지만, 하나의 방법으로 생각해주시고 참고 부탁드립니다.

profile
"어?~" 왜 안돌아가지.. "어?~" 왜 돌아가지..

0개의 댓글