큰 서비스는 분산된 많은 마이크로 서비스가 존재합니다.
고객은 마이크로 서비스에 대해 너무 많은 통신이 필요하고 클라이언트와 서비스 간의 결합도가 매우 높아집니다.
또한 권한 처리와 같은 보안 이슈를 비롯하여 장애 처리, 로깅, 모니터링, 캐싱 처리가 비효율적일 수 밖에 없습니다.
위 구조를
단일접점: 마이크로 서비스를 모아서 단일 접점을 제공해줍니다.
캡슐화: 내부 마이크로 서비스를 캡슐화해줍니다.
API Gateway는 마이크로 서비스를 묶어 단일 진입점을 제공합니다.
때문에 보안과 권한 제어과 같은 공통 로직 처리를 처리하기 좋습니다.
API에 대한 로깅 처리와 모니터링을 제어하기 수월합니다.
라우팅 기능을 제공하며 부하를 분산해주는 역할을 합니다.
단일 장애 포인트가 될 수 있습니다.
만약 API Gateway에 장애가 생길 경우 서비스 전체가 다운되는 현상이 벌어집니다.
또한 추가 네트워크 호출이 늘어나기 때문에 응답 속도가 상대적으로 저하됩니다.
라우팅하는 방식은 Java Config 설정과 Yml 파일 설정을 가장 많이 사용하며 형식은 아래와 같습니다.
@Configuration
public class RouteConfiguration {
public static final String MICROSERVICE_HOST_8080 = "http://localhost:8080";
@Bean
public RouteLocator helloRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("path_simple_hello",
r -> r.path("/hello")
.uri(MICROSERVICE_HOST_8080)
)
.build();
}
}
spring:
cloud:
gateway:
routes:
- id: path_simple_hello
uri: http://localhost:8080
predicates:
- Path=/hello
@Configuration
public class RouteConfiguration {
public static final String MICROSERVICE_HOST_8080 = "http://localhost:8080";
@Bean
public RouteLocator helloRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("path_route_hello", r -> r.path("/gateway-hello")
.filters(f -> f.rewritePath("/gateway-hello", "/microservice-hello"))
.uri(MICROSERVICE_HOST_8080)).build();
}
}
@Bean
public RouteLocator helloRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("add-header-route", r -> r.path("/get")
.filters(f -> f.addRequestHeader("role", "hello-api"))
.uri(ECHO_HTTP_BIN)
).build();
}
spring:
cloud:
gateway:
routes:
- id: path_route_hello
uri: http://localhost:8080
predicates:
- Path=/gateway-hello
filters:
- RewritePath=/gateway-hello, /microservice-hello
spring:
cloud:
gateway:
httpclient:
connect-timeout: 1000
response-timeout: 5s
@Component
class OrderApiRouteLocator {
@Value("${route.order-api.v1.base-url}")
String orderBaseUrl;
private final String gatewayPath = "/providers/order-api/v1/";
@Bean
public RouteLocator customOrderApiRouteLocator(RouteLocatorBuilder routeLocatorBuilder) {
return routeLocatorBuilder.routes()
.route("order-api",
r -> r.path(gatewayPath + "**")
.filters(f ->
f.rewritePath(gatewayPath + "(?<servicePath>.*)", "/${servicePath}")
).uri(orderBaseUrl)).build();
}
}
위 코드는 /providers/order-api/v1/가 포함되는 EndPoint로 요청이 왔을 때 라우팅을 해줍니다.
예를 들어 /providers/order-api/v1/orders/id 라는 응답이 오면 /providers/order-api/v1/ 뒤에 존재하는 /orders/id 경로로 라우팅을 해줍니다.
ex) routing 서버 = localhost:9090
주문 서버 = localhost:7070
결제 서버 = localhost:6060
orderBaseUrl = http://localhost:7070/
- client에서 localhost:9090/providers/order-api/v1/orders/${id}를 호출
- localhost:7070/orders/${id}로 라우팅
출처 : FastCampus
Git 주소