1. 스프링클라우드 게이트웨이
https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/
2. 핵심 구성 요소:
술부
GetewayFilter
전역 필터
3. 개략적인 개요
3. SpringMVC와의 수평적 비교
SpringMVC =====> 스프링 WebFlux
DispatchServlet =====> DispatchHandler
경로 일치:
핸들러 매핑 =====>핸들러 매핑
HanderAdaper ====> HanderAdaper
핸들러 =====> 웹핸더
4. 소스코드 추적
핵심 클래스: org.springframework.web.reactive.DispatcherHandler
public Mono<Void> handle(ServerWebExchange exchange) {
return this.handlerMappings == null ? this.createNotFoundError() : Flux.fromIterable(this.handlerMappings).concatMap((mapping) -> {
return mapping.getHandler(exchange);
}).next().switchIfEmpty(this.createNotFoundError()).flatMap((handler) -> {
return this.invokeHandler(exchange, handler);
}).flatMap((result) -> {
return this.handleResult(exchange, result);
});
}
org.springframework.cloud.gateway.handler.RoutePredicateHandlerMapping#getHandler내부
LookupRoute에서 모든 Predicate 어설션을 실행합니다.
protected Mono<Route> lookupRoute(ServerWebExchange exchange) {
return this.routeLocator.getRoutes().concatMap((route) -> {
return Mono.just(route).filterWhen((r) -> {
exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_PREDICATE_ROUTE_ATTR, r.getId());
return (Publisher)r.getPredicate().apply(exchange);
}).doOnError((e) -> {
this.logger.error("Error applying predicate for route: " + route.getId(), e);
}).onErrorResume((e) -> {
return Mono.empty();
});
}).next().map((route) -> {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Route matched: " + route.getId());
}
this.validateRoute(route, exchange);
return route;
});
}
org.springframework.cloud.gateway.handler.FilteringWebHandler#handle
모든 GlobalFilters를 필터로 변환하고 필터 체인에 추가합니다.
public Mono<Void> handle(ServerWebExchange exchange) {
Route route = (Route)exchange.getRequiredAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);
List<GatewayFilter> gatewayFilters = route.getFilters();
List<GatewayFilter> combined = new ArrayList(this.globalFilters);
combined.addAll(gatewayFilters);
AnnotationAwareOrderComparator.sort(combined);
if (logger.isDebugEnabled()) {
logger.debug("Sorted gatewayFilterFactories: " + combined);
}
return (new FilteringWebHandler.DefaultGatewayFilterChain(combined)).filter(exchange);
}
모든 필터
핵심 클래스 org.springframework.cloud.gateway.filter.LoadBalancerClientFilter
리본은 serviceId를 기반으로 해당 서비스의 IP를 찾습니다.
public Mono<Void> handle(ServerWebExchange exchange) {
Route route = (Route)exchange.getRequiredAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);
List<GatewayFilter> gatewayFilters = route.getFilters();
List<GatewayFilter> combined = new ArrayList(this.globalFilters);
combined.addAll(gatewayFilters);
AnnotationAwareOrderComparator.sort(combined);
if (logger.isDebugEnabled()) {
logger.debug("Sorted gatewayFilterFactories: " + combined);
}
return (new FilteringWebHandler.DefaultGatewayFilterChain(combined)).filter(exchange);
}