Spring Framework
Spring Webflux - Utils
흥부가귀막혀
2022. 3. 14. 13:14
BlockHound
- Spring Webflux 는 예상치 못한 blocking 로직이 있을 경우 성능에 큰 영향을 미치기 때문에 이러한 로직이 있는지 탐지하고 수정할 수 있어야 한다.
- BlockHound 는 비지니스 로직이 수행될 때 blocking 로직이 있으면 exception 을 던져 blocking 로직을 파악할 수 있게 도와준다.
- 번역 gateway 에서는 아래와 같은 방식으로 blockhound 를 실행한다.
Dependency 추가
<dependency>
<groupId>io.projectreactor.tools</groupId>
<artifactId>blockhound</artifactId>
<version>1.0.3.RELEASE</version>
</dependency>
Application class 에서 BlockHound 실행여부를 판단
@SpringBootApplication
public class Application {
static final String BLOCK_HOUND_INSTALL = "service.block-hound.install"; // (1)
public static void main(String[] args) {
boolean installBlockHound = SpringApplication.run(Application.class, args) // (2)
.getEnvironment()
.getProperty(BLOCK_HOUND_INSTALL, boolean.class, false);
if (installBlockHound) {
BlockHound.install(); // (3)
}
}
}
(1) application 실행시 특정 config 값을 통해 BlockHound 실행 여부를 판단할 수 있게 정의한다.
(2) application 실행시 BlockHound 실행 여부를 판단할 수 있는 config 값을 조회한다.
(3) BlockHound 를 실행하도록 config 가 주입되었으면 install API 호출을 통해 실행
- 비지니스 로직 수행중에 blocking 로직이 탐지되면 아래와 같이 에러가 발생한다.
java.lang.Error: Blocking call! java.lang.Thread.sleep
at reactor.blockhound.BlockHound$Builder.lambda$new$0(BlockHound.java:167)
at reactor.blockhound.BlockHound$Builder.lambda$install$6(BlockHound.java:226)
at reactor.blockhound.BlockHoundRuntime.checkBlocking(BlockHoundRuntime.java:46)
at java.lang.Thread.sleep(Thread.java)
at com.example.demo.DemoApplication.block(DemoApplication.java:30)
Reloadable Configuration
- Reloadable Configuration 을 하는 방법은 몇가지 있지만 Spring 에서 공식적으로 지원하는 방식은 Spring Cloud에서 지원하는 @RefreshScope 사용한 방식이다.
Spring Cloud 에 대한 dependency 추가
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
</dependency>
</dependencies>
Reloadable ConfigurationProperties 정의
@Bean
@RefreshScope
@ConfigurationProperties(prefix = "example.reload.properties")
public Map<String, String> exampleProperties() {
return new HashMap<String, String>();
}
Configuration 이 필요한 곳에서는 Bean 으로 등록된 Properties 를 주입받아 사용.
@Autowired
private Map<String, String> exampleProperties;
/**
* properties value 조회
*/
public String getValue(String key) {
return exampleProperties.get(key);
}
Configuration 변경이 필요할 경우 config file 을 수정한 뒤 다음과 같이 actuator API 호출. (단, management.endpoints.web.exposure.include 에 refresh 가 활성화 되있어야 한다.)
curl -XPOST http://{host}:{port}/actuator/refresh