본문 바로가기

전체보기/Spring

[Spring Boot]HikariCP 모니터링

이번글에서는 JMX MBean을 이용한

HikariCP의 모니터링 방법을 정리해보겠습니다. 

 

MBean(Managed Bean)이란,

디바이스, 어플리케이션 혹은 리소스의 상태를 모니터링 할 수 있는 Java Object입니다.

 

HikariCP에서 제공하는 MBean을 통해서 우리는 다음과 같은 정보를 알 수 있습니다.

  • Idle connections의 수
  • Active connections(현재 사용하고 있는)의 수
  • 모든 connection의 수
  • connection을 기다리고 있는 thread의 수

Configuration

MBean을 사용하기 위해선

application.properties에 다음과 같이

pool의 이름과 register-mbeans값을 설정해야합니다.

 

spring.datasource.hikari.register-mbeans=true
spring.datasource.hikari.pool-name=hikari

 

또한 MXBean을 가져오기 위한 코드를 추가합니다.

MXBean이란 MBean의 종류 중 하나로

제공되는 데이터를 제한하여 호환성을 높인 MBean입니다. 

 

@Bean
public HikariPoolMXBean poolProxy() throws MalformedObjectNameException {
    MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
    ObjectName objectName = new ObjectName("com.zaxxer.hikari:type=Pool (hikari)");
    return JMX.newMBeanProxy(mBeanServer, objectName, HikariPoolMXBean.class);
}

 

HikariPool

이번에는 우리가 작성하는 코드가 아닌,

HikariCP의 코드를 살펴보겠습니다.

 

//HikariPool.java
public HikariPool(final HikariConfig config)
{
   // other codes

   handleMBeans(this, true);
 
   // other codes
}

void handleMBeans(final HikariPool hikariPool, final boolean register)
{
   if (!config.isRegisterMbeans()) {
      return;
   }
   try {
      final MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();

      final ObjectName beanConfigName = new ObjectName("com.zaxxer.hikari:type=PoolConfig (" + poolName + ")");
      final ObjectName beanPoolName = new ObjectName("com.zaxxer.hikari:type=Pool (" + poolName + ")");
      if (register) {
         if (!mBeanServer.isRegistered(beanConfigName)) {
            mBeanServer.registerMBean(config, beanConfigName);
            mBeanServer.registerMBean(hikariPool, beanPoolName);
         } else {
            logger.error("{} - JMX name ({}) is already registered.", poolName, poolName);
         }
      }
      else if (mBeanServer.isRegistered(beanConfigName)) {
         mBeanServer.unregisterMBean(beanConfigName);
         mBeanServer.unregisterMBean(beanPoolName);
      }
   }
   catch (Exception e) {
      logger.warn("{} - Failed to {} management beans.", poolName, (register ? "register" : "unregister"), e);
   }
}

 

위 코드는 HikariPool이 생성되는 과정 중 일부를 가져온 것으로

 

13번째 줄 if(!config.isRegisterMbeans()) 에서는 우리가

application.properties에서 설정한 register-mbeans값을 가져와

true일 경우 MXBean 객체를 생성합니다.

 

또한 MXBean을 사용하기 위해서는 MXBean 객체를 생성하고

MBean server에 등록해야하는데

 

우리가 작성한 MXBean을 가져오는 코드는

이때 MBean server에 등록된 MXBean 객체를 가져오는 것입니다.

HikariPoolMXBean

이렇게 가져온 HikariPoolMXBean은 다음과 같이 정의되어 있습니다.

 

public interface HikariPoolMXBean
{
   int getIdleConnections();

   int getActiveConnections();

   int getTotalConnections();

   int getThreadsAwaitingConnection();

   //이하 method는 allowPoolSuspension=true로 설정해야 사용가능
   void softEvictConnections();

   void suspendPool();

   void resumePool();
}

 

이름을 통해서 각각의 기능이 무엇인지는

쉽게 유추하실 수 있을 것이라 생각합니다.

 

참고로 아래 3개의 기능을 사용하기 위해서는 application.properties에

allowPoolSuspension을 true로 설정해야 합니다.

 

Example

마지막으로 MXBean을 사용하는 코드는 다음과 같습니다. 

 

@Autowired
private HikariPoolMXBean poolMXBean;

public SampleController(HikariDataSource dataSource, HikariPoolMXBean poolMXBean) {
    this.dataSource = dataSource;
    this.poolMXBean = poolMXBean;
}

private void printHikariStatus(){
    log.info("connections info total: {}, active: {}, idle: {}, await: {}", poolMXBean.getTotalConnections(),
           poolMXBean.getActiveConnections(), poolMXBean.getIdleConnections(), poolMXBean.getThreadsAwaitingConnection());
}

 

그럼 여기까지 HikariCP 모니터링 방법이었습니다.

Reference

반응형