Microservice 아키텍쳐 구현을 위한 API 게이트웨이에 대해 정리합니다.
학습할 내용은 다음과 같습니다.
- API Gateway란
- 인증/인가에 관련된 기능
- 라우팅
- 공통 로직 처리
- Mediation(메디에이션)
- 로깅 및 미터링
- QoS 조정 (Quality of service)
Reference: MSA 아키텍쳐 구현을 위한 API 게이트웨이의 이해 (API GATEWAY)
API Gateway는 모든 서버로의 요청을 단일지점을 거쳐서 처리하도록 한다. 이를 통해 공통된 로직 처리나 인증 및 인가 처리, 라우팅 처리등을 할 수 있다.
인증은 요청을 보내는 사용자의 신원을 확인하는 거고 인가는 사용자가 이 요청에 대한 요구를 할 권한이 있는지 확인하는 과정이다.
인증/인가를 사용자로부터 매번 사용자의 Id와 Passwd를 입력 받기에는 번거롭다. 그렇다고 매 요청마다 Id와 Passwd를 요청에다가 담으면 보안상의 문제가 된다. 그래서 Gateway에서는 사용자가 요청할 수 있는 토큰을 인증서버로부터 발급해준다.
이때 인증서버는 내부에 있는 Database가 될 수도 있고 외부로 소셜 로그인을 이용한 인증서버가 있을 수 있다. 외부 인증서버를 이용하는거라면 사용자가 인증을 통과한 후 Token을 발급해주는 절차로 진행된다.
이렇게 발급된 토큰에 사용자 정보를 저장할 수 있는데 이를 클레임 기반 토큰이라고 한다. 클레임 기반의 토큰이 아닌 경우 서버에다가 사용자 정보를 저장하고 클라이언트는 이를 식별할 수 있는 간단한 string 정보만 넘겨주게 된다. 이를 서버 기반 토큰이라고 한다.
서버기반의 토큰과 클레임 기반의 토큰을 비교해보자면 서버 기반의 토큰은 서버에 정보를 저장하므로 더 안전하다는 특징이 있다. 하지만 토큰을 저장할 별도의 스토로지가 필요하기 때문에 이를 고려해야한다. 이 스토로지는 주로 데이터베이스가 아닌 Redis와 같은 memcache에 저장하는데 이를 통해 속도를 올릴 수 있다. 클레임 기반 토큰은 클라이언트쪽에 저장하므로 토큰의 길이가 크면 지연시간이 길어진다는 단점이 있고 토큰을 직접적으로 관리할 수 없으므로 주기적으로 발급받도록 하는 정책을 쓴다.
API Gateway는 토큰을 발급했으면 이 토큰을 바탕으로 유효성을 검증한 후 검증되면 서버로 전달해준다.
서버기반의 토큰의 경우 토큰의 유니크한 값을 가지고 토큰 저장소에서 토큰을 찾아서 있는지 보고 있다면 사용자 정보(권한 포함)을 함께 API 서버로 보낸다.
클레임 기반 토큰의 경우는 API Gateway에서 apitoken을 까보고 검증한 후 통과하면 사용자 정보를 함께 API 서버로 보낸다.
이렇게 토큰기반으로 인증을 허용하지만 서버와 서버간의 통시의 경우에는 이러한 인증을 거치지 않게 하기도 한다.
토큰을 이용해 사용자의 권한을 제어하는 방법은 크게 두가지가 있다. 하나는 개별 토큰에 권한을 부여하는 방식과 역할(ROLE) 기반으로 권한을 부여하는 방식이 있다.
개별 토큰에 권한을 부여하는 방법의 경우 개개인 별로 토큰에다가 세밀하게 권한을 부여할 수 있지만 이러한 토큰이 많아지면 관리하기 어렵다는 특징이 있다.
역할 기반으로 토큰에 권한을 부여한다면 토큰에 권한을 부여하는 숫자가 줄어들기 때문에 역할별로 엔드포인트를 나눠서 관리할 수도 있다. 예를들면 관리자 엔드포인트는 /service/admin
사용자 엔드포인트는 /service/user
이렇게 나눌 수 있다.
API Gateway의 주요 기능 중 하나는 같은 API 요청이라도 서비스나 클라이언트 종류에 따라서 다른 엔드포인트로 라우팅을 해주거나 로드밸런싱 기능을 지원해주기도 한다.
API Gateway 뒷단에 여러 동일한 서버가 대기하고 있다면 API Gateway에서 로드밸런싱 기능을 지원해줄 수 있다.
단순하게 로드밸런싱을 라운드 로빈으로도 제공해줄 수 있고 원하는 트래픽에 따라 분산시킬 수도 있다.
무엇보다 API 서버가 장애가 났을 경우에 이를 알아채고 그쪽으로 트래픽을 전달하지 않을 수도 있다.
또 다른 유용한 기능으로는 같은 API 요청이라도 여러개의 엔드포인트를 이용해 각 서비스마다 클라이언트마다 라우팅 해줄 수 있다는 점이다. 예를들면 IOT 센서가 있고 이런 데이터를 수집하는 같은 API가 있다라고 생각해보자.
이런식으로 다양한 엔드포인트로 요청을 하지만 API Gateway에서는 같은 경로로 전달해줄 수 있다.
라우팅에서 유용한 기능중의 하나는 메시지 내용을 기반으로 하는 라우팅이다. 메시지 헤더를 파싱해서 메시지 헤더에 있는 내용을 기반으로 라우팅할 수 있고 메시지 바디 내용에 기반해서 라우팅 할 수도 있다. 다만 이런 오버헤드에 대한 고려를 하면 된다. 메시지 기반으로 라우팅할 땐 웬만하면 헤더에 라우팅 정보를 넣어서 전달하면 좋다. 메시지 바디까지 파싱하는 건 좀 부담스럽기 떄문에.
API Gateway는 특성상 모든 API 서버 앞쪽에 위치하기 때문에 모든 API 호출이 Gateway를 거치기 때문에 공통된 로직 처리가 필요하다면 Gateway 에다가 넣으면 좋다. 이를 통해 각각의 서비스는 자신의 비즈니스 로직에 집중하면 되므로.
API 로깅이나 인증같은 기능은 공통 로직으로 포함된다.
메디에이션이란 "중재" 또는 "조정" 이라는 의미를 가지는데 API 서버가 클라이언트가 원하는 API 형태와 다를 때 API 게이트웨이가 이를 변경해주는 기능을 이야기 한다.
메시지 포맷 변환 기능이란 클라이언트에서 들어온 요청을 API 서버로 보낼 때 데이터를 변환해서 보내주거나 API 서버에서 응답하는 데이터를 클라이언트가 원하는 데이터로 변경해주는 기능을 말한다.
예를 들면 사용자의 연봉을 원하는 API 요청이 들어왔다고 하자. 연봉 정보만 주는 API 서버는 없지만 사용자의 정보를 리턴해주는 API가 있다고 했을 때 이 데이터를 서버에서 응답으로 가지고와서 API Gateway에서 클라이언트가 필요로하는 데이터만 추려서 전달해줄 수 있다.
다양한 서비스나 클라이언트를 지원하게 되면 다양한 통신 프로토콜을 지원해야 하는 경우가 있다. 예를들면 웹에서는 JSON이나 HTTP를 이용한 REST 기반의 통신을 많이 쓰지만 배나 비행기에서는 REST도 무겁기 때문에 바이너리 기반의 경량 프로토콜을 사용하게 된다. 이렇게 다양한 타입의 프로토콜을 지원하기 위해서 프로토콜마다 새로운 서비스를 구현하는게 아니라 API Gateway에서 프로토콜 변환을 이용해 서비스를 호출할 수 있도록 하면 된다.
실제로 유용한 기능인데 내부로는 REST 통신이 아니라 페이스북의 Thrift나 구글의 Protocol Buffer로 구현을 해서 성능을 올리고 외부로는 REST를 이용해서 범용성을 올리는 사례가 있다.
메시지 호출 패턴 변환이란 동기 비동기 호출같은 통신을 변경시킬 수 있다. API 클라이언트는 동기 호출을 했지만 API Gateway에서는 메시지 큐 서비스를 이용해 비동기 통신을 이용해 요청을 처리해주고 응답을 줄 수 있다.
API Gateway에서는 여러개의 API를 묶어서 하나의 API 처럼 처리하게 보이는 동작을 만들 수 있다. 이렇게 만들면 API Gateway에 부하가 집중되므로 조심해야 한다. 그리고 로깅과 디버깅이 어렵다는 단점이 있다.
API Gateway의 비기능적인 요건으로 중요한 기능이 로깅과 미터링이다.
API Gateway의 주요 기능인 공통 로직 처리 기능에서 봤듯이 API Gateway는 공통적으로 처리하는 기능에 유용하고 이에는 로깅이 있다. 모든 API 시작 지점이 Gateway부터 시작하므로 이부터 시작해서 서비스간 호출 패턴을 파악해서 사용자 패턴을 파악할 수 있다. 이는 빅데이터와 연계해서 유용하다.
또한 문제가 발생했을 때 문제를 추적하기 위한 용도로 많이 사용되기도 한다.
API 미터링과 차징은 유료 API 서비스를 위한 기능으로 미터링은 API 호출 횟수, 클라이언트 IP, API 종류, In/Out 용량등을 측정할 수 있는 지표들을 기록하는 서비스다.
마지막으로 Qos 조정 기능이란 API 서비스를 클라이언트 대상에 따라서 서비스 레벨을 조정하는 기능이다.
유료 서비스가 있는 API 서비스라고 가정할때, 무료 사용자의 경우 1일 1000건으로 호출횟수를 제한 한다거나, 전송 용량이나, 네트워크 대역폭을 유료/무료 사용자에 따라 다르게 적용하는 것과 같은 기능을 QoS 기능이라고 한다.
유료 서비스인 경우만 아니라, 플랫폼 차원에서 다양한 클라이언트나 다양한 서비스로 API 를 제공하는 경우, 각 클라이언트나 서비스에 따라서 이 QoS를 조정하는 기능은 유용하게 사용될 수 있다. 특정 서비스나 클라이언트가 폭주하여 API를 과도하게 사용하여 다른 서비스들이 API를 사용할 수 없게 한다던가 그런 문제를 미연에 예방할 수 있다.