안티패턴: 자바스크립트 코드에서 waitForComplete() 사용

현재 Apigee Edge 문서가 표시되고 있습니다.
Apigee X 문서로 이동
정보

Apigee Edge의 JavaScript 정책을 사용하면 API 프록시 흐름의 컨텍스트 내에서 실행되는 커스텀 코드를 추가할 수 있습니다. 예를 들어 자바스크립트 정책의 맞춤 코드를 사용하여 다음을 수행할 수 있습니다.

  • 흐름 변수 가져오기 및 설정
  • 커스텀 로직 실행 및 장애 처리 수행
  • 요청 또는 응답에서 데이터 추출
  • 백엔드 대상 URL을 동적으로 수정
  • 요청 또는 응답에서 동적으로 헤더 추가 또는 삭제
  • JSON 응답 파싱

HTTP 클라이언트

자바스크립트 정책의 강력한 기능은 HTTP 클라이언트입니다. HTTP 클라이언트(또는 httpClient 객체)를 사용하여 백엔드 또는 외부 서비스를 한 번 이상 호출할 수 있습니다. HTTP 클라이언트는 여러 외부 서비스를 호출하고 단일 API에서 응답을 매시업해야 할 때 특히 유용합니다.

httpClient 객체로 백엔드 호출을 수행하는 샘플 자바스크립트 코드

var headers = {'X-SOME-HEADER' : 'some value' };
var myRequest = new Request("http://www.example.com","GET",headers);
var exchange = httpClient.send(myRequest);

httpClient 객체는 HTTP 요청을 수행하기 위해 getsend 라는 두 가지 메서드를 노출합니다(위의 샘플 코드에서는 send가 사용됨). 두 메서드는 모두 비동기식이며 실제 HTTP 요청이 완료되기 전에 exchange 객체를 반환합니다.

HTTP 요청은 몇 초에서 몇 분 정도 걸릴 수 있습니다. HTTP 요청이 이루어진 후 요청의 응답이 처리될 수 있도록 완료 시점을 아는 것이 중요합니다. HTTP 요청이 완료된 시점을 확인하는 가장 일반적인 방법 중 하나는 exchange 객체의 waitForComplete() 메서드를 호출하는 것입니다.

waitForComplete()

waitForComplete() 메서드는 HTTP 요청이 완료되고 응답 (성공/실패)이 반환될 때까지 스레드를 일시중지합니다. 그런 다음 백엔드 또는 외부 서비스의 응답을 처리할 수 있습니다.

waitForComplete()를 사용한 샘플 자바스크립트 코드

var headers = {'X-SOME-HEADER' : 'some value' };
var myRequest = new Request("http://www.example.com","GET",headers);
var exchange = httpClient.send(myRequest);
// Wait for the asynchronous GET request to finish
exchange.waitForComplete();

// Get and Process the response
if (exchange.isSuccess()) {
    var responseObj = exchange.getResponse().content.asJSON;
    return responseObj.access_token;
} else if (exchange.isError()) {
    throw new Error(exchange.getError());
}

안티패턴

자바스크립트 코드로 HTTP 요청을 전송한 후 waitForComplete()를 사용하면 성능에 영향을 미칩니다.

HTTP 요청을 전송한 후 waitForComplete()를 호출하는 다음 자바스크립트 코드를 살펴보겠습니다.

sample.js 코드

// Send the HTTP request
var exchangeObj = httpClient.get("http://example.com");
// Wait until the request is completed
exchangeObj.waitForComplete();
// Check if the request was successful
if (exchangeObj.isSuccess())  {

    response = exchangeObj.getResponse();
    context.setVariable('example.status', response1.status);
} else {
   error = exchangeObj.getError();
   context.setVariable('example.error', 'Woops: ' + error);
}

예를 들면 다음과 같습니다.

  1. 자바스크립트 코드가 백엔드 API에 HTTP 요청을 전송합니다.
  2. 그런 다음 waitForComplete()를 호출하여 요청이 완료될 때까지 실행을 일시중지합니다.

    waitForComplete() API는 백엔드가 요청 처리를 완료하고 다시 응답할 때까지 JavaScript 코드를 실행하는 스레드를 차단합니다.

언제든지 메시지 프로세서에서 자바스크립트 코드를 동시에 실행할 수 있는 스레드 수는 상한(30%)이 정해져 있습니다. 이 제한에 도달하면 스레드가 자바스크립트 코드를 실행할 수 없습니다. 따라서 자바스크립트 코드에 waitForComplete() API를 실행하는 동시 요청이 너무 많으면 500 내부 서버 오류 및 '시간 초과' 오류 메시지(자바스크립트 정책 제한 시간이 경과되지 않은 경우에도)와 함께 후속 요청이 실패합니다.

일반적으로 백엔드에서 요청을 처리하는 데 시간이 오래 걸리거나 트래픽이 많은 경우 이러한 상황이 발생할 수 있습니다.

영향

  1. 자바스크립트 코드에서 waitForComplete()를 실행하는 동시 요청 수가 사전 정의된 제한을 초과하면 500 내부 서버 오류 '시간 초과' 오류 메시지와 함께 API 요청이 실패합니다.
  2. 특정 자바스크립트 정책의 시간 제한이 경과되지 않은 경우에도 '시간 초과' 오류와 함께 자바스크립트가 실패하므로 문제의 원인을 진단하기가 까다로울 수 있습니다.

권장사항

HTTP 클라이언트에서 콜백을 사용하여 콜아웃 코드를 간소화하고 성능을 개선하며 자바스크립트 코드에서 waitForComplete()을 사용하지 마세요. 이 메서드는 HTTP 요청이 완료될 때까지 JavaScript를 실행하는 스레드가 차단되지 않도록 합니다.

콜백이 사용되면 스레드가 자바스크립트 코드로 HTTP 요청을 전송하고 풀로 다시 돌아갑니다. 스레드가 더 이상 차단되지 않으므로 다른 요청을 처리할 수 있습니다. HTTP 요청이 완료되고 콜백을 실행할 준비가 되면 태스크가 생성되어 태스크 큐에 추가됩니다. 풀의 스레드 중 하나가 작업의 우선순위에 따라 콜백을 실행합니다.

httpClient에서 콜백을 사용하는 자바스크립트 코드 샘플

function onComplete(response,error) {
 // Check if the HTTP request was successful
    if (response) {
      context.setVariable('example.status', response.status);
     } else {
      context.setVariable('example.error', 'Woops: ' + error);
     }
}
// Specify the callback Function as an argument
httpClient.get("http://example.com", onComplete);

추가 자료