Spring Boot Admin Server, Client config 설정하기

이미지
 Spring Boot로 많은 프로젝트를 진행하게 됩니다. 많은 모니터링 도구가 있지만, Spring Boot 어플리케이션을 쉽게 모니터링 할 수 있는 방법을 소개하려고 합니다.   코드 중심으로 살펴보겠습니다. 1. 어드민 서버 구축 1-1. 디펜던시 추가 dependencies { // https://mvnrepository.com/artifact/de.codecentric/spring-boot-admin-starter-server implementation 'de.codecentric:spring-boot-admin-starter-server:2.5.4' } 1-2. 어드민 서버 설정 활성화 @SpringBootApplication @EnableAdminServer public class ServerApplication { public static void main (String[] args) { SpringApplication. run (ServerApplication. class, args) ; } } EnableAdminServer를 하면 됩니다. 2. 클라이언트 서버 설정  예제는 book-client, member-client 2가지 클라이언트, member-client가 2개의 인스턴스 실행으로 작성했습니다.  2-1 디펜던시 추가 dependencies { // https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web implementation 'org.springframework.boot:spring-boot-starter-web:2.5.4' // https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-actuator implementation 'org.spring...

Spring boot Webflux에서 block 찾기

Webflux로 개발하는 경우 block가 있으면 성능이 현저하게 낮아 집니다.


Webflux Event Loop
따라서 개발 후에 개발한 코드에 Block을 발생 시키는 코드가 있는지 확인하는 것은 중요합니다.
이것을 도와 주는 라이브러리가 Blockhound 입니다.

1. 의존성 추가

testImplementation('org.springframework.boot:spring-boot-starter-test')
testImplementation 'io.projectreactor:reactor-test'
testImplementation 'io.projectreactor.tools:blockhound:1.0.6.RELEASE'
testImplementation 'io.projectreactor.tools:blockhound-junit-platform:1.0.6.RELEASE'
Blockhound를 사용하면 Block을 발생시키는 곳에서 에러를 발생시킵니다. 따라서 운영 환경에서는 사용을 피해야 합니다. 테스트 환경에서 사용하는 것을 추천 드립니다.

2. 샘플 라우터 작성

@Configuration
public class BlockingRouter {

@Bean
public RouterFunction<ServerResponse> blockRouter() {
return RouterFunctions.route(RequestPredicates.GET("/nonBlock").and(RequestPredicates.accept(MediaType.APPLICATION_JSON)), request -> {
return ServerResponse.ok().body(Mono.just("nonblock response"), String.class);
}).andRoute(RequestPredicates.GET("/block").and(RequestPredicates.accept(MediaType.APPLICATION_JSON)), request -> {
block(); // 직접 block
return ServerResponse.ok().body(Mono.just("block response"), String.class);
});
}

private void block() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}


3. 테스트 코드 작성

@SpringBootTest
@AutoConfigureWebTestClient
@Slf4j
public class BlockHoundTest {

@Autowired
private WebTestClient webTestClient;

@Test
public void nonBlockCallTest() {
webTestClient.get().uri("/nonBlock").exchange().expectStatus().isOk();
log.info("Calling nonblock request is succeeded");
}

/**
*
* blockhound 라이브러리에서 block이 있는 경우에 에러를 발생시킴
*/
@Test
public void blockCallTest() {
webTestClient.get().uri("/block").exchange().expectStatus().isOk();
}
}
의존성이 추가 된 경우 추가 설정을 하지 않아도 Blockhound가 자동으로 동작합니다.

4. 테스트 수행 결과

테스트 수행 결과

blockCallTest의 경우 thread.sleep에서 block가 발생하므로 테스트 코드가 실패합니다.
blockCallTest 결과 로그



샘플 코드







참조

댓글

이 블로그의 인기 게시물

Spring boot redis cache config

Spring boot redis RedisTemplate

MySQL PK 중복 (duplicate key ) 해결 방법