@Async ๋ฅผ ๋์ ํ๋ฉฐ ์ปจํ ์คํธ ์ค์์นญ๊ณผ ์ฐ๋ ๋ ๋ฉ๋ชจ๋ฆฌ ๊ตฌ์กฐ ์ง์์ ๋ฐํ์ผ๋ก ์ฐ๋ ๋ ํ ์ค์ ์ ํ์ตํ๊ณ ์ ์ฉํ๋ ๊ณผ์ ์ ์๊ฐํ๋ฉฐ Jmeter ๋ฅผ ํตํด API ์๋ต ์๋๊ฐ ๊ฐ์ ๋์๋์ง ํ์ธํ๋ ๊ณผ์ ์ ๋ค์๊ณผ ๊ฐ์ ๋ชฉ์ฐจ๋ก ์๊ฐํฉ๋๋ค.
์ด๋ฉ์ผ ์ ์ก์ ๋น๋๊ธฐ๋ก ๊ฒฐ์ ํ ์ด์
์ฐ๋ ๋ ํ ์ฌ์ฉ ์ฌ๋ถ ๊ณ ๋ ค
์ฐ๋ ๋ ํ ์ค์ ๊ณ ๋ ค ์ฌํญ
์ฐ๋ ๋ ํ ์ค์
ThreadPoolTaskExecutor ๋์ ๋ฐฉ์
์ฐ๋ ๋ ํ ์ค๋ฅ ์ฒ๋ฆฌ ์ค์
Jmeter ๋ก @Async ๋์ ์ ์ฉ ์ ๊ณผ ํ์ API ์๋ต ์๊ฐ์ ๋น๊ต
@Async ์ฌ์ฉ ์ ์ฃผ์์
์ด๋ฉ์ผ ์ ์ก์ ๋น๋๊ธฐ๋ก ๊ฒฐ์ ํ ์ด์
์์ด๋น์ค๋น ํด๋ก ํ๋ก์ ํธ์์๋ ์ด๋ฉ์ผ ์ธ์ฆ ๊ธฐ๋ฐ์ ํ์๊ฐ์ /๋ก๊ทธ์ธ์ ์งํํ๊ณ ์์ต๋๋ค.
์ด๋ฉ์ผ ์ ์ก์๋ Spring Mail์ JavaMailSender๋ฅผ ์ฌ์ฉํ๊ณ ์์ผ๋ฉฐ, ์ด๋ ๋๊ธฐ API์ ๋๋ค.
์ฆ, ๋ฉ์ผ์ ๋ณด๋ด๊ธฐ ์ํด ์๋น์ค๊ฐ ๋ฉ์ผ ์๋ฒ์ TCP/IP ์ฐ๊ฒฐ์ ์ค์ ํ๊ณ SMTP ํ๋กํ ์ฝ๋ก ์์ฒญ์ ๋ณด๋ด์ผ ํฉ๋๋ค.
๋ฉ์ผ์ ๋ณด๋ด์ง ๋ชปํ๋ค๋ฉด ํด๋ผ์ด์ธํธ์๊ฒ "๋ฉ์ผ์ ๋ณด๋ด์ง ๋ชปํ์ต๋๋ค" ๋ผ๊ณ ์๋ต์ ๋ณด๋ผ ํ์๊ฐ ์๋ค๊ณ ์๊ฐํ์ต๋๋ค.
๊ทธ๋์, ๋ฉ์ผ ์๋ฒ์ ์๋ต์ ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ๋น๋๊ธฐ๋ก ์ฒ๋ฆฌํ๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค.
๊ทธ๋์, ๋ฉ์ผ ์ ์ก์๋ @Async๋ฅผ ์ฌ์ฉํ์ฌ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ์ ์ฉํ๊ณ , ๋ฉ์ผ ์๋ฒ์ API ์๋ต์ Non-blocking ๋ฐฉ์์ผ๋ก ์ฒ๋ฆฌํ์ฌ ์๋ต ์๋๋ฅผ ๊ฐ์ ํ๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค.
@Async ๊ด๋ จ ๋ด์ฉ์ Baeldung์์ ํ์ตํ์ต๋๋ค.
์ฐ๋ ๋ ํ ์ฌ์ฉ ์ฌ๋ถ ๊ณ ๋ ค
Spring์ @Async๋ ๊ธฐ๋ณธ์ ์ผ๋ก SimpleAsyncTaskExecutor๋ฅผ ์ฌ์ฉํฉ๋๋ค.
์ด๋ ์์ฒญ๋ง๋ค ์๋ก์ด ์ค๋ ๋๋ฅผ ์์ฑํด ์์ ์ ํ ๋นํ๋ฏ๋ก, 10๊ฐ์ ์์ฒญ์ด ๋ค์ด์ค๋ฉด 10๊ฐ์ ์ค๋ ๋๊ฐ ์์ฑ๋ฉ๋๋ค.
ํ์ง๋ง ์๋น์ค ํน์ฑ์ ๋ฉ์ผ ์ ์ก ์์ ์ ์ฃผ๋ก ํ์๊ฐ์ ์์๋ง ๋ฐ์ํ๋ฉฐ, ๋น๋ฒํ๊ฒ ์ผ์ด๋์ง ์์ต๋๋ค.
์ด ๋๋ฌธ์, ์ฐ๋ ๋ ํ์ ๋ง๋ค์ด ์ ํด ์ํ์ ์ค๋ ๋๋ฅผ ๋ฏธ๋ฆฌ ์ ์งํ๋ ๊ฒ์ ์คํ๋ ค ๋ฉ๋ชจ๋ฆฌ ์ค๋ฒํค๋๊ฐ ๋ฐ์ํ ์ ์๋ค๊ณ ํ๋จํ์ต๋๋ค.(์ฐ๋ ๋๋ง๋ค ๊ณ ์ ์ ์คํ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฐจ์งํ๊ธฐ ๋๋ฌธ์ ๋๋ค)
๋ฐ๋ฉด, ์ฐ๋ ๋ ํ์ ์ฌ์ฉํ์ง ์์ผ๋ฉด ์ต์ ์ ๊ฒฝ์ฐ 100๊ฐ์ ์์ฒญ์ด ๋์์ ๋ค์ด์ 100๊ฐ์ ์ค๋ ๋๊ฐ ์์ฑ๋ ์ ์์ต๋๋ค.
์ด๋ ๋ฉ๋ชจ๋ฆฌ ์ค๋ฒํค๋๋ฅผ ์ด๋ํ ๋ฟ๋ง ์๋๋ผ, ์ค๋ ๋ ์๊ฐ ๋ง์์ง์ ๋ฐ๋ผ ๊ณผ๋ํ ์ปจํ ์คํธ ์ค์์นญ์ผ๋ก ์ธํด CPU ์ค๋ฒํค๋๋ ๋ฐ์ํ๊ฒ ๋ฉ๋๋ค.
๋ฐ๋ผ์, ์ต์ ์ ๊ฒฝ์ฐ๋ฅผ ๋๋นํด ๋ฌด๋ฆฌํ๊ฒ ์ค๋ ๋๋ฅผ ์์ฑํ๊ธฐ๋ณด๋ค๋, ์ฐ๋ ๋ ํ์ ์ฌ์ฉํ์ฌ ์ค๋ ๋ ์๋ฅผ ์ ์ ์์ค์ผ๋ก ์ ํํ๋ ๋ฐฉ์์ ์ ํํ์ต๋๋ค.
์ฐ๋ ๋ ํ ์ค์ ๊ณ ๋ ค ์ฌํญ
ํด๋น ๋ถ๋ถ์ ์ฌ์ด์ฝ๋ - ์ฐ๋ ๋ ํ ์์์ ๋ณด๋ฉฐ ์ ๋ฆฌํ์ต๋๋ค.
1. ์ฐ๋ ๋ ํ์ ์ฐ๋ ๋ ๊ฐ์ ์ค์
์ฐ๋ ๋ ํ์์ ์ฌ์ฉํ ์ฐ๋ ๋ ๊ฐ์๋ CPU์ ๊ฐ์์ ์์ (task)์ ์ ํ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋๋ค.
- CPU-bound ์์
- CPU ์ฝ์ด ์์ ๊ฐ๊ฑฐ๋ 1~2๊ฐ ๋ง์ ์ ๋๋ก ์ค์ ํ๋ ๊ฒ์ด ์ผ๋ฐ์ ์ ๋๋ค.
- I/O-bound ์์
- I/O ์์ ์ CPU์ ๋ ์์กดํ๋ฏ๋ก, ์ฝ์ด ์์ 1.5๋ฐฐ, 2๋ฐฐ, ํน์ 3๋ฐฐ ์ ๋๋ก ์ค์ ํด๋ ๋ฌด๋ฐฉํฉ๋๋ค.
- ์ด ์์น๋ ๊ฒฝํ์ ์ผ๋ก ์ต์ ์ ์ฑ๋ฅ์ ์ฐพ๊ธฐ ์ํด ์กฐ์ ํ ์ ์์ต๋๋ค.
2. ์ฐ๋ ๋ ํ์ Queue ์ฌ์ด์ฆ ์ค์
Queue์ ์ฌ์ด์ฆ๊ฐ ๋ฌดํ๋์ธ ๊ฒฝ์ฐ Queue์ ์์ฒญ์ด ์ง์ํด์ ์์ด๊ฒ ๋๋ฉฐ Queue์ ์ฌ์ด์ฆ๊ฐ ๋งค์ฐ ์ปค์ ธ OOME๊ฐ ๋ฐ์ํ๋ ์ ์ฌ ์์ธ์ ๋๋ค.
Queue์ ์ฌ์ด์ฆ์ ์ ํ์ ๋์ด, ํน์ ์์ฒญ์ด ์ด๊ณผ๋๋๋ผ๋ ์๋ฒ ์ ์ฒด์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ง ์๋๋ก ํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
์๋ฐ์ Executors.newFixedThreadPool()๋ ๊ธฐ๋ณธ Queue ํฌ๊ธฐ๋ Integer.MAX_VALUE(์ฝ 20์ต)๋ก, ์ ํ ์์ด ์์ฒญ์ด ๋์ ๋ ์ ์์ด ๋ฉ๋ชจ๋ฆฌ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค.
์ฐ๋ ๋ ํ ์ค์
์ด์ 2๊ฐ์ง ๊ณ ๋ ค์ฌํญ์ ๋ฐํ์ผ๋ก ์ด๋ฉ์ผ ์ ์ก ์์ ์ ์ํ ์ฐ๋ ๋ ํ์ ์ค์ ํด๋ณด๊ฒ ์ต๋๋ค.
1. ์ฐ๋ ๋ ๊ฐ์ ์ค์
linux์ lscpu ๋ช ๋ น์ด๋ฅผ ์ฌ์ฉํด CPU ์ํคํ ์ฒ๋ฅผ ํ์ธํ์ต๋๋ค.
Socket(s): 1
- ๋ฌผ๋ฆฌ์ ์ธ CPU ๊ฐ์๊ฐ 1๊ฐ์ ๋๋ค.
Core(s) per socket: 8
- ๋ฌผ๋ฆฌ์ ์ธ CPU 1๊ฐ์ 8๊ฐ์ ์ฝ์ด๊ฐ ์์ต๋๋ค.
Thread(s) per core: 2
- ์ฝ์ด 1๊ฐ๋น 2๊ฐ์ ์ฐ๋ ๋๋ฅผ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
CPU(s): 16
- ๋ ผ๋ฆฌ์ ์ธ CPU ๊ฐ์๊ฐ 16๊ฐ์ ๋๋ค.
- 1๊ฐ์ CPU๊ฐ 8๊ฐ์ ์ฝ์ด๋ฅผ ๊ฐ์ง๊ณ ์๊ณ , ๊ฐ๊ฐ์ ์ฝ์ด๊ฐ 2๊ฐ์ ์ฐ๋ ๋๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค.
๊ทธ๋์, I/O-bound ์์ ์ธ ๋ฉ์ผ ์ ์ก ์์ ์ ์ํด ์ฐ๋ ๋ ํ์ ์ต๋ ์ฐ๋ ๋ ์๋ ๋ ผ๋ฆฌ CPU ๊ฐ์์ธ 16์ผ๋ก, ๊ธฐ๋ณธ ์ฐ๋ ๋ ์๋ 8๊ฐ์ ์ฝ์ด ์ 1.5๋ฐฐ์ธ 12๋ก ์ค์ ํ์ต๋๋ค.
2. Queue์ฌ์ด์ฆ ์ ํํ๊ธฐ
Spring ์ ์ฐ๋ ๋ํ์ธ ThreadPoolTaskExecutor ๋ฅผ ์ฌ์ฉํ๊ฒ ์ต๋๋ค.
ํด๋น ์ฝ๋๋ฅผ ๊น๋ณด๋ฉด Queue ์ฌ์ด์ฆ๊ฐ ์ ํ์ด ์์ผ๋ฏ๋ก(int queueCapacity = Integer.MAX_VALUE), Queue ์ฌ์ด์ฆ๋ฅผ ์ ํด์ผ ํฉ๋๋ค.
์ด๋ฉ์ผ ์ธ์ฆ ๋ณด๋ด๋ ์์ ์ด ๋์์ ๋ง์ง ์๋ค๊ณ ์๊ฐํด์ ์์์ ์ซ์์ธ 50์ผ๋ก ์ ํ์ต๋๋ค.
์ฐ๋ ๋ ํ ์ค์ ์ ์ฒด ์ฝ๋์ ๋๋ค.
@EnableAsync
@Configuration
public class MailConfig implements AsyncConfigurer {
@Override
@Bean
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(12); // ๊ธฐ๋ณธ ์ฐ๋ ๋ ๊ฐ์
executor.setMaxPoolSize(16); // ์ต๋ ์ฐ๋ ๋ ํ ๊ฐ์
executor.setQueueCapacity(50); // ์ต๋ Queue Size
executor.setThreadNamePrefix("MailExecutor-"); // ์ฐ๋ ๋ ํ์ ์ฐ๋ ๋ ์ด๋ฆ
executor.initialize(); // custom ํ ์ค์ ๋ค์ ์ฐ๋ ๋ ํ์ ๋ฐ์
return executor;
}
}
ThreadPoolTaskExecutor ๋์ ๋ฐฉ์
์คํ๋ง์ด ์ง์ํ๋ ThreadPool ์ธ ThreadPoolTaskExecutor ๋ ์ด๋ป๊ฒ ์๋์๋ฆฌ์ ๋ํด ์์๋ด ๋๋ค.
ํด๋น ๋ธ๋ก๊ทธ๋ ThreadPoolExecutor ๋์ ๋ฐฉ์ ๋ฐ ์ฃผ์ ์ฌํญ ์์ ์ค๋ช ํ์ง๋ง Spring ์ ThreadPoolTaskExecutor ์ ๋ด๋ถ ๊ตฌํ์ผ๋ก Java์ ThreadPoolExecutor ์ ์ฌ์ฉํ๋ฉฐ, ๋จ์ง Spring ์ ์ฌ์ฉํ๊ธฐ ์ฝ๋๋ก ์ถ์ํ๋ ๊ฒ์ผ๋ก ์๋ ๋ฉ์ปค๋์ฆ์ ๋์ผํฉ๋๋ค.
(์ถ์ฒ : Difference and suggest ThreadPoolTaskExecutor and ThreadPoolExecutor)
ThreadPoolExecutor์ ์๋ ๋ฉ์ปค๋์ฆ์ ์์ฝํ๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค
- ๊ธฐ๋ณธ ์ค๋ ๋ ์์ฑ: setCorePoolSize(12)๋ก ์ค์ ๋ ๊ธฐ๋ณธ ์ค๋ ๋ ์(12๊ฐ)๋งํผ ์ค๋ ๋๊ฐ ์์ฑ๋ฉ๋๋ค.
- ํ์ ์์ ์ถ๊ฐ: ๋ง์ฝ ๋์์ 12๊ฐ ์ด์์ ์์ฒญ์ด ๋ค์ด์ค๋ฉด, ์ถ๊ฐ ์์ ์ ๋๊ธฐ์ด(Queue)์ ์ ์ฅ๋ฉ๋๋ค.
- ์ค๋ ๋ ํ ํ์ฅ: ๋๊ธฐ์ด์ด ๊ฐ๋ ์ฐจ๋ฉด, setMaxPoolSize()๋ก ์ค์ ๋ ์ต๋ ์ค๋ ๋ ์๊น์ง ์ค๋ ๋ ํ์ ํ์ฅํ์ฌ ์ถ๊ฐ ์์ฒญ์ ์ฒ๋ฆฌํฉ๋๋ค.
- ์ ํด ์ค๋ ๋ ์ ๊ฑฐ: ์ต๋ ์ค๋ ๋ ์๋งํผ ์ค๋ ๋๊ฐ ์์ฑ๋์๋ค๊ฐ ์ ํด ์ํ๊ฐ ๋๋ฉด, 60์ด(๊ธฐ๋ณธ ์ค์ ) ํ์ ์ ํด ์ค๋ ๋๊ฐ ์ ์ฐจ ์ ๊ฑฐ๋์ด, ์ค๋ ๋ ํ์ setCorePoolSize()๋ก ์ค์ ๋ ๊ธฐ๋ณธ ์ค๋ ๋ ์๋ก ๋์๊ฐ๋๋ค.
- ์์ ๊ฑฐ๋ถ: ๋๊ธฐ์ด์ด ๊ฐ๋ ์ฐจ๊ณ ์ค๋ ๋ ์๊ฐ MaxPoolSize์ ๋๋ฌํ ํ์๋ ์๋ก์ด ์์ฒญ์ด ๋ค์ด์ค๋ฉด RejectedExecutionException ์์ธ๊ฐ ๋ฐ์ํ๋ฉฐ ํด๋น ์์ ์ ๊ฑฐ์ ๋ฉ๋๋ค.
RejectedExecutionException ์ ๋ํ ์์ธ ์ฒ๋ฆฌ๋ ๋ฉ์ผ ๋ณด๋ด๋ ๊ธฐ๋ฅ์ ์ค์ํ์ง ์๋ค๊ณ ์๊ฐํ์ฌ ์ฒ๋ฆฌํ์ง ์๊ณ , ๋ค ์ด์ด ์๊ฐํ AsyncUncaughtExceptionHandler ๋ฅผ ์ฌ์ฉํด์ ๋ก๊ทธ๋ง ๋จ๊ธฐ๋๋ก ํ์ต๋๋ค.
์ฐ๋ ๋ ํ ์ค๋ฅ ์ฒ๋ฆฌ ์ค์
@Async(๋น๋๊ธฐ)๋ก ์ฒ๋ฆฌ๋๋ ๋ฉ์๋์์ ๋ฐ์ํ ์ ์๋ ์ค๋ฅ๋ ์ด๋ป๊ฒ ์ฒ๋ฆฌํ ๊น์?
Baeldung์ ๋ฐ๋ฅด๋ฉด, ๋น๋๊ธฐ ๋ฉ์๋์ ๋ฐํ ํ์ ์ด Future์ธ ๊ฒฝ์ฐ Future.get()์ ํตํด ๋ฐํ์ ์์ธ๋ฅผ ์ก์ ํธ๋ค๋งํ ์ ์์ต๋๋ค. ํ์ง๋ง, ๋น๋๊ธฐ ๋ฉ์๋๊ฐ void ๋ฐํ ํ์ ์ธ ๊ฒฝ์ฐ์๋ ๋ฐํ์ ์์ธ๊ฐ ๋ฌด์๋ฉ๋๋ค.
์ ์ ๋น๋๊ธฐ๊ฐ ์ ์ฉ๋ ๋ฉ์๋๋ void ๋ฐํํ์ ์ด๊ธฐ ๋๋ฌธ์, ๋น๋๊ธฐ ์ฒ๋ฆฌ ์ค ์์ธ๊ฐ ๋ฐ์ํ ๋ ์ด๋ฅผ ์ธ์งํ ์ ์๋๋ก AsyncUncaughtExceptionHandler ๋ฉ์๋๋ฅผ ์ค๋ฒ๋ผ์ด๋ํ์ฌ log.error๋ก ์์ธ๋ฅผ ๊ธฐ๋กํ๋ ๋ฐฉ์์ผ๋ก ์์ธ๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค.
์ค๋ฒ๋ผ์ด๋ฉ์ ํ์ง ์์ผ๋ฉด, ์๋์ ๊ฐ์ ๋ค์ํ ์์ธ๊ฐ ๋ฐ์ํ ์ ์์ผ๋ฉฐ ์ด๋ฌํ ์์ธ๋ AsyncUncaughtExceptionHandler๋ฅผ ํตํด ๊ด๋ฆฌํ ์ ์์ต๋๋ค.
org.springframework.mail.MailSendException: Mail server connection failed. Failed messages: jakarta.mail.MessagingException: Could not connect to SMTP host: smtp.naver.com, port: 465;
Caused by: jakarta.mail.MessagingException: Could not connect to SMTP host: smtp.naver.com, port: 465
Caused by: javax.net.ssl.SSLHandshakeException: Remote host terminated the handshake
Caused by: java.io.EOFException: SSL peer shut down incorrectly
AsyncUncaughtExceptionHandler ๋ฅผ ์ค๋ฒ๋ผ์ด๋ฉํฉ๋๋ค.
@EnableAsync
@Configuration
public class MailConfig implements AsyncConfigurer {
...์ฐ๋ ๋ํ ์ค์ ...
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return (ex, method, params) -> log.error("[๋ฉ์ผ ์ฐ๋ ๋ ํ ์๋ฌ] ๋ฐ์ ์์น={}", method.toGenericString());
}
}
Jmeter ๋ก @Async ๋์ ์ ์ฉ ์ ๊ณผ ํ์ API ์๋ต ์๊ฐ์ ๋น๊ต
์ด์ , Jmeter ๋ก ๋น๋๊ธฐ๋ก ์ฒ๋ฆฌ ๋์ ๋์, ์ด๋ฉ์ผ์ ๋ณด๋ด๋ API ๋ฅผ ํธ์ถํ๋ฉฐ ์ฑ๊ณต์ ์ธ์ง ์์๋ณด๊ฒ ์ต๋๋ค.
๋๊ธฐ ๋ฐฉ์
- ์ฐ๋ ๋ ํ์ ํฌ๊ธฐ์ ๋ง์ถฐ 12๊ฐ์ ์์ฒญ(Request)์ ๋ณด๋ธ ๊ฒฐ๊ณผ, ํ๊ท ์๋ต ์๊ฐ์ 0.7์ด, ์ต๋ ์๋ต ์๊ฐ์ 1.4์ด์์ผ๋ฉฐ, ์ด๋น ์ฒ๋ฆฌ๋(TPS)์ 6์ผ๋ก ์ธก์ ๋์์ต๋๋ค
๋น๋๊ธฐ ๋ฐฉ์
- ๋์ผํ ์์ฒญ ์์์ ํ๊ท ์๋ต ์๊ฐ์ด 0.007์ด, ์ต๋ ์๋ต ์๊ฐ์ด 0.01์ด๋ก ์ค์์ผ๋ฉฐ, ์ด๋น ์ฒ๋ฆฌ๋(TPS)์ 13์ผ๋ก ์ฆ๊ฐํ์ต๋๋ค
์ด ๊ฒฐ๊ณผ๋ก, ๋น๋๊ธฐ ๋ฐฉ์์ผ๋ก ์ ํํจ์ผ๋ก์จ ํ๊ท ์๋ต ์๊ฐ์ด ์ฝ 99% ๊ฐ์ํ์ผ๋ฉฐ, ์ต๋ ์๋ต ์๊ฐ ์ญ์ 99% ์ด์ ๋จ์ถ๋์์ต๋๋ค.
@Async ์ฌ์ฉ ์ ์ฃผ์์
1. ์ฐ๋ ๋ ํ์ ์ฐ๋ ๋ ๊ฐ์์ Queue ์ฌ์ด์ฆ ์ค์ ํ๊ธฐ
2. @Async ๋ Spring ์ด๋ ธํ ์ด์ ์ผ๋ก Spring AOP ํ๋ก์ ๊ธฐ๋ฐ์ผ๋ก ์๋ํ๊ธฐ ๋๋ฌธ์, AOP ์ฌ์ฉ ์ ์ฃผ์์ ์ธ self-invocation(์๊ธฐ ํธ์ถ) ๊ณผ private ๋ฉ์๋์ผ ๋, ์ ์ฉ๋์ง ์์ต๋๋ค.
....
youtube ๋ฅผ ๋ณด๋ฉฐ ์ฌ๋ฐ์๋ ์ฐ๋ ๋ ํ ์ฌ์ง์ผ๋ก ๋ง๋ฌด๋ฆฌํ๊ฒ ์ต๋๋ค.
์ถ์ฒ