Spring (11) ์ธ๋ค์ผํ ๋ฆฌ์คํธํ RestTemplate ํ์ฅํด์ GET ์์ฒญ์๋ body ๋ฃ๊ธฐ Spring์ RestTemplate์ ๊ธฐ๋ณธ์ ์ผ๋ก GET ์์ฒญ์ Body๋ฅผ ๋ด์๋ ์ ์กํ์ง ์์ต๋๋ค.์ด๋ฒ ๊ธ์์๋ RestTemplate์ ํ์ฅํ์ฌ GET ์์ฒญ ์ Body๋ฅผ ํฌํจํ ์ ์๋๋ก ํ๋ ๋ฐฉ๋ฒ์ ์๊ฐํฉ๋๋ค. ์์๋ RestTemplate์ผ๋ก OpenSearch์ GET _search API๋ฅผ ํธ์ถํ๊ณ , ์๋ต์ ๋ฐ๋ ๊ณผ์ ์ ๋ค๋ฃน๋๋ค.ํ์ฅ ์ ·ํ์ Search API๋ก๋ถํฐ ์ด๋ค ์๋ต์ด ์ค๋์ง๋ฅผ ๋ก๊ทธ ๋น๊ต๋ฅผ ํตํด ํ์ธํด ๋ณด๊ฒ ์ต๋๋ค. OpenSearch์ Search API๋ ์ฟผ๋ฆฌ๊ฐ ๊ธธ์ด์ง ์ ์์ด, REST ๊ท์ฝ์ ์ด๊ธ๋๋๋ผ๋ GET ์์ฒญ์ Body๋ฅผ ํ์ฉํฉ๋๋ค.๋ค๋ง ๋ช ์ธ์ GET /{index_name}/_search๋ฅผ ์ฌ์ฉํ์ง๋ง, POST ์์ฒญ๋ ์ง์ํฉ๋๋ค. ์ ๋ ์ฒ์์ ๋ช ์ธ๋๋ก GET ์์ฒญ์.. Spring AOP ๋ก ์ฌ์ฉ์๊ฐ ๊ฐ์ง ๊ถํ์ ๋ฐ๋ผ ํน์ ๋ฉ๋ด(๊ธฐ๋ฅ) ์ ์ ์ ํํ๊ธฐ ์ฌ๋ด ์ด๋๋ฏผ์ ๊ฐ๋ฐํ๋ ์ค, ๋ค์๊ณผ ๊ฐ์ ์๊ตฌ์ฌํญ์ด ์๊ฒผ์ต๋๋ค."์ฌ์ฉ์๊ฐ ๊ฐ์ง๊ณ ์๋ ๊ถํ ์ธ์ ๋ฉ๋ด(๊ธฐ๋ฅ)์ ์ ๊ทผํ ์ ์๋๋ก ์ ํํด๋ฌ๋ผ." ์ด ์๊ตฌ์ฌํญ์ AWS์ IAM ๊ธฐ๋ฅ๋งํผ ๋ณต์กํ์ง ์์ง๋ง, ๋งฅ๋ฝ์ ๋น์ทํด์ IAM ๊ฐ๋ ์ ๋น๋ ค ์๊ตฌ์ฌํญ์ ์ค๋ช ๋๋ฆฌ๊ณ ์ ํฉ๋๋ค. IAM์ ๊ตฌ์ฑ์์์ ์ ๊ทผ ์ ์ด ๋ฐฉ์IAM์ ๊ตฌ์ฑ ์์ ์ค ๊ธ์ ์ค๋ช ํ๋๋ฐ ํ์ํ ๊ฐ๋ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. ์ฌ์ฉ์ (User)AWS ๋ฆฌ์์ค์ ๋ก๊ทธ์ธํ๊ฑฐ๋ API๋ฅผ ํธ์ถํ๋ ์ฃผ์ฒด๋ก, ์ค์ ์ฌ๋๊ณผ 1:1 ๋งคํ๋ฉ๋๋ค.์ญํ (Role)AWS์ IAM์ ์ญํ ์ ์ผ์์ ์ธ ๊ถํ ์์์ ์ํด ์กด์ฌํ๋ ์๊ฒฉ์ ๋๋ค. ์ฆ, "์ฌ์ฉ์๊ฐ ์ญํ ์ ๊ฐ๋ ๊ฒ"์ด ์๋๋ผ, ์ฌ์ฉ์๋ AWS ์๋น์ค๊ฐ ํ์ํ ๋ ์ญํ ์ ๋งก์์(๊ฐ์ ํด์, Assume), ์ญํ ์ ์ฐ๊ฒฐ๋ ์ ์ฑ ๊ถ.. MultipartFile ์ transferTo ์ดํ getBytes ํธ์ถ ์ NoSuchFileException ๋ฐ์ ์์ธ ์๊ฐ ์๋ก MultipartFile ๊ฐ์ฒด๋ฅผ ๋์คํฌ์ ์ ์ฅํ๊ณ , ํด๋น ํ์ผ์ ์๋ฒ ๋ฉํ๊ธฐ ์ํด FastAPI๋ก ๋ฐ์ด๋๋ฆฌ ๋ฐ์ดํฐ๋ฅผ ์ ์กํด์ผ ํ๋ ์๊ตฌ์ฌํญ์ ๊ตฌํ ์ค์ด์์ต๋๋ค.ํ์ผ์ ๋์คํฌ์ ์ ์ฅํ๊ธฐ ์ํด transferTo() ๋ฅผ ์ฌ์ฉํ๊ณ , getBytes() ๋ฅผ ํตํด ๋ฐ์ด๋๋ฆฌ ๋ฐ์ดํฐ๋ฅผ ์ป์ผ๋ ค ํ์ง๋ง, ํ์ผ์ ์ฐพ์ ์ ์๋ค๋ NoSuchFileException ์ด ๋ฐ์ํ์ต๋๋ค.Caused by: java.nio.file.NoSuchFileException: C:\Users\...\Local\Temp\tomcat.28080.5183490430648900766 ๊ฐ์ MultipartFile ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ์ง๋ง ํ์ผ์ ์ฐพ์ ์ ์๋ค๋ ๊ฒ์ด ์ดํด๊ฐ ๊ฐ์ง ์์์ต๋๋ค.๊ฒฐ๋ก MultipartFile์ spring.servlet.mu.. OpenFeign ์์ ISO-8601 ๋ ์ง ํฌ๋งท์ ์ํด FeignFormatterRegistrar ๋ฅผ ๋ฑ๋กํ๋ ์ด์ ๊ฐ์OpenFeign์ ์ฌ์ฉํด admin ์๋ฒ์ core ์๋ฒ ๊ฐ์ HTTP ํต์ ์ ํ๋ ์ค, ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค.admin ์๋ฒ์์ LocalDate ํ์ ์ yyyy-MM-dd ํฌ๋งท์ผ๋ก ์์ฒญ์ ๋ณด๋์ต๋๋ค.๊ทธ๋ฌ๋ core ์๋ฒ์์๋ LocalDate ํฌ๋งท์ด yyyy-MM-dd ๋ฅผ ๊ธฐ๋ํ์ง๋ง, yy. M. d. ์ผ๋ก ์์ ํฌ๋งท ๋ณํ์ ์คํจํ๋ ์๋ฌ ๋ก๊ทธ๊ฐ ๋ฐ์ํ์ต๋๋ค.์ด ๋ฌธ์ ๋ ์ฐ์ํํ์ ๋ค ๊ธฐ์ ๋ธ๋ก๊ทธ์์ ์ ์ํ ๋ฐฉ์์ผ๋ก ๊ฐ๋จํ ํด๊ฒฐํ ์ ์์ต๋๋ค:@Beanpublic FeignFormatterRegistrar localDateFeignFormatterRegister() { return registry -> { DateTimeFormatterRegistrar registrar = new .. ํธ๋์ญ์ ๋กค๋ฐฑ ์ ๊ฒฐ์ ์ทจ์ ์์ฒญํ๊ธฐ - @TransactionalEventListener & ApplicationEventPublisher ๋ชจํน ์ด์ ์ฌ์ด๋ ํ๋ก์ ํธ์์ ๊ฒฐ์ ํ๋ก์ธ์ค๋ฅผ ์ค๊ณํ๋ฉด์, ๊ธฐ์กด์๋ try-catch๋ฅผ ํ์ฉํด ํธ๋์ญ์ ๋ด๋ถ์์ ๋ฐ์ํ๋ ๋ฐํ์ ์์ธ๋ฅผ ์ฒ๋ฆฌํ๊ณ , ๊ฒฐ์ ์ทจ์ ์์ฒญ์ ๋ณด๋์ต๋๋ค. ๊ทธ๋ฌ๋, ์ด์ ๋ํ ํ๊ณ๋ฅผ ๋๊ผ๊ณ ํธ๋์ญ์ ๋กค๋ฐฑ ์ ๊ฒฐ์ ์ทจ์ ์์ฒญ์ ๋ช ํํ๊ณ ์ง๊ด์ ์ผ๋ก ์ฒ๋ฆฌํ๊ธฐ ์ํด @TransactionalEventListener๋ฅผ ๋์ ํ์ต๋๋ค. ๊ธฐ์กด try-catch ๋ฐฉ์์ ํ๊ณ try-catch์์๋ ์ฃผ๋ก DB ์์ธ(์: DataIntegrityViolationException)๋ ๋น์ฆ๋์ค ๋ก์ง์์ ๋ฐ์ํ๋ ์์ธ๋ฅผ ์ฒ๋ฆฌํ๊ณ , ๊ฒฐ์ ์ทจ์ ์์ฒญ์ ๋ณด๋์ต๋๋ค. ํ์ง๋ง, try-catch๋ฅผ ์ฌ์ฉํ๋ฉด ์์ธ๋ฅผ ์ ์์ ์ธ ํ๋ฆ์ผ๋ก ์ ์ดํ๋ ๊ฒ์ฒ๋ผ ๋ณด์ด๊ฒ ๋ฉ๋๋ค. ์ด๋ "ํธ๋์ญ์ ์ด ๋กค๋ฐฑ๋์์ ๋ ๊ฒฐ์ ์ทจ์๋ฅผ ์ํํ๋ค"๋ผ๋ ์.. [ํธ๋ฌ๋ธ์ํ ] RestTemplate ๋ก๊น ์ค 404 ์๋ต์ ๋ํ FileNotFoundException ํด๊ฒฐ ๊ฒฐ์ ์น์ธ POST ์์ฒญ ์ RestTemplate ๋ก๊ทธ์์ ๋ฐ์ํ ์ค๋ฅ ๊ฒฐ์ ๊ธฐ๋ฅ์ ๊ฐ๋ฐํ๋ฉด์, ๊ฒฐ์ ์น์ธ ์์ฒญ์ ๋ณด๋ด๋ RestTemplate์ ํ์์์์ ์ ์ฉํ๊ณ , ์์ฒญ๊ณผ ์๋ต์ ๋ํ ๋ก๊น ์ ์ถ๊ฐํ๊ณ ์ ํ์ต๋๋ค. Baeldung์ "RestTemplage Logging" ๊ณผ ๋ง๋๋ ๊ฐ๋ฐ์๋์ ๋ก๊น ์ ์ฐธ๊ณ ํด์ RestTemplate ์ ๋ก๊ทธ๋ฅผ ์ถ๊ฐ ํ์ง๋ง ์๋ต์ ๋ฐ์ ๋, FileNotFoundException ์ด ๋ฐ์ํ๋ฉฐ ์๋์ ๊ฐ์ ์คํ ํธ๋ ์ด์ค๋ฅผ ํ์ธํ์ต๋๋ค.java.io.FileNotFoundException: https://api.tosspayments.com/v1/payments/confirmjava.base/sun.net.www.protocol.http.HttpURLConnection.. @Async ์ด๋ฉ์ผ ์ ์ก ๊ณ ๋ํ: ์ฌ์๋, ์์ธ ์ฒ๋ฆฌ, ํ ์คํธ ์ธ์ฆ ์ด๋ฉ์ผ ์ ์ก ์, ๊ฐํน ๋คํธ์ํฌ ์ค๋ฅ๋ก ์ธํด ๋ฉ์ผ์ด ์ ์์ ์ผ๋ก ์ ์ก๋์ง ์๋ ๊ฒฝ์ฐ๊ฐ ๋ฐ์ํฉ๋๋ค.์ด๋ฌํ ์ํฉ์์ ์ฌ์ฉ์์๊ฒ ์ฆ์ ์ค๋ฅ๋ฅผ ์๋ฆฌ๋ ๋์ , ์ฌ์๋ ๋ก์ง์ ํตํด ์ด๋ฉ์ผ ์ ์ก ์ฑ๊ณต ๊ฐ๋ฅ์ฑ์ ๋์ด๋ ๊ฒ์ด ์ฌ์ฉ์ ๊ฒฝํ์ ํฅ์ํ๋ ์ค์ํ ์์๋ผ๊ณ ํ๋จํ์ต๋๋ค. ๊ทธ๋์, ์ฌ์๋ ์ถ๊ฐ ์ ๊ณ ๋ คํ ๊ฒ๋ค์ ๋ค์๊ณผ ๊ฐ์ ๋ชฉ์ฐจ๋ก ์๊ฐํฉ๋๋ค.์ฌ์๋(@Retryable) ์กฐ๊ฑด ์ค์ ์ฌ์๋ ์์ธ์ ์ฐ๋ ๋ ํ ์์ธ๋ฅผ ๊ตฌ๋ถํด์ ์ฒ๋ฆฌํ๊ธฐ์ฌ์๋ ๋ฐ ๋ณต๊ตฌ๊ฐ ์ ๋์๋์ง ํ ์คํธํ๊ธฐ* ๋น๋๊ธฐ์์ ์ฌ์๋ ๋ก์ง ๊ตฌํ์ ์ํด Baeldung(async-retry)๋ฅผ ์ฐธ๊ณ ํ์ต๋๋ค. ์ฌ์๋(@Retryable) ์กฐ๊ฑด ์ค์ ๋จผ์ , ์ด๋ฉ์ผ ์ ์ก์ ์ฌ์๋ ์กฐ๊ฑด์ ์ค์ ํ๊ธฐ ์ํด Spring Mail ๊ด๋ จ ์์ธ๋ฅผ ์๊ฐํฉ๋๋ค.MailAuthentic.. ์ด๋ฉ์ผ ์ ์ก์ Async-NonBlocking ์ฒ๋ฆฌํ๊ธฐ: ์ฐ๋ ๋ ํ ์ค์ ๊ณผ API ์ต๋ ์๋ต ์๋ 1.4์ด → 0.01์ด @Async ๋ฅผ ๋์ ํ๋ฉฐ ์ปจํ ์คํธ ์ค์์นญ๊ณผ ์ฐ๋ ๋ ๋ฉ๋ชจ๋ฆฌ ๊ตฌ์กฐ ์ง์์ ๋ฐํ์ผ๋ก ์ฐ๋ ๋ ํ ์ค์ ์ ํ์ตํ๊ณ ์ ์ฉํ๋ ๊ณผ์ ์ ์๊ฐํ๋ฉฐ Jmeter ๋ฅผ ํตํด API ์๋ต ์๋๊ฐ ๊ฐ์ ๋์๋์ง ํ์ธํ๋ ๊ณผ์ ์ ๋ค์๊ณผ ๊ฐ์ ๋ชฉ์ฐจ๋ก ์๊ฐํฉ๋๋ค.์ด๋ฉ์ผ ์ ์ก์ ๋น๋๊ธฐ๋ก ๊ฒฐ์ ํ ์ด์ ์ฐ๋ ๋ ํ ์ฌ์ฉ ์ฌ๋ถ ๊ณ ๋ ค์ฐ๋ ๋ ํ ์ค์ ๊ณ ๋ ค ์ฌํญ์ฐ๋ ๋ ํ ์ค์ ThreadPoolTaskExecutor ๋์ ๋ฐฉ์์ฐ๋ ๋ ํ ์ค๋ฅ ์ฒ๋ฆฌ ์ค์ Jmeter ๋ก @Async ๋์ ์ ์ฉ ์ ๊ณผ ํ์ API ์๋ต ์๊ฐ์ ๋น๊ต@Async ์ฌ์ฉ ์ ์ฃผ์์ ์ด๋ฉ์ผ ์ ์ก์ ๋น๋๊ธฐ๋ก ๊ฒฐ์ ํ ์ด์ ์์ด๋น์ค๋น ํด๋ก ํ๋ก์ ํธ์์๋ ์ด๋ฉ์ผ ์ธ์ฆ ๊ธฐ๋ฐ์ ํ์๊ฐ์ /๋ก๊ทธ์ธ์ ์งํํ๊ณ ์์ต๋๋ค. ์ด๋ฉ์ผ ์ ์ก์๋ Spring Mail์ JavaMailSender๋ฅผ ์ฌ์ฉํ๊ณ ์์ผ๋ฉฐ.. ์ด์ 1 2 ๋ค์