마이크로서비스와 같은 분산형 아키텍처에서는 보안, 로깅, 그리고 여러 서비스 호출 간의 사용자 추적과 같은 중요한 작업을 수행해야 할 필요가 생긴다. 모든 개발 팀이 이러한 기능을 독자적으로 구현하는 대신, 각 서비스에서 일관되게 적용할 수 있는 방법을 찾는 것이 중요하다. 공통 라이브러리나 프레임워크를 사용해 이러한 기능을 각 서비스에 통합할 수도 있지만, 이 접근 방식은 유지보수와 확장성 측면에서 문제를 일으킬 가능성이 크다.
- 이러한 기능을 각 서비스에 일관되게 구현하기 어렵다: 개발자는 제품 기능 구현에 집중하느라 바쁜 일상을 보내는 경우가 많아, 서비스 로깅이나 추적 기능처럼 필수적이지만 부가적인 작업을 간과하기 쉽다. 특히, 이러한 기능이 반드시 요구되는 규제 산업이 아니라면 더욱 잊혀지기 쉽다.
- 보안과 로깅 같은 횡단 관심사 (cross-cutting concerns)의 구현 책임을 개별 개발 팀에 전가하면 잘못 구현하거나 아예 누락할 수 있다: 횡단 관심사는 애플리케이션 전반에 걸쳐 공통적으로 적용되며, 애플리케이션의 여러 부분에 영향을 미치는 설계 요소나 기능을 의미한다.
- 모든 서비스에 걸쳐 강한 의존성을 만들 수 있다: 모든 서비스가 공유하는 공통 프레임워크에 기능을 계속 추가하면, 공통 코드의 동작을 변경하거나 기능을 추가할 때 서비스 재컴파일과 재배포가 필수적으로 요구된다. 특히, 공유 라이브러리에 내장된 핵심 기능을 갑작스레 업그레이드하는 경우 이는 장기적인 이전 작업으로 이어질 가능성이 크다.
이 문제를 해결하려면 횡단 관심사를 독립적으로 처리할 수 있는 서비스를 도입하고, 아키텍처 내 모든 마이크로서비스 호출에 대해 필터와 라우터 역할을 수행하도록 해야 한다. 이러한 서비스는 게이트웨이(Gateway)라 불린다. 서비스 클라이언트는 더 이상 마이크로서비스를 직접 호출하지 않고, 모든 호출이 단일 정책 시행 지점(Policy Enforcement Point, PEP) 역할을 하는 서비스 게이트웨이를 통해 전달된 후 최종 목적지로 라우팅된다.
- 하나의 URI 뒤에 모든 서비스를 배치하고 서비스 디스커버리를 사용하여 해당 호출을 실제 서비스 인스턴스에 매핑하는 방법
- 서비스 게이트웨이를 경유하는 모든 서비스 호출에 상관관계 ID를 삽입하는 방법
- HTTP 응답에 전달받은 상관관계 ID를 삽입하여 클라이언트로 재전송하는 방법
8.1 서비스 게이트웨이란?
서비스 게이트웨이는 서비스 클라이언트와 호출 대상 서비스 사이에서 중개 역할을 하며, 클라이언트는 게이트웨이가 관리하는 단일 URL로 통신한다. 게이트웨이는 클라이언트 호출에서 전달된 경로를 분석하여 클라이언트가 호출하려는 특정 서비스를 결정한다.
서비스 게이트웨이는 애플리케이션 내 마이크로서비스를 호출하기 위해 들어오는 모든 트래픽의 게이트키퍼 (gatekeeper) 역할을 한다. 이를 통해 서비스 클라이언트는 개별 서비스의 URL을 직접 호출하지 않고, 서비스 게이트웨이를 통해 요청을 보낼 수 있다.
- 정적 라우팅 (static routing): 서비스 게이트웨이는 단일 서비스 URI와 API 경로를 통해 모든 서비스를 호출한다. 이를 통해 개발자는 모든 서비스에 대해 하나의 서비스 엔드포인트만 알면 되므로 개발 과정이 더 간편해진다.
- 동적 라우팅 (dynamic routing): 서비스 게이트웨이는 유입된 서비스 요청을 검사한 뒤 요청 데이터를 기반으로 서비스 호출자에게 적합한 지능적 라우팅을 수행할 수 있다. 예를 들어, 베타 프로그램 참여 고객의 서비스 요청은 일반 사용자와는 다른 버전의 코드를 실행하는 특정 서비스 클러스터로 라우팅될 수 있다.
- 인증 (authentication)과 인가 (authorization): 모든 서비스 호출이 서비스 게이트웨이로 라우팅되기 때문에, 서비스 게이트웨이는 서비스 호출자가 자신의 인증 여부를 확인할 수 있는 적합한 장소가 된다.
- 자료수집 (metic collection)과 로깅: 서비스 호출이 게이트웨이를 통과하기 때문에, 서비스 게이트웨이는 지표와 로그를 수집하는 데 사용될 수 있다. 또한, 사용자 요청에 대한 중요한 정보가 있는지 확인하여 균일한 로깅을 보강할 수 있다. 그렇다고 개별 서비스에서 자료를 수집해서는 안 된다는 것은 아니다. 서비스 게이트웨이를 사용하면 서비스 호출 횟수 및 응답 시간처럼 많은 기본 지표를 한 곳에서 더 잘 수집할 수 있다.
8.2 스프링 클라우드 게이트웨이 소개
스프링 클라우드 게이트웨이는 스프링 프레임워크 5, 프로젝트 리액터, 스프링 부트 2.0을 기반으로 한 API 게이트웨이 구현체다. 논블로킹 애플리케이션은 주요 스레드를 차단하지 않는 방식으로 작성된다. 이러한 애플리케이션은 요청을 처리할 때 주요 스레드를 사용하지 않고 백그라운드에서 비동기식으로 작업을 처리한다. 처리가 완료되면 비로소 응답을 반환하여, 애플리케이션의 효율성을 높이고 더 많은 요청을 동시에 처리할 수 있다.
- 애플리케이션의 모든 서비스 경로를 단일 URL에 매핑한다: 스프링 클라우드 게이트웨이는 하나의 URL에 제한되지 않고, 실제 여러 경로에 대해 진입점을 정의하고 경로 매핑을 세분화할 수 있다. 각 서비스 엔드포인트는 고유한 경로로 매핑될 수 있다. 그러나 가장 일반적인 사용 사례는 모든 서비스 클라이언트 호출이 통과하는 단일 진입점을 제공하는 것이다. 이를 통해 관리와 라우팅이 더 간편해지고, 모든 트래픽이 중앙에서 처리될 수 있다.
- 게이트웨이로 유입되는 요청과 응답을 검사하고 조치를 취할 수 있는 필터를 작성한다: 이 필터를 사용하면 코드에 정책 시행 시점을 삽입하여 모든 서비스 호출에 다양한 작업을 수행할 수 있다. 즉, 이 필터로 유입되고 유출되는 HTTP 요청 및 응답을 수정할 수 있다. 이를 통해 인증, 로깅, 트래픽 제한, 헤더 수정 등의 작업을 서비스 호출 전에 또는 후에 중앙에서 처리할 수 있다.
- 요청을 실행하거나 처리하기 전에 해당 요청이 주어진 조건을 충족하는지 확인할 수 있는 서술자 (predicates)를 만든다: 스프링 클라우드 게이트웨이에는 자체 Route Predicate Factories 세트가 포함되어 있어, 이를 통해 경로(route)를 정의할 때 다양한 조건을 설정할 수 있다. 이러한 프레디케이트(조건)는 요청이 특정 경로로 라우팅되기 전에 평가되며, 조건을 만족할 경우 요청이 해당 경로로 전달된다. 예를 들어, 요청의 HTTP 메서드, 헤더, 파라미터 등을 기준으로 경로를 동적으로 결정할 수 있다.
8.2.1 스프링 부트 게이트웨이 프로젝트 설정
※ 예제 및 예제 설명 생략
8.2.2 유레카와 통신하는 스프링 클라우드 게이트웨이 구성
※ 예제 및 예제 설명 생략
8.3 스프링 클라우드 게이트웨이에서 라우팅 구성
스프링 클라우드 게이트웨이는 기본적으로 리버스 프록시 역할을 한다. 리버스 프록시 (reverse proxy)는 자원에 접근하려는 클라이언트와 자원 사이에 위치한 중개 서버다. 클라이언트는 실제로 어떤 서버와 통신하는지 알지 못하며, 리버스 프록시는 클라이언트의 요청을 받아 대신 원격 자원을 호출하고 그 결과를 반환한다.
마이크로서비스 아키텍처에서 스프링 클라우드 게이트웨이(리버스 프록시)는 클라이언트의 마이크로서비스 호출을 받아 상위 서비스에 전달한다. 서비스 클라이언트는 오직 게이트웨이와 통신한다고 생각한다.
상위 서비스와 통신하려면 게이트웨이는 유입된 호출이 상위 경로에 매핑하는 방법을 알아야 한다. 스프링 클라우드 게이트웨이는 이를 수행하는 몇 가지 메커니즘을 제공한다.
- 서비스 디스커버리를 이용한 자동 경로 매핑
- 서비스 디스커버리를 이용한 수동 경로 매
8.3.1 서비스 디스커버리를 이용한 자동 경로 매핑
스프링 클라우드 게이트웨이에서는 경로 매핑을 gateway-server.yml 파일에서 정의할 수 있다. 이 파일을 사용하여 각 서비스의 경로를 설정할 수 있으며, 서비스 ID를 기반으로 요청을 자동으로 라우팅하는 구성을 추가할 수 있다. 이를 통해 각 서비스에 대한 URL 경로를 정의하는 것 외에도, 스프링 클라우드 환경에서 서비스 레지스트리를 사용하여 동적으로 서비스 요청을 처리할 수 있다. 이 방법은 서비스가 추가되거나 변경될 때마다 게이트웨이의 구성을 자동으로 업데이트하여 유연하게 라우팅을 관리할 수 있도록 한다.
스프링 클라우드 게이트웨이는 호출되는 서비스의 유레카 서비스 ID를 자동으로 사용하여 하위 서비스 인스턴스에 매핑한다.
유레카와 함께 스프링 클라우드 게이트웨이를 사용하는 장점은 호출할 수 있는 엔트리포인트가 하나라는 사실 외에도, 게이트웨이를 수정하지 않고도 서비스 인스턴스를 추가하거나 제거할 수 있다는 점이다. 유레카와의 통합 덕분에 서비스 인스턴스가 동적으로 변경되더라도, 게이트웨이가 이를 자동으로 반영할 수 있다.
예를 들어, 유레카에 새로운 서비스를 추가하면 게이트웨이는 서비스의 물리적 엔드포인트 위치에 대해 유레카와 통신하여 자동으로 호출을 라우팅할 수 있다. 이렇게 함으로써, 서비스 인스턴스가 변경되거나 새로 추가되어도 게이트웨이는 별도의 수정 없이 자동으로 새로운 서비스로의 요청을 처리할 수 있게 된다.
※ 예제 및 예제 설명 생략
8.3.2 서비스 디스커버리를 이용한 수동 경로 매핑
스프링 클라우드 게이트웨이는 유레카 서비스 ID로 생성된 자동화된 경로에만 의존하지 않고 명시적으로 경로 매핑을 정의할 수 있어 코드를 더욱 세분화할 수 있다.
※ 예제 및 예제 설명 생략
8.3.3 동적으로 라우팅 구성을 재로딩
동적인 라우팅 재로딩 기능은 게이트웨이 서버를 재시작하지 않고도 경로 매핑을 변경할 수 있어 유용하다. 이를 통해 기존 경로를 빠르게 수정할 수 있으며, 해당 환경 내의 각 게이트웨이 서버에 새로운 경로를 적용하는 작업을 수행할 수 있다.
actuator/gateway/routes 엔드포인트를 통해 현재 게이트웨이에 설정된 조직 서비스를 확인할 수 있다. 새로운 매핑을 추가하려면 구성 파일을 수정한 후, 스프링 클라우드 컨피그 서버가 참조하는 구성 데이터가 저장된 깃 저장소에 변경 사항을 반영하고 이를 깃 허브에 커밋하면 된다.
스프링 액추에이터는 라우팅 구성 정보를 다시 로드할 수 있도록 actuator/gateway/refresh라는 POST 기반 엔드포인트를 제공한다. 이 엔드포인트를 호출한 후 actuator/gateway/routes를 호출하면 추가된 두 개의 새로운 경로를 확인할 수 있다. actuator/gateway/refresh의 응답은 HTTP 200 상태 코드만 반환하며, 별도의 응답 내용은 없다.
8.4 스프링 클라우드 게이트웨이의 진정한 능력: Predicate와 Filter Factories
게이트웨이는 모든 요청을 프록시할 수 있어 서비스 호출을 단순화할 수 있다. 하지만 스프링 클라우드 게이트웨이의 진정한 강점은 게이트웨이를 통과하는 모든 서비스 호출에 사용자 정의 로직을 적용할 때 발휘된다. 대부분의 경우 이러한 사용자 정의 로직은 보안, 로깅, 추적 등 모든 서비스에 일관된 애플리케이션 정책을 적용하는 데 사용된다.
애플리케이션 정책을 구현할 때 각 서비스를 개별적으로 수정하지 않고 모든 서비스에 적용하려면 이러한 정책들은 횡단 관심사로 간주된다. 이를 위해 스프링 클라우드 게이트웨이의 Predicate와 Filter Factories를 활용할 수 있다. 이들은 스프링의 관점 클래스와 유사하게 동작하여 다양한 동작을 일치시키거나 가로채는 방식으로 호출 동작을 변경하거나 확장할 수 있다.
서블릿 필터나 스프링 관점 클래스가 특정 서비스에 맞게 동작하도록 설계되었다면, 게이트웨이와 그 Predicate 및 Filter Factories는 게이트웨이를 통해 라우팅되는 모든 서비스에 공통 관심사를 일관되게 적용할 수 있다. 또한, 서술자 (predicate)를 사용하면 요청을 처리하기 전에 요청이 특정 조건을 충족하는지 확인하는 작업을 수행할 수 있다.
게이트웨이 클라이언트(브라우저나 앱 등)가 스프링 클라우드 게이트웨이에 요청을 보내면, 요청은 먼저 게이트웨이 핸들러로 전달된다. 게이트웨이 핸들러는 요청된 경로가 사전에 구성된 경로와 일치하는지 확인한다. 경로가 일치하면 핸들러는 요청을 처리할 필터 체인을 읽고 실행한다. 요청이 모든 필터를 통과하면, 최종적으로 설정된 경로의 마이크로서비스로 요청이 전달된다.
8.4.1 게이트웨이 Predicate Factories
게이트웨이의 서술자는 요청을 실행하거나 처리하기 전에 요청이 지정된 조건을 충족하는지 확인하는 객체이다. 이러한 서술자는 주로 Predicate Factories를 사용하여 요청이 특정 조건을 만족하는지 확인한다. 각 경로에는 여러 개의 Predicate Factories를 설정할 수 있으며, 이들은 논리적 AND로 결합되어 요청이 모든 조건을 만족해야만 해당 경로로 라우팅된다. 이를 통해 매우 유연하고 동적인 라우팅을 구성할 수 있다.
8.4.2 게이트웨이 Filter Factories
게이트웨이의 Filter Factories를 사용하면 코드에 정책 시행 지점(PEP)을 삽입하여 모든 서비스 호출에 대해 일관된 방식으로 작업을 수행할 수 있다. 이를 통해 요청과 응답에 대한 공통 처리를 쉽게 할 수 있다. 필터는 주로 수신되는 HTTP 요청과 발신되는 HTTP 응답을 수정하거나 추가적인 작업을 수행하는 데 사용된다. 예를 들어, 요청에 대한 인증, 로깅, 오류 처리, 응답 포맷 변환 등의 작업을 필터를 통해 처리할 수 있다.
8.4.3 사용자 정의 필터
게이트웨이를 경유하는 모든 요청을 프록시하는 기능을 사용하면 서비스 호출을 단순화할 수 있다. 하지만 스프링 클라우드 게이트웨이의 진정한 강점은 게이트웨이를 통과하는 모든 서비스 호출에 적용될 수 있는 사용자 정의 로직을 작성할 때 발휘된다. 이러한 사용자 정의 로직은 보통 모든 서비스 간에 보안, 로깅, 추적 등 일관된 애플리케이션 정책을 적용하는 데 사용된다. 이를 통해 개발자는 여러 서비스에서 일관된 방식으로 공통 기능을 구현하고 관리할 수 있게 된다.
스프링 클라우드 게이트웨이 내에서 필터를 사용하여 사용자 정의 로직을 만들 수 있다. 필터를 사용하면 각 서비스 요청이 통과하는 비즈니스 로직 체인을 구현할 수 있다. 스프링 클라우드 게이트웨이는 아래의 두 가지 종류의 필터를 지원한다.
- 사전 필터 (pre-filter): 실제 요청이 목적지로 전송되기 전에 사전 필터가 호출된다. 사전 필터는 일반적으로 서비스가 일관된 메시지 형식인지 확인하는 작업 (예: 주요 HTTP 헤더 존재 여부 확인)을 수행하거나, 서비스를 호출하는 사용자가 인증되었는지 확인하는 게이트키퍼 역할을 한다. 이러한 필터는 요청이 목적지 서비스로 전달되기 전에 필요한 처리를 수행하여, 서비스에 대한 일관성과 보안을 유지하는 데 중요한 역할을 한다.
- 사후 필터 (post-filter): 사후 필터는 대상 서비스 이후에 호출되며, 응답이 클라이언트로 다시 전송되기 전에 처리된다. 일반적으로 사후 필터는 대상 서비스의 응답을 다시 기록하거나 오류를 처리하는 등의 작업을 수행하거나, 민감한 정보에 대한 응답을 검사하여 보안적인 측면을 강화한다. 이 필터는 클라이언트에게 반환될 데이터가 적절한지 확인하고, 응답을 필요에 맞게 수정할 수 있는 기회를 제공한다.
항상 서비스 클라이언트 (게이트웨이로 노출된 서비스롤 호출하는)에서 시작된다는 것을 알 수 있다.
- 게이트웨이에서 정의된 모든 사전 필터는 요청이 게이트웨이에 유입될 때 호출된다. 사전 필터는 HTTP 요청이 실제 서비스에 도달하기 전에 검사하고 수정한다. 하지만 사용자를 다른 엔드포인트나 서비스로 리다이렉션 할 수는 없다.
- 게이트웨이에 들어오는 요청에 대해 사진 필터가 실행된 후 게이트웨이는 목적지 (서비스가 향하는 곳)를 결정한다.
- 대상 서비스가 호출된 후 게이트웨이의 사후 필터가 호출된다. 사후 필터는 호출된 서비스의 응답을 검사하고 수정한다.
- 추적 필터 (tracking filter): 추적 필터는 게이트웨이로 유입되는 모든 요청에 상관관계 ID가 포함되어 있는지 확인하는 사전 필터다. 상관관계 ID는 고객 요청을 처리하는 과정에서 여러 마이크로서비스 간에 전달되는 고유 식별자다. 이를 통해 요청이 마이크로서비스를 거치며 발생하는 이벤트의 흐름을 추적할 수 있다.
- 대상 서비스 (target service): 대상 서비스는 조직 또는 라이선스 서비스일 수 잇다. 두 서비스 모두 HTTP 요청 헤더에서 상관관계 ID를 받는다.
- 응답 필터 (response filter): 응답 필터는 서비스 호출 후, 상관관계 ID를 클라이언트로 전송되는 HTTP 응답 헤더에 삽입하는 사후 필터다. 이를 통해 클라이언트는 요청과 관련된 상관관계 ID에 접근할 수 있게 되며, 이를 활용하여 호출된 마이크로서비스의 연속적인 트랜잭션을 추적할 수 있다.
8.5 사전 필터 만들기
스프링 클라우드 게이트웨이에서 필터를 만드는 과정은 간단하다. 예를 들어, tmx-correlation-id라는 HTTP 헤더의 포함 여부를 검사하는 TrackingFilter라는 사전 필터를 만들 수 있다. 이 헤더는 여러 마이크로서비스를 거쳐서 사용자 요청을 추적하는 데 사용되는 고유한 GUID (Globally Unique Identifier)를 포함한다. 이 필터는 요청이 게이트웨이에 도달하기 전에 상관관계 ID를 확인하고, 요청을 추적할 수 있도록 하는 역할을 한다.
- tmx-correlation-id가 HTTP 헤더에 없으면 게이트웨이 TrackingFilter 상관관계 ID를 생성하고 설정한다,
- 상관관계 ID가 이미 있다면 게이트웨이는 아무 일도 하지 않는다. (상관관계 ID가 있다는 것은 이 특정 서비스 호출이 사용자 요청을 수행하는 서비스 호출 체인의 한 부분임을 의미한다)
※ 예제 및 예제 설명 생략
스프링 클라우드 게이트웨이에서 글로벌 필터를 생성하려면 GlobalFilter 클래스를 구현한 후 filter() 메서드를 재정의해야 한다. 이 메서드는 필터에서 구현할 비즈니스 로직을 포함한다. HTTP 헤더의 추출 방법은 아래와 같다.
HttpHeaders requestHeaders = exchange.getRequest().getHeader();
tmx-correlation-id를 설정하라면 FilterUtils의 setcorrelationId() 메서드를 사용해야 한다.
FilterUtils의 setCorrelationId() 메서드를 사용하면 HTTP 요청 헤더에 값을 추가할 수 있다. 이를 위해 ServerWebExchange.Builder의 mutate() 메서드를 사용할 수 있다. mutate() 메서드는 교환 객체를 ServerWebExchangeDecorator로 래핑하며, 변경된 값을 반환하거나 해당 인스턴스에 다시 위임하여 교환 객체의 프로퍼티를 변경하는 빌더를 반환한다.
이 호출을 테스트하려면 조직 또는 라이선스 서비스를 호출할 수 있다. 호출이 전달되면, 필터를 통과할 때 전달된 상관관계 ID가 기록된 로그 메시지가 콘솔에 출력된다.
8.6 서비스에서 상관관계 ID 사용
이제 게이트웨이를 통과하는 모든 마이크로서비스 호출에 상관관계 ID가 추가되었으므로 아래 사항을 확인한다.
- 상관관계 ID는 호출된 마이크로서비스가 쉽게 액세스할 수 있다.
- 마이크로서비스로 수행될 모든 하위 서비스 호출에도 상관관계 ID가 전파된다.
이를 구현하기 위해 각 마이크로서비스에서 UserContextFilter, UserContext, UserContextInterceptor 세 가지 클래스를 빌드한다. 이 클래스들은 유입되는 HTTP 요청에서 상관관계 ID를 읽기 위해 협업하고, 애플리케이션의 비즈니스 로직에서 쉽게 액세스할 수 있도록 클래스를 매핑하여 모든 하위 서비스 호출에 이 ID를 전파할 것이다.
- 게이트웨이로 라이선싱 서비스를 호출할 때 TrackingFilter는 게이트웨이로 유입되는 모든 호출에 대해 상관관계 ID를 삽입한다.
- 사용자가 정의할 수 있는 HTTP ServletFilter인 UserContextFilter 클래스는 상관관계 ID를 UserContext에 매핑한다. UserContext 클래스는 해당 호출의 나중 부분에서 사용될 것을 대비하여 그 값을 스레드에 저장한다.
- 라이언싱 서비스의 비즈니스 로직은 조직 서비스에 대한 호출을 실행한다.
- RestTemplate은 조직 서비스를 호출한다. RestTemplate은 사용자 정의 스프링 인터셉터 클래스인 UserContextInterCeptor를 사용하여 상관관계 ID를 아웃바운드 호출의 HTTP 헤더에 삽입한다.
8.6.1 유입되는 HTTP 요청을 가로채는 UserContextFilter
UserContextFilter 클래스는 서비스로 들어오는 모든 HTTP 요청을 가로채고, HTTP 요청에서 사용자 컨텍스트 클래스로 상관관계 ID(및 몇 가지 다른 정보)를 매핑하는 HTTP 서블릿 필터다.
※ 예제 및 예제 설명 생략
궁극적으로 UserContextFilter는 관심있는 HTTP 헤더 값을 자바 UserContext 클래스에 매핑한다.
8.6.2 서비스에 쉽게 액세스할 수 있는 HTTP 헤더를 만드는 UserContext
UserContext 클래스는 마이크서비스가 처리하는 각 서비스 클라이언트 요청의 HTTP 헤더 값을 보관한다. 이 클래스는 java.lang.ThreadLocal에서 값을 조회하고 저장하는 getter/setter 메서드로 구성된다.
※ 예제 및 예제 설명 생략
보통 UserContext 클래스는 유입되는 HTTP 요청에서 가져온 값을 보유하는 POJO에 불과하다.
※ 예제 및 예제 설명 생략
8.6.3 상관관계 ID 전파를 위한 사용자 정의 RestTemplate과 UserContextInterceptor
UserContextInterceptor 클래스는 RestTemplate 인스턴스에서 실행되는 모든 HTTP 기반 서비스 발신 요청에 상관관계 ID를 주입한다. 이 작업은 서비스 호출 간 링크를 설정하는 데 사용되며, 이를 위해 RestTemplate 클래스에 주입될 스프링 인터셉터를 이용한다.
※ 예제 및 예제 설명 생략
UserContextInterceptor를 사용하려면 RestTemplate 빈을 정의한 후 UserContextInterceptor를 그 빈에 추가해야 한다.
※ 예제 및 예제 설명 생략
8.7 상관관계 ID를 수신하는 사후 필터 작성
스프링 게이트웨이는 클라이언트를 대신해 실제 HTTP 호출을 실행하고, 대상 서비스에서 반환된 응답을 다시 검사한다. 이 과정에서 응답을 변경하거나 추가 정보를 덧붙이는 것도 가능하다. 사전 필터가 데이터를 캡처하는 역할과 연관된다면, 사후 필터는 지표를 수집하거나 사용자의 트랜잭션과 관련된 로깅을 완료하기에 적합한 위치다. 특히 마이크로서비스로 전달된 상관관계 ID를 사용자에게 다시 전달하고 활용하려는 경우, 메시지 본문을 수정하지 않고도 상관관계 ID를 호출자에게 전달할 수 있다.
※ 예제 및 예제 설명 생략
'스프링 마이크로서비스' 카테고리의 다른 글
7장. 나쁜 상황에 대비한 스프링 클라우드와 Resilience4j를 사용한 회복성 패턴 (0) | 2024.12.16 |
---|---|
6장. 서비스 디스커버리 (2) | 2024.12.12 |
5장. 스프링 클라우드 컨피그 서버로 구성 관리 (0) | 2024.12.12 |
4장. 도커 (0) | 2024.12.11 |
3장. 스프링 부트로 마이크로서비스 구축하기 (1) | 2024.12.10 |