ํ† ์Šค์˜ Spring Boot Actuator์˜ ํ—ฌ์Šค์ฒดํฌ ์‚ดํŽด๋ณด๊ธฐ๋ผ๋Š” ๊ธ€์„ ๋ณด๊ณ  ์Šคํ”„๋ง ๋ถ€ํŠธ ์•ก์ถ”์—์ดํ„ฐ์—์„œ ๊ธฐ๋ณธ์œผ๋กœ ์ œ๊ณตํ•˜๋Š” MailHealthIndiator์˜ ํ—ฌ์Šค ์ฒดํฌ ๊ฒฐ๊ณผ๋ฅผ ๋ณ„๋„๋กœ ์š”์ฒญํ•˜๋Š” ๊ฒฝ์šฐ management.endpoint.health.cache-time-to-live ์†์„ฑ์œผ๋กœ ์บ์‹œ๋˜์ง€ ์•Š์Œ์„ ํ™•์ธํ–ˆ๋‹ค. ํ•ด๋‹น ์†์„ฑ์€ ์ „์ฒด ํ—ฌ์Šค ์ฒดํฌ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ—ฌ์Šค ์—”๋“œํฌ์ธํŠธ(/actuator/health)์— ํ•ด๋‹นํ•˜๋Š” ์บ์‹œ ์˜ต์…˜์œผ๋กœ ๋ฉ”์ผ์— ๋Œ€ํ•œ ํ—ฌ์Šค ์—”๋“œํฌ์ธํŠธ(/actuator/health/mail)์— ๋Œ€ํ•ด์„œ๋Š” ์ ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค.

์Šคํ”„๋ง ๋ถ€ํŠธ ์•ก์ถ”์—์ดํ„ฐ์˜ MailHealthIndicator ๋Š” JavaMailSenderImpl์˜ testConnection ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ํ—ฌ์Šค ์ฒดํฌ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ์ž‘์„ฑ๋˜์–ด์žˆ๋‹ค. MailHealthIndicator๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ HealthIIndicator๋ฅผ ๊ตฌํ˜„ํ•˜๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœ ์ œ๊ณตํ•˜๋Š” MailHealthIndicator ๋Œ€์‹ ์— ๋“ฑ๋ก๋˜๋ฏ€๋กœ SMTP ์„œ๋ฒ„๋กœ์˜ ์—ฐ๊ฒฐ ์ˆ˜ํ–‰ ๊ฒฐ๊ณผ๋ฅผ ์บ์‹œํ•˜์—ฌ ์‘๋‹ตํ•˜๋„๋ก ์ž‘์„ฑํ•ด๋ณผ ์ˆ˜ ์žˆ๋‹ค.

CachableMailHealthIndicator

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.mail.MailHealthIndicator;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.time.Instant;

@Component("mailHealthIndicator")
public class CachableMailHealthIndicator extends MailHealthIndicator implements InitializingBean {
    private Cache<String, Health> cache;

    public CachableMailHealthIndicator(JavaMailSenderImpl javaMailSender) {
        super(javaMailSender);
    }

    @Override
    protected void doHealthCheck(Health.Builder builder) throws Exception {
        Health cached = cache != null ? cache.getIfPresent("mail") : null;
        if (cached != null) {
            builder.status(cached.getStatus()).withDetails(cached.getDetails());
            return;
        }

        try {
            super.doHealthCheck(builder);
        } catch (Exception e) {
            builder.down(e);
        }

        if (cache != null) {
            Health health = builder.withDetail("datetime", Instant.now()).build();
            cache.put("mail", health);
        }
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        cache = CacheBuilder.newBuilder()
                .maximumSize(1)
                .expireAfterWrite(Duration.ofSeconds(30))
                .build();
    }
}

268ms โ†’ 4ms

CacheableMailHealthIndicator๋Š” ํ˜ธ์ŠคํŠธ ์ •๋ณด ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์บ์‹œ๋œ ์‹œ๊ฐ„์„ ํฌํ•จํ•˜์—ฌ ์–ธ์ œ ์ธก์ •๋œ ๊ฒฐ๊ณผ์ธ์ง€๋„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.