개발자

거대한 API 데이터를 불러오기

2023년 04월 20일조회 441

안녕하세요 입사한지 얼마 안된 주니어 개발자 입니다. 현재 저희 회사에서 챗봇 서비스를 다른 서비스로 이전하고있는데, 원래 사용중인 챗봇 서비스의 데이터를 저희 백엔드에 저장하는 일을 맡고있습니다. 데이터가 계속 추가되는 상황이고 현재 3만개 정도의 요청을 해야하는데, api응답이 페이징 되어있어 한 번 불러올 때마다 150개씩 약 200페이지를 읽어야합니다. Current 페이지에 다음 페이지의 키 값을 param에 넣어서 요청하면 다음 페이지가 로드되는 방식입니다. 현재 axios와 nodejs를 사용해서 코드 작성을 하고 있는데요. 한시간 반 정도 기다려서 id를 다 가져왔는데 문제는 그 이후에 가져온 id로 다시 3만개의 요청을 보내서 전체 결과를 json에 저장해야하는데.. 한시간 후에 확인하면 ETIMEOUT 에러가 뜹니다. Axios에러이고 너무 많은 요청을 보내서 뜬 것 같은데 시간도 너무 오래걸리고 디버깅 하기가 어려운 상황입니다ㅠㅠ 혹시 이렇게 많은 양의 api를 호출할 때 좀 더 효율적인 방법이 있을까요..? async로만 처리하기엔 한계가 있는것 같습니다ㅠ

이 질문이 도움이 되었나요?
'추천해요' 버튼을 누르면 좋은 질문이 더 많은 사람에게 노출될 수 있어요. '보충이 필요해요' 버튼을 누르면 질문자에게 질문 내용 보충을 요청하는 알림이 가요.
profile picture
익명님의 질문

답변 3

이재찬님의 프로필 사진

좀 더 찾아보면 여러 방법이 있기야 하겠지만, axios responseType을 stream으로 설정하여 chunk 단위로 데이터를 받아 메모리부족을 해결하는 방법을 사용했었는데 잘 될지는 모르겠습니다.

profile picture

익명

작성자

2023년 04월 21일

조언 감사합니다!! 내일 더 알아보고 시도해볼게요😎

커리어리 AI 봇님의 프로필 사진

안녕하세요, 주니어 개발자님! 이런 상황에서 더 효율적으로 API 호출을 처리하는 방법을 찾으시는군요. 몇 가지 방법을 제안드리겠습니다. 1. 병렬 요청 제한하기 Axios를 사용해 요청을 보낼 때 동시에 너무 많은 요청을 보내면 서버에서 거부할 수 있습니다. 따라서 Promise.all이나 async.mapLimit 같은 도구를 사용해 동시에 처리할 수 있는 요청 수를 제한할 수 있습니다. 2. 요청 간 지연 시간 추가하기 API 서버가 각 요청 사이에 일정 시간을 요구하는 경우, 요청 간 지연 시간을 추가할 수 있습니다. 이를 위해 setTimeout 또는 Promise.delay와 같은 도구를 사용할 수 있습니다. 3. 캐싱 동일한 데이터를 여러 번 요청하는 경우, 캐싱을 사용해 이전에 가져온 데이터를 저장하고 재사용할 수 있습니다. 이렇게 하면 API 서버에 요청하는 횟수를 줄일 수 있습니다. 4. 서버와 협업 서버 측에서 요청 제한 정책을 변경할 수 있는지 확인하십시오. 이를 통해 동시 요청 수를 늘리거나 요청 간 지연 시간을 줄일 수 있습니다. 이러한 방법 중 일부 또는 모두를 사용하여 API 호출을 효율적으로 처리하고 에러를 줄일 수 있습니다. 제안한 방법들을 적용한 통합 코드 예제를 드리겠습니다. 이 예제에서는 동시 요청 수를 10개로 제한하고, 요청 간 지연 시간을 1000밀리초로 설정했습니다. 이 값을 조절하여 시스템에서 허용하는 동시 요청 수와 지연 시간을 찾으십시오. 이렇게 하면 API 호출을 효율적으로 처리하고 에러를 줄일 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const async = require('async');
const axios = require('axios');

async function fetchAllData(ids) {
  return new Promise((resolve, reject) => {
    async.mapLimit(ids, 10, async (id) => {
      const response = await axios.get(`https://api.example.com/data/${id}`);
      // 요청 간 지연 시간 추가 (예: 1000ms)
      await new Promise((resolve) => setTimeout(resolve, 1000));
      return response.data;
    }, (err, results) => {
      if (err) {
        reject(err);
      } else {
        resolve(results);
      }
    });
  });
}

커리어리 AI 봇의 답변을 평가해 주세요!

커리어리 AI 봇님의 프로필 사진

안녕하세요, 주니어 개발자님. 데이터가 많은 API를 처리하는 경우에는 한 번에 많은 양의 데이터를 가져오려고 하면 문제가 발생할 수 있습니다. 대부분의 API는 페이지 매개 변수와 같은 기능을 제공하여 쿼리에 대한 결과를 분할 할 수 있게합니다. 그러나 200 페이지가 있으며 150 개의 결과가 있기 때문에 페이지가 많습니다. 이러한 API를 호출하는 경우 병렬 처리 기능을 사용하여 API를 병렬로 호출 할 수 있습니다. 이렇게하면 요청이 더 빨리 처리되어 전체 작업을 완료하는 데 걸리는 시간이 줄어듭니다. Node.js의 ' Promise.all() ' 함수를 사용하면 다수의 HTTP 요청을 병렬로 처리할 수 있습니다. 다음은 ' Promise.all() '을 사용하여 병렬로 HTTP 요청을 수행하는 간단한 예입니다. 아래 코드에서는 ' urls ' 배열에 있는 모든 URL을 병렬로 요청하고, ' Promise.all() ' 함수를 사용하여 모든 응답을 기다립니다. 그리고 모든 응답이 도착하면 각각의 응답에서 필요한 데이터를 추출하고 처리합니다. 또한, 가져온 데이터를 저장하는 방법도 고려해야 합니다. 모든 데이터를 메모리에 저장하려면 시스템 자원을 많이 소비하게 됩니다. 이 경우 데이터베이스나 파일 시스템에 저장하는 것이 좋습니다. 그러나 이 경우 저장되는 데이터의 구조에 대한 고려도 필요합니다. 많은 양의 데이터를 처리하는 경우에는 API에서 분할을 지원하는지 확인하고, 필요한 경우 병렬 처리를 사용하고 데이터를 저장하는 방법에 대해 고려해야 합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const axios = require('axios');

const urls = ['http://example.com/1', 'http://example.com/2', 'http://example.com/3'];

const requests = urls.map(url => axios.get(url));

Promise.all(requests)
  .then(responses => {
    // responses에는 모든 응답이 배열로 들어갑니다.
    // 각각의 응답에서 필요한 데이터를 추출하고 처리합니다.
  })
  .catch(error => {
    // 오류 처리
  });

지금 가입하면 모든 질문의 답변을 볼 수 있어요!

현직자들의 명쾌한 답변을 얻을 수 있어요.

또는

이미 회원이신가요?

목록으로
키워드로 질문 모아보기

실무, 커리어 고민이 있다면

새로운 질문 올리기

지금 가입하면 모든 질문의 답변을 볼 수 있어요!