API Gateway를 통한 Batch Request Processing
April 27, 2023
배치 요청 처리는 웹 개발에서 API 성능을 향상시키기 위해 사용되는 강력한 기술입니다. 이를 통해 개발자는 여러 API 요청을 단일 HTTP 요청/응답 주기로 그룹화할 수 있습니다. 즉, 클라이언트로부터의 단일 API 요청을 여러 백엔드 서버에 대한 여러 API 요청으로 변환하고, 응답을 집계하여 클라이언트에게 단일 응답으로 반환할 수 있습니다. 이는 클라이언트와 서버 간의 왕복 횟수를 크게 줄일 수 있습니다.
이 글에서는 Apache APISIX에서 배치 요청 처리를 구현하는 방법을 탐구하고, 이를 활용할 수 있는 몇 가지 사용 사례를 살펴보겠습니다.
이는 마이크로서비스 아키텍처에서 널리 적용되는 API 컴포지션 패턴과 유사합니다.
배치 요청 처리를 사용하는 이유는 무엇인가요?
클라이언트가 서버에 여러 API 요청을 보낼 때, 각 요청은 별도의 HTTP 요청/응답 주기가 필요합니다. 이는 지연 시간 증가, 성능 저하 및 서버 부하 증가로 이어질 수 있습니다. 여러 요청을 단일 배치 요청으로 그룹화하면 HTTP 요청/응답 주기의 횟수를 줄여 성능을 향상시키고 지연 시간을 줄일 수 있습니다.
배치 요청 처리는 다음과 같은 시나리오에서 특히 유용할 수 있습니다:
- 데이터베이스에서 여러 레코드를 검색할 때
- 데이터베이스에서 여러 레코드를 업데이트할 때
- 작업을 완료하기 위해 여러 API 요청을 실행할 때
배치 요청 처리의 실제 예시
예시 1:
사용자의 피드를 표시하는 소셜 미디어 애플리케이션이 있다고 가정해 보겠습니다. 이 피드에는 사용자의 친구와 팔로우하는 페이지의 게시물이 포함됩니다. 이 피드를 채우기 위해 필요한 데이터를 검색하기 위해 여러 API 요청을 해야 합니다. 예를 들어:
- 사용자의 친구 목록과 팔로우하는 페이지를 검색합니다.
- 각 친구 또는 페이지에 대해 최근 게시물을 검색합니다.
전통적인 접근 방식에서는 이러한 각 API 요청을 별도로 수행합니다. 먼저 사용자의 친구 목록을 검색하고, 두 번째 요청에서 각 친구의 최근 게시물을 가져옵니다. 이는 사용자가 많은 친구를 가지고 있고 많은 페이지를 팔로우할 때 특히 지연 시간을 증가시킬 수 있습니다.
예시 2:
다른 예로, 사용자가 탐색할 수 있는 제품 목록을 표시하는 모바일 애플리케이션이 있다고 가정해 보겠습니다. 이 목록을 채우기 위해 원격 서버에서 제품 데이터를 검색하기 위해 여러 API 요청을 해야 합니다. 예를 들어:
- 제품 ID 목록을 검색합니다.
- 각 제품 ID에 대해 제품 세부 정보(이름, 설명, 이미지 등)를 검색합니다.
예시 3:
컨퍼런스 관리 웹 앱이 있다고 상상해 보세요. 시스템에는 여러 명의 스피커가 있으며, 단일 웹 페이지에 스피커의 세션과 관련 주제를 표시하려고 합니다. 백엔드 컨퍼런스 API 서비스는 이 정보를 노출하기 위해 두 개의 다른 엔드포인트 /speaker/{speakerId}/sessions
와 /speaker/{speakerId}/topics
를 가지고 있습니다. 단일 스피커에 속한 세션과 주제를 모두 표시하기 위해 프론트엔드 앱에서 두 개의 요청을 보낼 수 있지만, 이는 이상적인 해결책이 아닙니다. 대신, 다음 섹션에서 설명하는 것처럼 API 게이트웨이를 사용하여 이러한 모든 요청을 단일 HTTP 요청으로 그룹화할 수 있습니다.
Apache APISIX API 게이트웨이를 사용한 배치 요청 처리
APISIX에서 배치 요청 처리를 구현하려면 batch-requests 플러그인을 사용할 수 있습니다. 이 플러그인을 사용하면 단일 HTTP POST
요청 페이로드에 여러 API 요청을 정의할 수 있습니다. 각 요청은 자신의 HTTP 메서드, URL 경로, 헤더 집합 및 페이로드를 가질 수 있습니다. 예시 3(컨퍼런스 API 요청)에 대한 curl 요청 명령어를 참조하세요:
curl -i http://{API_GATEWAY_HOST_ADDRESS}/speaker -X POST -d \
'{
"pipeline": [
{
"method": "GET",
"path": "/speaker/1/topics"
},
{
"method": "GET",
"path": "/speaker/1/sessions"
}
]
}'
APISIX가 배치 요청을 받으면 batch-requests 플러그인이 페이로드를 파싱하고 배치의 각 요청을 병렬로 실행합니다. 플러그인은 또한 각 요청의 응답을 집계하여 클라이언트에게 단일 HTTP 응답으로 반환합니다. 다음 데모 섹션에서 이를 단계별로 수행하는 방법을 알아보세요.
배치 요청 플러그인 데모
batch-requests 플러그인을 사용하기 전에 Apache APISIX를 설치해야 합니다.
전제 조건
- Docker는 컨테이너화된 etcd와 APISIX를 설치하는 데 사용됩니다.
- curl은 APISIX Admin API에 요청을 보내는 데 사용됩니다. Postman과 같은 쉬운 도구를 사용하여 API와 상호 작용할 수도 있습니다.
다음 quickstart 스크립트를 사용하여 APISIX를 쉽게 설치하고 시작할 수 있습니다:
curl -sL <https://run.api7.ai/apisix/quickstart> | sh
백엔드 서비스 구성(업스트림)
요청을 라우팅할 컨퍼런스 API에 대한 백엔드 서비스를 구성해야 합니다. 이는 Apache APISIX에서 Admin API를 통해 업스트림 서버를 추가하여 수행할 수 있습니다.
curl http://127.0.0.1:9180/apisix/admin/upstreams/1 -X PUT -d '
{
"name": "Conferences API upstream",
"desc": "Register Conferences API as the upstream",
"type": "roundrobin",
"scheme": "https",
"nodes": {
"conferenceapi.azurewebsites.net:443": 1
}
}'
배치 처리 API를 위한 라우트 생성
/speaker
에 대한 요청을 가로채고 [public-api](https://apisix.apache.org/docs/apisix/plugins/public-api/)
플러그인을 사용하여 배치 처리를 위한 공개 가상 엔드포인트를 노출하는 새로운 라우트를 생성해야 합니다.
curl http://127.0.0.1:9180/apisix/admin/routes/a -X PUT -d '
{
"uri": "/speaker",
"plugins": {
"public-api": {
"uri": "/apisix/batch-requests"
}
}
}'
스피커의 주제 및 세션 엔드포인트를 위한 라우트 생성
다음으로, 스피커의 주제 및 세션 엔드포인트(/speaker/*/topics
및 /speaker/*/topics
경로 매칭)를 위한 또 다른 라우트를 생성합니다. 이렇게 하면 API 게이트웨이가 배치 요청에서 추출한 개별 요청이 스피커의 주제 또는 세션을 검색하기 위해 책임 있는 컨퍼런스 API 엔드포인트로 전달되며, 기존 업스트림 서비스를 참조합니다.
curl http://127.0.0.1:9180/apisix/admin/routes/b -X PUT -d '
{
"methods": ["GET"],
"uris": ["/speaker/*/topics","/speaker/*/sessions"],
"plugins": {
"proxy-rewrite":{
"host":"conferenceapi.azurewebsites.net"
}
},
"upstream_id":"1"
}'
여기서는 또 다른 proxy-rewrite 플러그인을 사용하고 컨퍼런스 API의 호스트 주소를 암시적으로 지정하고 있습니다. 그렇지 않으면 API 게이트웨이가 DNS 변환을 수행하고 컨퍼런스 API를 IP 주소로 요청할 수 있습니다.
배치 요청 처리 테스트
다음은 APISIX에서 batch-requests 플러그인을 사용하는 방법의 예입니다:
curl -i http://127.0.0.1:9080/speaker -X POST -d \
'{
"pipeline": [
{
"method": "GET",
"path": "/speaker/1/topics"
},
{
"method": "GET",
"path": "/speaker/1/sessions"
}
]
}'
이 예제에서는 /speaker
엔드포인트에 대한 라우트가 정의되어 있으며, batch-requests 플러그인을 통해 배치 요청 처리를 지원합니다. 플러그인은 두 개의 요청 집합으로 구성되어 있으며, 각 요청은 주제와 세션을 포함한 스피커 레코드를 ID로 검색합니다. 이 명령을 실행하면 API 게이트웨이로부터 병합된 응답을 받을 수 있습니다:
[
{
"body":"{\r\n \"collection\": {\r\n \"version\": \"1.0\",\r\n \"links\": [],\r\n \"items\": [\r\n {\r\n \"href\": \"https://conferenceapi.azurewebsites.net/topic/8\",\r\n \"data\": [\r\n {\r\n \"name\": \"Title\",\r\n \"value\": \"Microsoft\"\r\n }\r\n ],\r\n \"links\": [\r\n {\r\n \"rel\": \"http://tavis.net/rels/sessions\",\r\n \"href\": \"https://conferenceapi.azurewebsites.net/topic/8/sessions\"\r\n }\r\n ]\r\n },\r\n {\r\n \"href\": \"https://conferenceapi.azurewebsites.net/topic/10\",\r\n \"data\": [\r\n {\r\n \"name\": \"Title\",\r\n \"value\": \"Mobile\"\r\n }\r\n ],\r\n \"links\": [\r\n {\r\n \"rel\": \"http://tavis.net/rels/sessions\",\r\n \"href\": \"https://conferenceapi.azurewebsites.net/topic/10/sessions\"\r\n }\r\n ]\r\n }\r\n ],\r\n \"queries\": [],\r\n \"template\": {\r\n \"data\": []\r\n }\r\n }\r\n}",
"status":200,
"headers":{
"Expires":"-1",
"Connection":"keep-alive",
"Pragma":"no-cache",
"Content-Length":"953",
"Server":"APISIX/3.2.0",
"Content-Type":"application/vnd.collection+json",
"X-AspNet-Version":"4.0.30319",
"Cache-Control":"no-cache",
"X-Powered-By":"ASP.NET"
},
"reason":"OK"
},
{
"body":"{\r\n \"collection\": {\r\n \"version\": \"1.0\",\r\n \"links\": [],\r\n \"items\": [\r\n {\r\n \"href\": \"https://conferenceapi.azurewebsites.net/session/206\",\r\n \"data\": [\r\n {\r\n \"name\": \"Title\",\r\n \"value\": \"\\r\\n\\t\\t\\tjQuery Mobile and ASP.NET MVC\\r\\n\\t\\t\"\r\n },\r\n {\r\n \"name\": \"Timeslot\",\r\n \"value\": \"05 December 2013 09:00 - 10:00\"\r\n },\r\n {\r\n \"name\": \"Speaker\",\r\n \"value\": \"Scott Allen\"\r\n }\r\n ],\r\n \"links\": [\r\n {\r\n \"rel\": \"http://tavis.net/rels/speaker\",\r\n \"href\": \"https://conferenceapi.azurewebsites.net/speaker/16\"\r\n },\r\n {\r\n \"rel\": \"http://tavis.net/rels/topics\",\r\n \"href\": \"https://conferenceapi.azurewebsites.net/session/206/topics\"\r\n }\r\n ]\r\n }\r\n ],\r\n \"queries\": [],\r\n \"template\": {\r\n \"data\": []\r\n }\r\n }\r\n}",
"status":200,
"headers":{
"Expires":"-1",
"Connection":"keep-alive",
"Pragma":"no-cache",
"Content-Length":"961",
"Server":"APISIX/3.2.0",
"Content-Type":"application/vnd.collection+json",
"X-AspNet-Version":"4.0.30319",
"Cache-Control":"no-cache",
"X-Powered-By":"ASP.NET"
},
"reason":"OK"
}
]
배치 요청의 최대 크기는 API 게이트웨이에 의해 제한됩니다. 현재 제한 및 요청 시간 초과 구성에 대해서는 API 게이트웨이 문서를 확인하세요.
주요 내용
- API 게이트웨이를 사용한 배치 요청 처리는 API 성능을 향상시키는 데 유용한 기술일 수 있습니다.
- Apache APISIX는 개발자가 배치 요청 처리를 쉽게 구현할 수 있도록 **
batch-requests
**라는 플러그인을 제공합니다.
다음 단계
API 게이트웨이를 사용하면 사용자에게 응답 데이터의 일부 사용자 정의 집계를 제공할 수도 있습니다. serverless-function 플러그인을 사용하여 사용자 정의 코드를 실행하고 백엔드 서비스의 응답을 병합하여 API 소비자에게 다른 구조로 반환할 수 있습니다.