1. 개요
이 사용방법(예제)에서는 HAProxy를 라우팅 및 속도 제한을 위한 API 게이트웨이로 사용하는 방법을 배웁니다.
2. API 게이트웨이로서의 HAProxy
API 게이트웨이는 클라이언트와 수많은 백엔드 서비스 사이에 있는 애플리케이션입니다. 리버스 프록시처럼 작동합니다 . API 호출을 해당 서비스로 라우팅합니다. 또한 서비스 Security, API 호출 속도 제한, 트래픽 모니터링, 때로는 로드 밸런싱과 같은 많은 책임을 맡을 수 있습니다.
HAProxy 는 오픈 소스 소프트웨어 로드 밸런서 및 애플리케이션 제공 컨트롤러 입니다. 매우 효율적이며 업계에서 널리 사용됩니다.
다음 섹션에서는 API 게이트웨이 역할을 하도록 HAProxy를 구성합니다.
3. HAProxy를 사용한 HTTP API 라우팅
API 게이트웨이의 주요 책임 중 하나는 HTTP 요청을 대상 서버로 라우팅하는 것입니다. 경로, 소스 도메인 및 데이터 형식을 기반으로 HTTP 요청 라우팅을 시작하도록 HAProxy 구성을 시작합니다.
3.1. 기본 구성
HAProxy 의 기본 구성 은 로드 밸런서가 되는 것입니다. 예제 의 프런트엔드 와 백엔드 를 정의합니다 .
frontend haproxy_as_api_gateway
bind 127.0.0.1:80
default_backend load_balancing
backend load_balancer
server server1 127.0.0.1:8080
server server2 127.0.0.1:8081
부하 분산에 사용할 두 개의 서버가 있습니다 . 클라이언트 측 애플리케이션은 127.0.0.1:80 에서 요청을 해결합니다 . 여기에서 HAProxy는 백엔드 load_balancer 를 정의한 대로 사용 가능한 서버로 라우팅하는 데 도움이 됩니다 . 이 백엔드는 127.0.0.1:8080 및 127.0.0.1:8081 에서 확인되는 두 서버 위에 있습니다 .
사용 사례와 관련하여 API 게이트웨이처럼 작동하도록 추가 구성을 추가할 것입니다.
3.2. 경로별로 요청 분리
API 게이트웨이의 기본 기능은 HTTP API 호출을 마이크로서비스 아키텍처의 각 서비스로 라우팅하는 것입니다.
클라이언트 응용 프로그램에 대한 온라인 상점의 두 Endpoints을 지정했다고 가정해 보겠습니다. 엔드포인트 127.0.0.1:80/order 에서 주문을 받습니다 . 다른 하나는 엔드포인트 127.0.0.1:80/invoicing 에서 송장 발행을 관리합니다 .
이 두 Endpoints에 대해 두 개의 개별 마이크로 서비스를 배포했습니다. 주문 서비스는 127.0.0.1:8080에서 해결되고 청구 서비스는 127.0.0.1:8081 에서 해결됩니다 .
구성은 다음과 같습니다.
frontend haproxy_as_api_gateway
bind 127.0.0.1:80
acl PATH_order path_beg -i /order
acl PATH_invoicing path_beg -i /invoicing
use_backend order_service if PATH_order
use_backend invoicing_service if PATH_invoicing
backend order_service
server server1 127.0.0.1:8080
backend invoicing_service
server server1 127.0.0.1:8081
이 구성에서 경로 /order 는 항상 백엔드 order_service 에서 확인됩니다 . 마찬가지로 /invoicing 경로 는 항상 백엔드 invoicing_service 에서 확인됩니다 .
주문 서비스의 한 서버가 로드를 관리할 수 없는 경우 127.0.0.1:8090 에서 확인하는 다른 서버를 추가 하고 HAProxy의 로드 밸런싱 기능을 사용할 수 있습니다.
frontend haproxy_as_api_gateway
bind 127.0.0.1:80
acl PATH_order path_beg -i /order
acl PATH_invoicing path_beg -i /invoicing
use_backend order_service if PATH_order
use_backend invoicing_service if PATH_invoicing
backend order_service
server server1 127.0.0.1:8080
server server2 127.0.0.1:8090
backend invoicing_service
server server1 127.0.0.1:8081
이러한 방식으로 주문 서비스를 다른 위치로 라우팅할 뿐만 아니라 로드 밸런싱도 합니다.
3.3. 도메인별로 요청 분리
간단한 시나리오의 경우 위의 구성이 제대로 작동합니다. 그러나 현실 세계에서 우리는 복잡한 시나리오를 경험합니다. 이러한 시나리오 중 하나는 서로 다른 도메인에 대한 API 경로를 분리하는 것 입니다.
온라인 상점의 예를 계속 살펴보겠습니다. 주문 API는 소비자가 사용하고 인보이스는 운영 팀에서 사용합니다. 소비자 웹 사이트와 운영 팀 포털을 위한 두 개의 서로 다른 도메인이 있습니다 . 각 도메인에는 해당 API 경로가 있습니다.
소비자가 웹사이트에서 인보이스에 액세스하려고 시도하는 경우 이러한 요청이 해결되지 않아야 합니다. 마찬가지로 운영 팀 포털의 주문 요청은 해결되지 않아야 합니다.
위의 시나리오를 달성하는 방법은 다음과 같습니다.
frontend haproxy_as_api_gateway
bind :80
acl consumerapi_host req.hdr(Host) -i -m dom 127.0.0.1
acl operationapi_host req.hdr(Host) -i -m dom 127.0.0.2
acl PATH_order path_beg -i /order
acl PATH_invoicing path_beg -i /invoicing
use_backend order_service if consumerapi_host PATH_order
use_backend invoicing_service if operationapi_host PATH_invoicing
backend order_service
server server1 127.0.0.1:8080
server server2 127.0.0.1:8090
backend invoicing_service
server server1 127.0.0.1:8081
이 구성을 사용 하여 두 도메인 127.0.0.1 및 127.0.0.2에 대해 각각 consumerapi_host 및 operationapi_host 라는 두 변수를 정의 했습니다 .
HAProxy는 요청이 경로 순서( 예: 127.0.0.1:80/order )로 consumerapi_host 에서 오는 경우에만 요청을 order_service 백엔드로 라우팅합니다 . 마찬가지로 요청이 invoicing 경로 ( 예: 127.0.0.2:80/invoicing )가 있는 operationapi_host 에서 오는 경우에만 요청을 invoicing_service 백엔드로 라우팅합니다 .
3.4. 데이터 형식별로 요청 분리
요청의 콘텐츠 유형에 따라 주문 서비스를 분리해야 하는 시나리오가 있을 수 있습니다. 예를 들어, 특정 클라이언트는 XML 형식으로 데이터를 보내고 다른 클라이언트는 JSON 형식으로 데이터를 보낼 수 있습니다 .
위의 요구 사항을 수용할 수 있는 방법은 다음과 같습니다.
frontend haproxy_as_api_gateway
bind :80
acl consumerapi_host req.hdr(Host) -i -m dom 127.0.0.1
acl operationapi_host req.hdr(Host) -i -m dom 127.0.0.2
acl api_json req.hdr(Content-Type) -i -m dom application/json
acl api_xml req.hdr(Content-Type) -i -m dom application/xml
acl PATH_order path_beg -i /order
acl PATH_invoicing path_beg -i /invoicing
use_backend order_service_json if consumerapi_host api_json PATH_order
use_backend order_service_xml if consumerapi_host api_xml PATH_order
use_backend invoicing_service if operationapi_host PATH_invoicing
backend order_service_json
server server1 127.0.0.1:8080
backend order_service_xml
server server2 127.0.0.1:8090
backend invoicing_service
server server1 127.0.0.1:8081
이제 주문 서비스에 대해 서로 다른 두 개의 백엔드를 정의했습니다. 127.0.0.1:8080 은 모든 JSON 요청을 처리합니다. 127.0.0.1:8090 은 모든 XML 요청을 처리합니다.
요청 헤더를 사용하여 들어오는 모든 요청에 대해 두 개의 변수 api_json 및 api_xml을 정의했습니다. 경로에 주문이 있는 소비자 도메인에서 요청이 오는 경우에만 사용법을 추가했습니다.
4. 속도 제한
속도 제한은 클라이언트의 요청 수를 제한합니다. 우리의 경우 주문 수를 제한하고 싶을 수 있습니다. 예를 들어, 우리는 10초에 100개의 주문을 제한합니다. 그 외에도 일부 악의적인 활동이 진행되고 있다고 예상할 수 있습니다. 또는 로드를 관리하기 위해 추가 서버를 추가해야 할 수도 있습니다.
우선 path_param_rates.map 파일을 생성 하겠습니다 . 각각의 제한이 있는 경로를 추가할 것입니다.
/order 100
HAProxy에서 스틱 테이블 은 다양한 매개변수를 추적하고 저장하는 데 사용됩니다. 스틱 테이블은 HAProxy 내의 빠른 메모리 내 스토리지 입니다. 클라이언트 세션 관련 데이터를 키/값 쌍으로 저장합니다.
이 경우 주문 요청이 접수된 횟수를 추적합니다.
frontend haproxy_as_api_gateway
bind :80
stick-table type string size 1m expire 10s store http_rate_limiting
http-request track-sc0 base32+src
http-request set-var(req.rate_limit) path,map_beg(path_param_rates.map,20)
http-request set-var(req.request_rate) base32+src,table_http_rate_limiting()
acl rate_abuse var(req.rate_limit),sub(req.request_rate) lt 0
http-request deny deny_status 429 if rate_abuse
acl consumerapi_host req.hdr(Host) -i -m dom 127.0.0.1
acl operationapi_host req.hdr(Host) -i -m dom 127.0.0.2
acl consumerapi_json req.hdr(Content-Type) -i -m dom application/json
acl consumerapi_xml req.hdr(Content-Type) -i -m dom application/xml
acl PATH_order path_beg -i /order
acl PATH_invoicing path_beg -i /invoicing
use_backend order_service_json if consumerapi_host consumerapi_json PATH_order
use_backend order_service_xml if consumerapi_host consumerapi_xml PATH_order
use_backend invoicing_service if operationapi_host PATH_invoicing
backend order_service_json
server server1 127.0.0.1:8080
backend order_service_xml
server server2 127.0.0.1:8090
backend invoicing_service
server server1 127.0.0.1:8081
스틱 테이블 http_rate_limiting 을 만들었습니다 . 10초마다 데이터를 지웁니다.
이 구성으로 주문 요청이 10초 이내에 100을 초과하면 클라이언트는 코드 429와 함께 오류를 수신합니다.
5. 결론
이 기사에서는 HAProxy를 API 게이트웨이로 사용했습니다. HTTP Routing과 Rate Limiting의 사례를 살펴보았습니다. HAProxy는 이러한 사용 사례에서 매우 쉽게 구성할 수 있습니다.