Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- JPA
- 키클락
- 체인 패턴
- Transaction Pattern
- spring cloud
- Serial GC
- 배치
- thread
- Java
- 사가 패턴
- 스프링 배치
- 디자인 패턴
- 멀티스레드
- java 정렬
- saga pattern
- 디자인패턴
- TypeScript
- 생산자 소비자 패턴
- 스레드
- zipkin
- Spring Boot Actuator
- spring batch
- Resilinece4j
- 알고리즘
- Action Pattern
- The law of Demeter
- Parallel Old GC
- MSA
- 타입스크립트
- Spring Cloud Netfilx Eureka
Archives
- Today
- Total
PSD( Private-Self-Development )
API Gateway 본문
API Gateway 란?
사용자가 설정한 라우팅 설정에 따라서 각각의 엔드포인트에 요청을 대신 보내주고 응답을 대신 받아서 이를 전달하는 프록시 역할을 수행한다.
MSA 에 해당 구조가 사용되는 이유는
클라이언트에서 각각의 micro service 를 직접 호출하게 되면
micro service 에 수정사항이 생기면 각각의 클라이언트가 모두 수정되야 하므로
이를 방지하기 위해 사용한다.
API Gateway 의 기능
- 인증 및 권한 부여
- 서비스 검색 통합
- 응답 캐싱
- 정책, 회로 차단기(서비스 문제 생긴 경우) 및 Qos 다시 시도
- 속도 제한
- 부하 분산( Load Balancing )
- 로깅, 추적, 상관 관계
- 헤더, 쿼리 문자열 및 청구 변환
- IP 허용 목록에 추가
Netflix Rebbon (Deprecated)
- Client Side Load Balancer
- 서버가 아닌 클라이언트에서 사용한다.
- MSA 이름으로 호출 가능
- 비동기 처리가 불가능하므로 잘 사용하지 않는다.
Netflix zuul (Deprecated)
- Server Side Load Balancer
Spring Cloud Gateway
- 사용 권장
구현
1. Dependency 추가
implementation 'org.springframework.cloud:spring-cloud-starter-config'
implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
2. yml 파일 설정
server:
port: 8000
# Service Discovery 에 게이트 웨이 등록
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:8761/eureka
# Service Discovery 사용 안하는 경우
Spring:
application:
name: apigateway-service
cloud:
gateway:
# yml 에서 필터 및 라우팅 설정
routes:
- id: first-service
uri: http://localhost:8081/
predicates:
- Path=/first-service/**
filters:
# 헤더값 추가
- AddRequestHeader = first-request, first-requests-header2
- AddResponseHeader = first-response, first-response-header2
# 커스텀 필터 적용
- CustomFilter
- id: second-service
uri: http://localhost:8082/
predicates:
- Path=/second-service/**
filters:
# 헤더값 추가
- AddRequestHeader = first-request, first-requests-header2
- AddResponseHeader = first-response, first-response-header2
# 커스텀 필터 적용
- CustomFilter
# 커스텀 필터 적용 (매개 변수 사용)
- name: loggingFilter
args:
baseMessage: Spring Cloud Gateway GlobalFilter
preLogger: true
postLogger: true
# 공통 필터 설정
default-filters:
- name: GlobalFilter
args:
baseMessage: Spring Cloud Gateway GlobalFilter
preLogger: true
postLogger: true
# Service Discovery 사용 하는 경우
Spring:
cloud:
gateway:
routes:
- id: first-service
uri: lb://MY-FIRST-SERVICE # 로드 밸런서:서비스 이름 => 이러면 Service Discovery 에서 자동으로 로드 밸런서 동작을 한다.
predicates:
- Path=/first-service/**
filters:
3. java 코드를 이용한 필터 및 라우터 추가
/**
* 자바 코드를 이용한 필터 적용
* */
@Configuration
public class FilterConfig {
@Bean
public RouteLocator gatewayRoutes(RouteLocatorBuilder builder){
return builder.routes()
.route( r -> r.path("/first-service/**")
.filters( f -> f.addRequestHeader("first-request", "first-request-header")
.addResponseHeader("first-response", "first-response-header")
)
.uri("http://localhost:8081/")
)
.route( r -> r.path("/second-service/**")
.filters( f -> f.addRequestHeader("second-request", "second-request-header")
.addResponseHeader("second-response", "second-response-header")
)
.uri("http://localhost:8082/")
)
.build();
}
}
4. 커스텀 필터 구현
/**
* 커스텀 필터
* 각각의 라우터 정보에 맵핑 필요
* */
@Component
@Slf4j
public class CustomFilter extends AbstractGatewayFilterFactory<CustomFilter.Config> {
public CustomFilter(Class<Config> configClass) {
super(configClass);
}
public static class Config{
// Config Info
}
@Override
public GatewayFilter apply(Config config) {
// 기본
return (exchange,chain) -> {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
log.info("Custom PRE filter: request ID -> {}", request.getId());
return chain.filter(exchange).then(Mono.fromRunnable(()->{
log.info("Custom POST filter: response code -> {}", response.getStatusCode());
}));
};
// 우선 순위 설정 가능
GatewayFilter filter = new OrderedGatewayFilter((exchange,chain) -> {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
log.info("Custom PRE filter: request ID -> {}", request.getId());
return chain.filter(exchange).then(Mono.fromRunnable(()->{
log.info("Custom POST filter: response code -> {}", response.getStatusCode());
}));
}, Ordered.HIGHEST_PRECEDENCE);
return filter;
}
}
5. 글로벌 필터 구현
@Component
@Slf4j
public class GlobalFilter extends AbstractGatewayFilterFactory<GlobalFilter.Config> {
public GlobalFilter(Class<Config> configClass) {
super(configClass);
}
@Data
public class Config {
private String baseMessage;
private boolean preLogger;
private boolean postLogger;
}
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
log.info(config.getBaseMessage());
if(config.isPreLogger()){
log.info(request.getId());
}
return chain.filter(exchange).then(Mono.fromRunnable( () -> {
if(config.isPostLogger()){
log.info(response.getStatusCode() + "");
}
}));
};
}
}
'Backend > MSA' 카테고리의 다른 글
Kafka( 카프카 ) (0) | 2024.04.22 |
---|---|
Feign Client (1) | 2024.04.19 |
Spring Cloud Config (0) | 2024.04.16 |
Service Discovery (1) | 2024.01.09 |
MSA (0) | 2024.01.09 |