ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • spring boot 2.0 actuator
    카테고리 없음 2023. 4. 22. 14:40
    오늘은 Spring boot 2.0의 actuator에 대해서 살펴보자. 아직 마일스톤 버전이라 바뀔 가능성은 있지만 크게 바뀌지 않을 것 같다. 기존(2.0 이전)의 actuator 와는 구조가 많이 변경되었다. 구조가 변경되었다고 하더라도 우리가 사용하는 것에 대해서는 많은 변화는 없다. 약간의 변화? 일단 spring-boot-actuator 모듈이 분리 되었다. 원래는 spring-boot-actuator 모듈 하나만 있었지만 autoconfigure 모듈이 새로 추가되었다.
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-actuator-autoconfigure</artifactId>
    </dependency>
    
    하지만 우리는 기존과 동일하게 spring-boot-starter-actuator 만 디펜더시 받으면 된다. 그럼 자동으로 actuatoractuator-autoconfigure이 디펜더시 받아진다.
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    
    
    일단 필자가 아는 것만큼 이야기를 해보자.

    Endpoint

    새로운 @Endpoint 어노테이션이 추가되었다. 기존에는 인터페이스로 되어있던 걸로 기억하는데 어노테이션으로 변경되었다. 새로운 @Endpoint 속성에는 세가지 속성이 있다. id, exposure, defaultEnablement 속성인데 id는 말그대로 id를 뜻하며 endpoint 도 id와 동일하게 지정된다. exposure 은 노출 속성을 의미한다. 두가지 속성이 있는데 JMXWEB이 있다. 아무 설정하지 않았을 경우에는 모두 다 노출되며 특정한(JMX 혹은 WEB) 경우에 노출 시키고 싶다면 JMX 또는 WEB을 지정해주면 된다. defaultEnablement 속성은 기본적으로 enable 시킬 것인가 아니면 disable 시킬것인가 속성이다. 일단 한번 코드로 살펴보자.
    @Endpoint(id = "hello")
    @Component
    public class HelloEndpoint {
    
      @ReadOperation
      public String hello(String name)  {
        return "hello " + name;
      }
    
      @WriteOperation
      public String foo(String name) {
        return name;
      }
    }
    
    
    나머지는 위에서 설명을 했으니 넘어가고 여기서 조금 익숙하지 않은 어노테이션이 눈에 띈다. @ReadOperation, @WriteOperation 어노테이션이다. 이 어노테이션은 말그대로 읽기 오퍼레이션이냐 쓰기 오퍼레이션이냐를 정하는 것이다. 그럼 무엇이 다를까? ReadOperation은 http method의 GET에 해당하고 WriteOperation 어노테이션은 POST에 해당한다. 이외에도 @DeleteOperation 어노테이션도 존재한다. 아마도 DELETE 메서드에 해당하지 않을까 생각된다. 아직 테스트는 해보지 않았지만 그러지 않을까? 한번 요청을 해보자.
    http http://localhost:8080/application/hello name==wonwoo
    
    hello wonwoo
    
    위와 같이 요청을 했을 경우 hello wonwoo를 볼 수 있을 것이다. 아니다 볼 수 없다. 왜냐하면 기본적으로 몇가지를 제외하고는 모두 disable 되어 있기 때문이다. 루트와 info, status를 제외하고는 모두 비활성화 되어있다. enable 시키기 위해서는 프로퍼티에 다음과 같이 작성하면 된다.
    endpoints.hello.web.enabled=true
    
    만약 web을 활성화 시키고 싶다면 위와 같이 작성하면 된다. JMX를 활성화 시키고 싶다면 동일하게 endpoints.hello.jmx.enabled=true 를 작성해주면 된다. 하지만 지금 버그인지 원래그런건지 아니면 필자가 M5 버전이라 그런건지 web만 설정하고 싶어서 저렇게 했는데 jmx도 보인다. 하지만 jmx만 설정하면 web은 동작하지 않는다. 뭐 나중에 다시 확인해봐서 안되면 한번 물어나보지 머.. 위와 같이 작성을 했다면 다시 요청을 해보자. 그럼 원하는 대로 hello wonwoo를 볼수 있을 것이다. 하지만 spring boot 에서는 web을 사용할 때 다른 것을 권장하고 있다. @WebEndpointExtension 어노테이션을 사용해서 웹에 특화되게 확장한 어노테이션이라고 생각하면 된다. 다른 건없다. 사용법도 간단하다. 아래와 같이 해당 엔드포인트만 연결해주면 된다.
    @WebEndpointExtension(endpoint = HelloEndpoint.class)
    @Component
    public class HelloWebEndpointExtension {
    
      private final HelloEndpoint delegate;
    
      public HelloWebEndpointExtension(HelloEndpoint delegate) {
        this.delegate = delegate;
      }
    
      @ReadOperation
      public WebEndpointResponse<String> hello(@Nullable String name) {
        return new WebEndpointResponse<>(delegate.hello(name));
      }
    }
    
    어렵지 않다. 딱 보기에도 쉽다. 참고로 spring5부터는 Nullable을 지원한다. 옵션값일 경우 spring 에서 제공해주는 Nullable 어노테이션을 사용하면 된다. DI를 받을 때에도 옵션 값이면 Nullable을 사용하면 된다.
    private final SomeClass some;
    
    public HelloEndpoint(@Nullable SomeClass some) {
      this.some = some;
    }
    
    그리고 Spring boot 만의 Conditional 어노테이션인 ConditionalOnEnabledEndpoint 어노테이션이 추가 되었다. 이것은 endpoints.hello.enabled=false 일 때는 빈으로 동작 시키지 않는 어노테이션이다.
    @Bean
    @ConditionalOnEnabledEndpoint
    public HelloEndpoint helloEndpoint() {
      return new HelloEndpoint();
    }
    
    위와 같이 설정 했을 경우 endpoints.hello.enabled=false 이라면 helloEndpoint는 빈으로 등록 시키지 않는다. 이외에도 ConditionalOnEnabledHealthIndicator 어노테이션도 추가 되었다. HealthIndicator는 설정 하는 것 이외에는 변경된 부분은 없다. 기존과 동일하게 HealthIndicator 인터페이스 혹은 AbstractHealthIndicator 추상 클래스를 구현하면 된다.
    @Component
    public class DummyHealthIndicator implements HealthIndicator {
    
      @Override
      public Health health() {
        return Health.up().build();
      }
    
    }
    
    HealthIndicator는 우리가 사용하는 것에 대한 변화는 없으므로 넘어가고 마지막으로 Endpoint에 새로 추가된 어노테이션이 하나 더 있다. 그건 @Selector라는 어노테이션인데 간단히 말해서 PathVariable 어노테이션과 동일하다.
    @ReadOperation
    public WebEndpointResponse<String> selector(@Selector String name) {
      return new WebEndpointResponse<>(delegate.hello(name));
    }
    
    위와 같이 설정 했을 경우에 다음과 같이 요청이 가능하다.
    http http://localhost:8080/application/hello/wonwoo
    
    hello wonwoo
    
    그럼 동일하게 hello wonwoo라고 응답 받을 수 있다. 안타깝게 현재는 Post로 받을때 바디를 Object로 받을 수 는 없다. 나중에 가능할지는 모르겠지만 현재로는 String, Integer, Long 기타 enum 등으로만 받을 수 있다.
    @WriteOperation
    public WebEndpointResponse<Person> person(String name) {
      return new WebEndpointResponse<>(new Person(delegate.hello(name)));
    }
    
    위와 같이 POST로 설정했을 경우 body로 요청 할 수 있다.
    http POST http://localhost:8080/application/hello name=wonwoo
    
    {
        "name": "hello wonwoo"
    }
    
    이렇게 actuator 의 Endpoint에 변화에 대해서 알아봤다. 다른 것들은 우리가 사용하는데 있어서 많은 변화는 없었지만 내부적으로 많은 변화가 있었다. 특히 reactive가 추가 됨으로써 구조적으로 많은 변화가 있었다. 우리는 잘 가져다 쓰면 된다. 물론 내부를 아는 것이 휠씬 좋지만 일단 먼저 어떻게 사용하지는 아는 것도 중요하니 잘 가져다 쓰자. 오늘은 이렇게 Spring boot 2.0 actuator에 대해서 살펴봤다. reactive stream 도 공부하는 중이라 조만간 한번 언급을 할 예정이다. 하지만 너무 어렵..

    댓글

Designed by Tistory.