2023. 5. 22. 16:33ใ์ธํ๋ฐ/์คํ๋ง ๋ถํธ - ํต์ฌ ์๋ฆฌ์ ํ์ฉ
0๏ธโฃ Timer ๋?
: Timer ๋ ์ข ํน๋ณํ ๋ฉํธ๋ฆญ ์ธก์ ๋๊ตฌ๋ก, ์๊ฐ์ ์ธก์ ํ๋๋ฐ ์ฌ์ฉ๋๋ค.
์นด์ดํฐ์ ์ ์ฌํ๋ฉฐ, Timer๋ฅผ ์ฌ์ฉํ๋ฉด ์คํ์๊ฐ๋ ํจ๊ป ์ธก์ ํ ์ ์๋ค.
seconds_count : ๋์ ์คํ ์ (์นด์ดํฐ)
seconds_sum : ์คํ ์๊ฐ ์ ํฉ
seconds_max : ์ต๋ ์คํ ์๊ฐ(๊ฐ์ฅ ์ค๋๊ฑธ๋ฆฐ ์คํ ์๊ฐ) (๊ฒ์ด์ง) -> ๋ด๋ถ์ ํ์ ์๋์ฐ๋ผ๋ ๊ฐ๋ ์ด ์๊ธฐ ๋๋ฌธ์ 1 ~ 3 ๋ถ ๋ง๋ค ์ต๋ ์คํ ์๊ฐ์ด ๋ค์ ๊ณ์ฐ๋๋ค.
1๏ธโฃ ๋ฉํธ๋ฆญ ๋ฑ๋ก 3 - Timer
OrderServiceV3
@Slf4j
public class OrderServiceV3 implements OrderService
{
private final MeterRegistry meterRegistry;
private AtomicInteger stock = new AtomicInteger(100);
public OrderServiceV3(MeterRegistry meterRegistry)
{
this.meterRegistry = meterRegistry;
}
@Override
public void order()
{
Timer timer = Timer.builder("my.order")
.tag("class", this.getClass().getName())
.tag("method", "order")
.description("order")
.register(meterRegistry);
timer.record(() -> {
log.info("์ฃผ๋ฌธ");
stock.decrementAndGet();
sleep(500);
});
}
@Override
public void cancel()
{
Timer timer = Timer.builder("my.order")
.tag("class", this.getClass().getName())
.tag("method", "cancel")
.description("cancel")
.register(meterRegistry);
timer.record(() -> {
log.info("์ทจ์");
stock.incrementAndGet();
sleep(200);
});
}
@Override
public AtomicInteger getStock()
{
return stock;
}
private static void sleep(int l)
{
try
{
Thread.sleep(l + new Random().nextInt(200));
}
catch (InterruptedException e)
{
throw new RuntimeException(e);
}
}
}
Timer ์์ฑํ๊ณ ๋ฑ๋กํ๋ ๊ฒ๋ Timer์ ๋น์ทํ๋ค.
Timer.builder(name) ์ ํตํด์ ํ์ด๋จธ๋ฅผ ์์ฑํ๊ณ name์ ๋ฉํธ๋ฆญ ์ด๋ฆ์ ์ง์ ํด์ค๋ค.
tag๋ฅผ ์ฌ์ฉํด ํ๋ก๋ฉํ ์ฐ์ค์์ ํํฐํ ์ ์๋ ๋ ์ด๋ธ๋ก ์ฌ์ฉ๋๋ค. -> ์ฃผ๋ฌธ๊ณผ ์ทจ์๋ ๋ฉํธ๋ฆญ ์ด๋ฆ์ ๊ฐ๊ณ tag๋ฅผ ํตํด์ ๊ตฌ๋ถํ๋๋ก ํ๋ค.
register(registry) ๋ฅผ ํตํด ๋ง๋ MeterRegistry์ ๋ฑ๋กํ๋ฉด ์ค์ ๋ก ๋ฑ๋กํ๋ค.
Timer๋ฅผ ์์ฑํ ๋ค์์ ํ์ด๋จธ๋ฅผ ์ฌ์ฉํ ๋๋ timer.record()๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ทธ ์์ ์๊ฐ์ ์ธก์ ํ๊ณ ์ถ์ ๋ด์ฉ์ ํจ์๋ก ํฌํจํ๋ฉด ๋๋ค.
(๊ทธ๋ฆฌ๊ณ ์ด๋ ์ฃผ๋ฌธ or ์ทจ์ํ ๋ ๊ฑธ๋ฆฌ๋ ์๊ฐ์ ํ์ธํ๊ธฐ ์ํด์ 0.5, 0.2 ์ด ๋๊ธฐํ๋๋ก ํ๋ค. ๊ทธ๋ฆฌ๊ณ ์ต๋ ์คํ์๊ฐ์ ํ์ธํ๊ธฐ ์ํด์ ๋๋ค์ผ๋ก ๊ฐ์ ๋ํด์คฌ๋ค. )
OrderConfigV3
@Configuration
public class OrderConfigV3
{
@Bean
OrderService orderService(MeterRegistry meterRegistry)
{
return new OrderServiceV3(meterRegistry);
}
}
ActuatorApplication
@Import(OrderConfigV3.class)
@SpringBootApplication(scanBasePackages = "hello.controller")
public class ActuatorApplication {
public static void main(String[] args) {
SpringApplication.run(ActuatorApplication.class, args);
}
}
* ์คํ
http://localhost:8080/order
http://localhost:8080/cancel
๋ง์ฐฌ๊ฐ์ง๋ก ์๋ก ์์ํ๋๊ฑฐ๋๊น ์ฃผ๋ฌธ๊ณผ ์ทจ์๋ฅผ ๋ช๋ฒ ์คํดํด์ฃผ๊ณ ๋ฉํธ๋ฆญ ํ์ธํ๋ฉด ๋๋ค.
http://localhost:8080/actuator/metrics/my.order
COUNT : ๋์ ์คํ ์๊ฐ (์นด์ดํฐ)
TOTAL_TIME : ์คํ ์๊ฐ์ ํฉ (๊ฐ๊ฐ์ ์คํ ์๊ฐ ๋์ ํฉ)
MAX : ์ต๋ ์คํ ์๊ฐ (๊ฐ์ฅ ์ค๋ ๊ฑธ๋ฆฐ ์คํ์๊ฐ)
* ๊ทธ๋ผํ๋ ๋ฑ๋ก
* ์ฃผ๋ฌธ์
* ์ต๋ ์คํ์๊ฐ
* ํ๊ท ์คํ์๊ฐ
2๏ธโฃ ๋ฉํธ๋ฆญ ๋ฑ๋ก 4 - @Timed
OrderServiceV4
@Timed(value = "my.order")
@Slf4j
public class OrderServiceV4 implements OrderService
{
private AtomicInteger stock = new AtomicInteger(100);
@Override
public void order()
{
log.info("์ฃผ๋ฌธ");
stock.decrementAndGet();
sleep(500);
}
@Override
public void cancel()
{
log.info("์ทจ์");
stock.incrementAndGet();
sleep(200);
}
@Override
public AtomicInteger getStock()
{
return stock;
}
private static void sleep(int l)
{
try
{
Thread.sleep(l + new Random().nextInt(200));
}
catch (InterruptedException e)
{
throw new RuntimeException(e);
}
}
}
@Timed("my.order") ์ด๋ ธํ ์ด์ ์ ์ฌ์ฉํด์ฃผ๋ฉด ํ๋ค๊ฒ(?) ์ฝ๋๋ฅผ ์ฌ๋ฌ๋ฒ ์์ฑํ์ง ์์๋ ์๊ฐ ์ธก์ ์ ํ ์ ์๋ค.
์ด๋ ๊ผญ ํด๋์ค๊ฐ ์๋ ํ์ ์ด๋ ๋ฉ์๋์๋ ์ ์ฉํ ์ ์๋ค.
(์ง๊ธ์ ํด๋์ค์ ์ ์ฉํ๊ณ ์๊ธฐ ๋๋ฌธ์ ์ด ๊ฒฝ์ฐ์๋ getStock() ์๋ ํ์ด๋จธ๊ฐ ์ ์ฉ๋๋ค. )
OrderConfigV4
@Configuration
public class OrderConfigV4
{
@Bean
OrderService orderService()
{
return new OrderServiceV4();
}
@Bean
public TimedAspect timedAspect(MeterRegistry meterRegistry)
{
return new TimedAspect(meterRegistry);
}
}
์ ์ @Counted์ ๋์ผํ๊ฒ @Timed๋ TimeAspect๋ฅผ ๋น์ผ๋ก ๋ฑ๋กํด์ฃผ์ง ์์ผ๋ฉด AOP๊ฐ ์ ์ฉ๋์ง ์๋๋ค.
ActuatorApplication
@Import(OrderConfigV4.class)
@SpringBootApplication(scanBasePackages = "hello.controller")
public class ActuatorApplication {
public static void main(String[] args) {
SpringApplication.run(ActuatorApplication.class, args);
}
}
* ์คํ
http://localhost:8080/actuator/metrics/my.order
http://localhost:8080/actuator/prometheus