Spring cloud 1장 (gateway)

심심해서 해보는 스프링 클라우드 샘플코드 만들어보기

github 소스 링크

Spring cloud란

Spring 공홈 링크

이것을 설명하기보다는… 유명한 네이버, 우아한형제 등등 기술블로그에서 검색하여 간단하게 읽는 것을 강력하게 추천! 설명 잘되어있음

A. 시작해보자

build.gradle

1
2
3
4
5
6
7
8
9
10
11
12

dependencies {
implementation 'org.springframework.cloud:spring-cloud-starter'
implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
implementation 'org.springframework.cloud:spring-cloud-starter-sleuth'
implementation 'org.springframework.cloud:spring-cloud-starter-zipkin'
testImplementation 'org.springframework.boot:spring-boot-starter-test'

compileOnly 'org.projectlombok:lombok'
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
compile group: 'it.ozimov', name: 'embedded-redis', version: '0.7.2'
}

다른것을 해보기 위해 미리 디펜던시들을 추가하였고 이번장에서 중요허게 봐야할 부분은 gateway, sleuth이다. 물론 zuul도 나중에.. 시간이 된다면 추가해서 무엇이 다른지에 대한 설명을 추가해야된다.

게이트웨이란?

  • end point를 통합하는 서버이다( 클라이언트 요청의 집합소!). like 프록시 서버

슬루스란?

  • SOA, MSA이건 여러개의 서비스에서 서로간의 통신을 한다고 가정을 하자!
    • 로그 추적을 어떻게??
    • 이를 쉽게 해주는 서비스 Sleuth
    • Sleuth traceId와 spanId제공

Span ID

  • 작업의 기본 단위이다. 각 서비스 호출시에 새로운 Span이 하나 생성
  • Description, key-value annotation, process ID 등의 추가 정보를 가짐
  • Trace에서 제일 처음 만들어지는 Span을 root span이라 함(trace id와 동일)

Trace ID

  • 최초 호출시 인입 서비스에서 생성

B. 소스를 적용해보자

RouterConfig.class

1
2
3
4
5
6
7
8
9
10
11

@Configuration
@EnableWebFlux
public class RouterConfig implements WebFluxConfigurer {

@Bean
public RouterFunction<ServerResponse> routes(HelloWorldHandler handler) {
return route(GET("/"), handler::helloWorld);
}

}

HelloWorldHandler.class

1
2
3
4
5
6
7
8
9
10
@Component
public class HelloWorldHandler {

private static final Logger logger = LoggerFactory.getLogger(HelloWorldHandler.class);

public Mono<ServerResponse> helloWorld(ServerRequest request) {
logger.info("start to get healthcheck");
return ServerResponse.ok().body(Mono.just("hello"), String.class);
}
}

위처럼 하면 끝이다. 물론 현재 프록시하는 역할을 가지고 있지 않다. 2장에서 서비스 서버 하나를 띄우고 어찌작동되는지 함께 보여줄 예정

위처럼 하고 실행! 후 http://localhost:9000/

1
2019-07-21 18:19:10.084  INFO [gateway,3fb0ee4984a21a7e,3fb0ee4984a21a7e,false] 37457 --- [ctor-http-nio-2] c.b.beangw.handler.HelloWorldHandler     : start to get healthcheck

앞쪽이 traceId, 뒤쪽이 spanid이다

집킨설정을 통해 로그를 바꿔보자

application.yml

1
2
3
4
spring:
zipkin:
service:
name: sample-gw

재기동 후 로그는 아래처럼

1
2019-07-21 18:22:25.117  INFO [sample-gw,1c296c8c12cc57b5,1c296c8c12cc57b5,false] 37462 --- [ctor-http-nio-2] c.b.beangw.handler.HelloWorldHandler     : start to get healthcheck

C. 헤더에 traceID를 심어보자

GatewayDefaultConfig.class

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
32

@Configuration
public class GatewayDefaultConfig {

private final Tracer tracer;



public GatewayDefaultConfig(Tracer tracer) {
this.tracer = tracer;

}

private static final Logger logger = LoggerFactory.getLogger(GatewayDefaultConfig.class);


@Bean
public GlobalFilter lifeLandGlobalFilter() {


return (exchange, chain) -> chain.filter(exchange).then(Mono.fromRunnable(() -> {


String tracerId = tracer.currentSpan().context().traceIdString();

exchange.getResponse().getHeaders().set("X-BEANBROKER-TRACE", tracerId);


}));
}

}

음 실제로 운영하다보면 헤더에 trace-id를 넣어서 하면 좋은 경우가 있다.

2장에서 실제로 서비스서버로 호출하여 trace-id가 찍히는지 확인해보자!