- Netflix에서 개발한 HTTP 클라이언트 라이브러리를 Spring Cloud에서 통합한 선언적 HTTP 클라이언트 라이브러리입니다. - Spring Cloud에서는 OpenFeign을 스프링 MVC 어노테이션을 사용하여 웹 서비스 클라이언트를 쉽게 작성할 수 있도록 통합했습니다. - OpenFeign은 마이크로서비스 아키텍처에서 특히 유용하며, 코드를 더 간결하고 유지보수하기 쉽게 만듭니다.
💡 OpenFeign 설정 중앙화 - REST API 통신을 수행할 때, 이와 관련된 설정에 대해서 중앙에서 관리가 가능합니다. - 주요 설정 정보는 타임아웃, 로깅, 인증 및 보안 설정, 재시도 정책, 디코더/인코더 설정, 서킷브레이커 설정에 대해 설정에 대해서 yaml/yml 파일 혹은 Configuration 클래스에서 중앙에서 설정하여 공통적으로 관리할 수 있습니다.
구분
세부 설정
타임아웃 설정 (Timeout)
- connectTimeout: 연결 시도 제한 시간 - readTimeout: 읽기 작업 제한 시간
로깅 설정 (Logging)
- 로그 레벨 (NONE, BASIC, HEADERS, FULL) - 로그 패턴 및 형식
인증 및 보안 설정
- 인증 토큰 - API 키 - 공통 헤더 정보
재시도 정책 (Retry Policy)
- 재시도 횟수 - 재시도 간격 - 재시도 조건
디코더/인코더 설정
- 요청/응답 변환 방식 - 에러 처리 로직 - 커스텀 디코더/인코더
서킷브레이커 설정
- 실패 임계값 - 타임아웃 설정 - 폴백 메커니즘
3) OpenFeign 설정 중앙화: 타임아웃 설정
💡 OpenFeign 설정 중앙화: 타임아웃 설정 - OpenFeign에서 외부 서비스와의 통신 시 발생할 수 있는 API 통신 지연을 제어하는 중요한 설정입니다. 이는 connectTimeout (연결 타임아웃), readTimeout (읽기 타임아웃)으로 나뉩니다. 이에 따르는 타임아웃 예외 처리도 필요합니다.
1. connectTimeout (연결 타임아웃) - 클라이언트가 서버와 연결을 맺는데 허용되는 최대 시간을 지정하며, 네트워크 문제나 서버 응답 지연 시 연결 시도를 제한할 수 있습니다.
2. readTimeout (읽기 타임아웃) - 서버로부터 데이터를 읽는데 허용되는 최대 시간을 의미하며, 서버의 응답이 늦어질 경우 요청을 중단합니다.
1. yaml 기반 설정 방법
💡 yaml 기반 설정 방법
- 아래와 같은 OpenFeign에서 전역으로 설정하는 설정 정보를 제공합니다. 1. config.default: 전역으로 설정하는 설정정보를 의미합니다. 2. config.keycloak-auth-client: feignClient 별로 지정을 할 수 있습니다. @FeignClient의 name 속성으로 지정한 값을 참조합니다.
구분
타임아웃 값
의미
connect-timeout
5000ms (5초)
- 클라이언트가 서버와 TCP 연결을 맺는데 허용되는 최대 시간 - 네트워크 연결 수립 과정의 제한 시간 - DNS 조회, TCP handshake 등의 과정 포함
read-timeout
5000ms (5초)
- 서버와 연결된 후 데이터를 주고받는데 허용되는 최대 시간 - 요청을 보낸 후 응답을 받을 때까지의 제한 시간 - 서버의 처리 시간이 긴 경우 고려 필요
spring:cloud:openfeign:client:config:default:connect-timeout:5000# 연결 타임아웃read-timeout:5000# 읽기 타임 아웃keycloak-auth-client:connect-timeout:6000# 연결 타임아웃read-timeout:6000# 읽기 타임아웃
2. Configuration 기반 설정 방법
💡 Configuration 기반 설정 방법
- Java Configuration을 사용하여 OpenFeign의 타임아웃 정책을 설정할 수 있습니다. - @Configuration 어노테이션이 달린 클래스에서 Request.Options를 Bean으로 등록하여 설정합니다. - 전역 설정과 특정 클라이언트별 설정을 모두 구성할 수 있습니다.
설정
설명
connectTimeout
클라이언트가 서버와의 연결을 시도할 때 허용되는 최대 시간을 설정하는 값입니다. 이 시간을 초과하면 연결 시도가 중단됩니다.
readTimeout
서버로부터 데이터를 읽어오는데 허용되는 최대 시간을 설정하는 값입니다. 이 시간을 초과하면 요청이 타임아웃 됩니다.
followRedirects
HTTP 리다이렉션(3xx 응답)을 자동으로 따를지 여부를 결정하는 boolean 값입니다. true로 설정하면 자동 리다이렉션을 수행합니다.
package com.blog.springbootkeycloak.config;
import feign.Request;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.TimeUnit;
/**
* OpenFeign 타임아웃 정책 설정 환경 파일
*
* @author : jonghoon
* @fileName : FeignClientTimeoutConfig
* @since : 25. 2. 16.
*/@Slf4j@ConfigurationpublicclassFeignClientTimeoutConfig{
/**
* 공통 FeignClient Timeout 정책 설정
*
* @return
*/@Beanpublic Request.Options feignRequestOptions(){
returnnew Request.Options(
5000, // connectTimeout (5초)
TimeUnit.MILLISECONDS,
5000, // readTimeout (5초)
TimeUnit.MILLISECONDS,
true// followRedirects
);
}
/**
* 특정 FeignClient Timeout 정책 설정
*
* @return
*/@Beanpublic Request.Options customRequestOptions(){
returnnew Request.Options(
3000, // connectTimeout (3초)
TimeUnit.MILLISECONDS,
3000, // readTimeout (3초)
TimeUnit.MILLISECONDS,
true// followRedirects
);
}
}
3. 사용 예시
💡 사용 예시
- 수행이 잘되는지 1초로 지정하여서 통신을 하였을 때, connect-timeout으로 Read timed out이 발생함을 확인하였습니다.
spring:
cloud:
openfeign:
client:
config:
default:
connect-timeout: 1 # 연결 타임아웃
read-timeout: 1 # 읽기 타임 아웃
keycloak-auth-client:
connect-timeout: 1 # 연결 타임아웃
read-timeout: 1 # 읽기 타임아웃
4) OpenFeign 설정 중앙화: 로깅 설정 (Logging)
💡 OpenFeign 설정 중앙화: 로깅 설정 (Logging)
- HTTP 요청과 응답에 대한 상세한 로깅을 제공하며, 다양한 로깅 레벨을 통해 필요한 정보를 선택적(Client 별)으로 확인할 수 있습니다.
1. default 설정: 모든 Feign 클라이언트에 적용되는 기본 로깅 설정을 정의합니다. 2. client 별 설정: 특정 클라이언트에만 적용되는 로깅 설정을 별도로 정의할 수 있습니다
로그 레벨
설명
NONE
로깅하지 않음 (기본값)
BASIC
요청 메서드와 URL, 응답 상태 코드, 실행 시간만 기록
HEADERS
BASIC 정보와 함께 요청과 응답의 헤더들을 기록
FULL
요청과 응답의 헤더, 본문, 메타데이터를 모두 기록
1. yaml 기반 설정 방법
💡 yaml 기반 설정 방법
1. default : logger-level을 full로 설정하여 모든 클라이언트의 요청/응답에 대한 상세 정보를 로깅합니다. 2. keycloak-auth-client: 별도로 logger-level을 none으로 설정하여 로깅을 비활성화했습니다.
spring:
cloud:
openfeign:
client:
config:
default:
logger-level: full # 전체 모두 기록
keycloak-auth-client:
logger-level: none # 기록하지 않음
2. Configuration 기반 설정 방법
💡 Configuration 기반 설정 방법 - Java Configuration을 통해 로깅 설정을 구성할 수 있습니다. - @Configuration 어노테이션이 달린 클래스에서 Logger.Level을 Bean으로 등록하여 설정합니다. - 로깅을 위한 패키지 레벨도 함께 설정해야 합니다.
package com.blog.springbootkeycloak.config.feign;
import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* OpenFeign 로깅 정책 설정 환경 파일
*
* @author : jonghoon
* @fileName : FeignClientLoggingConfig
* @since : 25. 2. 16.
*/@ConfigurationpublicclassFeignClientLoggingConfig{
/**
* 공통 FeignClient Logging 정책 설정
*
* @return
*/@Bean
Logger.Level customFeignLoggerLevel(){
return Logger.Level.FULL;
}
/**
* 특정 FeignClient Logging 정책 설정
*/@Beanpublic Logger.Level defaultFeignLoggerLevel(){
return Logger.Level.BASIC; // 특정 Feign 클라이언트에 적용될 기본 로깅 레벨
}
}
3. 사용예시
💡 사용예시
- OpenFeign를 활용하여 Keycloak 서버로 요청을 하였을 때, 아래와 같이 요청 정보, 응답 정보가 반환이 됩니다. - 응답 상태, 응답 헤더, 응답 값 들이 출력이 잘 됨을 확인하였습니다.이를 통해서 상세한 로그를 통해 API 요청/응답의 전체 과정을 모니터링하고 디버깅할 수 있습니다.
5) OpenFeign 설정 중앙화: 인증 및 보안 설정
💡 OpenFeign 설정 중앙화: 인증 및 보안 설정
- OpenFeign을 사용하여 외부 API와 통신할 때 보안을 강화하고 인증된 요청을 보내기 위해 사용됩니다. - OpenFeign를 통한 통신을 수행할 때, 모든 Feign Client에 공통으로 인증 헤더를 적용할 수 있습니다. - 예를 들어서 Authorization를 통해서 Bearer 토큰을 전달하거나 커스텀 키 인 x-api-key 형태를 포함하여 전달할 수 있습니다.
- OpenFeign 클라이언트의 인증 및 보안 설정을 yaml 파일에서 중앙 관리할 수 있습니다. - Bearer 토큰, API 키, 커스텀 헤더 등 다양한 인증 정보를 설정할 수 있습니다. - defaultRequestHeaders를 통해 모든 요청에 공통으로 적용될 헤더를 설정할 수 있습니다.또한 클라이언트 별로 각각 인증 정보를 지정할 수 있습니다.
spring:
cloud:
openfeign:
client:
config:
default:
logger-level: full # 전체 모두 기록
defaultRequestHeaders:
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJLbHVfNEVEamQzQnRseUdpaUtabTNFUTF0cXZReDNGOUN0WGxEUXJ0QUpBIn0.eyJleHAiOjE3Mzk1MDI4NjUsImlhdCI6MTczOTQ5OTI2NSwianRpIjoiMTU1MTIyMGMtN2IzMC00MDA4LThlMGUtYWU0ZWZkZjY2OTRlIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo5MDAxL3JlYWxtcy9kZXYtcmVhbG0iLCJhdWQiOlsicmVhbG0tbWFuYWdlbWVudCIsImJyb2tlciIsImFjY291bnQiXSwic3ViIjoiOTcyMDRhYTItMTE2MC00MjQzLTkwM2ItODFiYTJiZTE0ZGUwIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoic3ByaW5nLWJvb3QtYXBwIiwic2lkIjoiMDM1ZDM3YTktYzEyMC00YjA3LWI2ZWItMDVhYjkzYjFlNDhhIiwiYWNyIjoiMSIsImFsbG93ZWQtb3JpZ2lucyI6WyJodHRwOi8vbG9jYWxob3N0OjgwODAiXSwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbIm9mZmxpbmVfYWNjZXNzIiwidW1hX2F1dGhvcml6YXRpb24iLCJkZWZhdWx0LXJvbGVzLWRldi1yZWFsbSJdfSwicmVzb3VyY2VfYWNjZXNzIjp7InJlYWxtLW1hbmFnZW1lbnQiOnsicm9sZXMiOlsidmlldy1pZGVudGl0eS1wcm92aWRlcnMiLCJ2aWV3LXJlYWxtIiwibWFuYWdlLWlkZW50aXR5LXByb3ZpZGVycyIsImltcGVyc29uYXRpb24iLCJyZWFsbS1hZG1pbiIsImNyZWF0ZS1jbGllbnQiLCJtYW5hZ2UtdXNlcnMiLCJxdWVyeS1yZWFsbXMiLCJ2aWV3LWF1dGhvcml6YXRpb24iLCJxdWVyeS1jbGllbnRzIiwicXVlcnktdXNlcnMiLCJtYW5hZ2UtZXZlbnRzIiwibWFuYWdlLXJlYWxtIiwidmlldy1ldmVudHMiLCJ2aWV3LXVzZXJzIiwidmlldy1jbGllbnRzIiwibWFuYWdlLWF1dGhvcml6YXRpb24iLCJtYW5hZ2UtY2xpZW50cyIsInF1ZXJ5LWdyb3VwcyJdfSwic3ByaW5nLWJvb3QtYXBwIjp7InJvbGVzIjpbInNwcmluZy1ib290LWFwcC1zdWItcm9sZSJdfSwiYnJva2VyIjp7InJvbGVzIjpbInJlYWQtdG9rZW4iXX0sImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJ2aWV3LWFwcGxpY2F0aW9ucyIsInZpZXctY29uc2VudCIsInZpZXctZ3JvdXBzIiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJkZWxldGUtYWNjb3VudCIsIm1hbmFnZS1jb25zZW50Iiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJvcGVuaWQgcHJvZmlsZSBlbWFpbCIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJuYW1lIjoiVXBkYXRlZCBVc2VyIiwicHJlZmVycmVkX3VzZXJuYW1lIjoic3ViYWRtaW4iLCJnaXZlbl9uYW1lIjoiVXBkYXRlZCIsImZhbWlseV9uYW1lIjoiVXNlciIsImVtYWlsIjoidXBkYXRlZEBleGFtcGxlLmNvbSJ9.IqfTKGmHqoa6j063e7RwmOmQbU21_joYwB9TIUH8vWaGHBL19IUCLYW25pRYa5OwJbH_ryuZZ08Phb7dTHEA4cvxcSzDxRnxyoAKQovNpEU7oi5CbeBUnNjXxS4exXK104WNIwX8UcpOaPLZJbkS6VS40Xlwpqy0grMtaP-7tPXOOnBVEGHnteWSAP4SEFPMoSWKf0iEWMCs4fqkasnoaTXQ6nrbD-dNhyhcqGN0-dI2eauCCQendj6AWTCQlrcPksAntT2yQ5n81DHmNyGnQH7FhzJlkSnB2VB2cZCN91kq9HhEWDBXZlF6aPBLZBMflf9-M9kHHtXkie0k8ZO_fw
x-api-key: test-api-key
Custom-Header: common-value
keycloak-auth-client:
logger-level: none # 기록하지 않음
defaultRequestHeaders:
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJLbHVfNEVEamQzQnRseUdpaUtabTNFUTF0cXZReDNGOUN0WGxEUXJ0QUpBIn0
x-api-key: custom-api-key
Custom-Header: common-header-value
2. Configuration 기반 설정 방법
💡 Configuration 설정
- OpenFeign를 이용한 요청을 수행할때, header에 대한 설정을 추가하였습니다. - Header에 Authorization를 통한 Bearer 토큰 전송을 하고 추가적으로 커스텀 키에 해당하는 “x-api-key”를 추가하며, Custom-Header를 추가하여서 OpenFeign 전송 시마다 전달을 하도록 구성하였습니다.