์ ์ฒด ๊ธ (46) ์ธ๋ค์ผํ ๋ฆฌ์คํธํ OpenFeign์ INFO ๋ ๋ฒจ ๋ก๊ทธ ์ถ๊ฐํ๊ธฐ (2/2): ๋ก๊ทธ ์ค์ ๊ณผ Configuration ๊ณ ๋ฏผ ์ ๋ฒ ๊ธ์์๋ WireMock์ ํ์ฉํด Clova AI(์ธ๋ถ) ์๋ฒ๋ฅผ ๋ชจํนํ๋ ๋ฐฉ๋ฒ์ ๋ค๋ค์ต๋๋ค. ์ด๋ฅผ ํตํด Clova ์๋ฒ๋ฅผ ํธ์ถํ์ง ์์์ผ๋ก์จ ๋น์ฉ ๋ฐ์ ์์ด, @FeignClient ์ logger-level: FULL ์ค์ ์ด ์ ์ ์ฉ ๋์๋์ง๋ฅผ ํ์ธํ๋ ๊ณผ์ ์ ์ดํด๋ดค์ต๋๋ค. ์ด๋ฒ ๊ธ์์๋ INFO ๋ ๋ฒจ์์ Feign ๋ก๊ทธ๋ฅผ ์ถ๋ ฅํ๋๋ก ์ปค์คํฐ๋ง์ด์งํ๋ ๋ฐฉ๋ฒ์ ์๊ฐํ๋ ค ํ์ง๋ง, ์ด๋ฏธ ์ด๋ฅผ ๋ค๋ฃฌ ์ข์ ๊ธ๋ค์ด ๋ง์ ํด๋น ์ฃผ์ ๋ฅผ ๊ฐ๋จํ ๋์ด๊ฐ๊ณ , OpenFeign์ @Configuration ์ค๊ณ ๊ณผ์ ์์ ๊ณ ๋ฏผํ๋ ์ ์ ๊ณต์ ํ๊ณ ์ ํฉ๋๋ค. Feign ์ปค์คํฐ๋ง์ด์ง ๊ด๋ จ ์ข์ ๊ธ ์ฐ์ํ feign ์ ์ฉ๊ธฐ๋ง๋๋ ๊ฐ๋ฐ์๋์ OpenFeign ์ค๋ช ๊ณผ Github (tistory) FeignClient Log.. OpenFeign์ INFO ๋ ๋ฒจ ๋ก๊ทธ ์ถ๊ฐํ๊ธฐ (1/2): WireMock์ ํ์ฉํ ์ธ๋ถ ์๋ฒ ๋ชจํน ** ์ด๋ฒ ๊ธ์์๋ ํ ์คํธ์์ WireMock์ ํ์ฉํ์ฌ ์ธ๋ถ ์๋ฒ๋ฅผ ๋ชจํนํ๋ ๊ณผ์ ์ ์ค๋ช ํ๋ฉฐ, ๋ค์ ๊ธ์์๋ INFO ๋ ๋ฒจ ๋ก๊ทธ ์ค์ ๋ฐฉ๋ฒ์ ๋ค๋ฃฐ ์์ ์ ๋๋ค. ** Clova AI์ ๋ฐ๋ณต์ ์ธ ์๋ต ์ค๋ฅ ๋ฌธ์ ๊ณ ๋ฏผ ์๋ด ํ๋ซํผ ํ๋ก์ ํธ๋ฅผ ์งํํ๋ฉฐ ๋ค์ด๋ฒ Clova AI์ ์์ฒญ์ ๋ณด๋ด๋ ์์ ์ ์ํํ์ต๋๋ค. ํ์ง๋ง Clova AI๋ก๋ถํฐ ์ค๋ ์๋ต์ด ๋น์ฆ๋์ค ์๊ตฌ์ฌํญ์ ๋ง์ง ์์ ๋น๋ฒํ๊ฒ ์ค๋ฅ๋ฅผ ๋ฐ์์์ผฐ์ต๋๋ค. ์ด์ ๋ฐ๋ผ, Clova AI ๊ฐ ์ด๋ค ์๋ต์ ์ฃผ๊ณ , ์ด๋ค ์ค๋ฅ๋ฅผ ์ ๋ฐํ๋์ง ์ ํํ ํ์ธํ ํ์๊ฐ ์์์ต๋๋ค.์ด ๊ณผ์ ์์ OpenFeign์ ๋ก๊น ๊ธฐ๋ฅ์ ํ์ฉํ๋ ค ํ์ง๋ง, ๊ธฐ์กด ๋ฐฉ์์ผ๋ก๋ ๋ช ๊ฐ์ง ๋ถํธํจ์ด ์์์ต๋๋ค. logger-level : FULL ์ ์ฌ์ฉํ์ง ์๋ ์ด์ 1. ์ค์ ์ด์ ์๋ฒ์์ F.. Github Actions ์ผ๋ก CI ํ ์คํธ ์๋ํ ์ค ๊ฒช์ ์ด์ ์ ๋ฆฌ (Embedded Redis, Profile, Spring Rest Docs) 210๊ฐ์ ํ ์คํธ ์ฝ๋์ 99% ํ ์คํธ ์ปค๋ฒ๋ฆฌ์ง์์ ์์ฝ ํ๋ซํผ์ ๊ฐ๋ฐํ๋ฉฐ ์ด 210์ฌ ๊ฐ์ ํ ์คํธ ์ฝ๋๋ฅผ ์์ฑํ๊ณ , 99% ํ ์คํธ ์ปค๋ฒ๋ฆฌ์ง๋ฅผ ๋ฌ์ฑํ์ต๋๋ค. ํ์ง๋ง ์ฝ๋์ ๋ณ๊ฒฝ ์ฌํญ์ด ์์ ๋๋ง๋ค ์ ์ฒด ํ ์คํธ๋ฅผ ์๋์ผ๋ก ์คํํด์ผ ํ๊ณ , ์ด๋ ์ ์ ๋ถํธํ ์์ ์ด ๋์์ต๋๋ค. ๊ทธ๋์ CI/CD ํด์ธ GitHub Actions๋ฅผ ๋์ ํ์ฌ push ๋๋ pull_request๊ฐ ๋ฐ์ํ ๋ ์๋์ผ๋ก ํ ์คํธ๊ฐ ์คํ๋๋๋ก ์ค์ ํ์ต๋๋ค. GitHub Actions๋ฅผ ์ ํํ ์ด์ GitHub Actions๋ฅผ ์ ํํ ์ด์ ๋ ๋จ์ํฉ๋๋ค.Jenkins์ฒ๋ผ ๋ณ๋์ ์๋ฒ๋ฅผ ๊ตฌ์ถํ ํ์๊ฐ ์์ผ๋ฉฐ,๋จ์ํ .github/workflows ๋๋ ํ ๋ฆฌ์ YAML ํ์ผ๋ง ์์ฑํ๋ฉด ๋ฐ๋ก ๋์ํ๊ธฐ ๋๋ฌธ์ ๋๋ค.๋ํ Groovy์ ๊ฐ์ ์๋ก์ด ๋ฌธ๋ฒ์.. ํธ๋์ญ์ ๋กค๋ฐฑ ์ ๊ฒฐ์ ์ทจ์ ์์ฒญํ๊ธฐ - @TransactionalEventListener & ApplicationEventPublisher ๋ชจํน ์ด์ ๊ฒฐ์ ํ๋ก์ธ์ค๋ฅผ ์ค๊ณํ๋ฉด์, ๊ธฐ์กด์๋ try-catch๋ฅผ ํ์ฉํด ํธ๋์ญ์ ๋ด๋ถ์์ ๋ฐ์ํ๋ ๋ฐํ์ ์์ธ๋ฅผ ์ฒ๋ฆฌํ๊ณ , ๊ฒฐ์ ์ทจ์ ์์ฒญ์ ๋ณด๋์ต๋๋ค. ๊ทธ๋ฌ๋, ์ด์ ๋ํ ํ๊ณ๋ฅผ ๋๊ผ๊ณ ํธ๋์ญ์ ๋กค๋ฐฑ ์ ๊ฒฐ์ ์ทจ์ ์์ฒญ์ ๋ช ํํ๊ณ ์ง๊ด์ ์ผ๋ก ์ฒ๋ฆฌํ๊ธฐ ์ํด @TransactionalEventListener๋ฅผ ๋์ ํ์ต๋๋ค. ๊ธฐ์กด try-catch ๋ฐฉ์์ ํ๊ณ try-catch์์๋ ์ฃผ๋ก DB ์์ธ(์: DataIntegrityViolationException)๋ ๋น์ฆ๋์ค ๋ก์ง์์ ๋ฐ์ํ๋ ์์ธ๋ฅผ ์ฒ๋ฆฌํ๊ณ , ๊ฒฐ์ ์ทจ์ ์์ฒญ์ ๋ณด๋์ต๋๋ค. ํ์ง๋ง, try-catch๋ฅผ ์ฌ์ฉํ๋ฉด ์์ธ๋ฅผ ์ ์์ ์ธ ํ๋ฆ์ผ๋ก ์ ์ดํ๋ ๊ฒ์ฒ๋ผ ๋ณด์ด๊ฒ ๋ฉ๋๋ค. ์ด๋ "ํธ๋์ญ์ ์ด ๋กค๋ฐฑ๋์์ ๋ ๊ฒฐ์ ์ทจ์๋ฅผ ์ํํ๋ค"๋ผ๋ ์๋ฏธ๋ฅผ ์ ํํ ํํํ์ง.. ISO 8601 ๊ธฐ์ค์ผ๋ก ํน์ ๋ ์ง์ N์ N์ฃผ์ฐจ๋ฅผ Java 8 ๋ ์ง API๋ก ๊ตฌํ๊ธฐ ISO 8601 ๋ ?ISO 8601์ ๋ ์ง์ ์๊ฐ์ ๊ด๋ จ๋ ๊ตญ์ ํ์ค์ผ๋ก์จ, ์ ์๋ ๋ฐ์ ๋ฐ๋ฅด๋ฉด ๋งค์ฃผ์ ์์์ผ์ ์์์ผ์ด ๋ฉ๋๋ค.๋ํ, ๋งค์์ ์ฒซ ์ฃผ๋ ๊ณผ๋ฐ์ ์ด์์ ์์ผ์ด ํฌํจ๋ ์ฃผ๊ฐ ๊ธฐ์ค์ด ๋ฉ๋๋ค. ISO 8601 ๊ธฐ์ค์ผ๋ก ์ฃผ์ฐจ ๊ณ์ฐ ์์2024๋ 12์ ์์ 2024๋ 12์ 30์ผ, 31์ผ์ ๋ค์๊ณผ ๊ฐ์ ๊ท์น์ ๋ฐ๋ฆ ๋๋ค. 2025๋ 1์ 1~5์ผ(์ด 5์ผ)์ 7์ผ ์ค ๊ณผ๋ฐ์๋ฅผ ๋์ผ๋ฏ๋ก 1์ 1์ฃผ์ฐจ์ ๋๋ค ๋ฐ๋ผ์, 2024๋ 12์ 30์ผ, 31์ผ์ 2025๋ 1์ 1์ฃผ์ฐจ์ ํฌํจ๋ฉ๋๋ค 12์ 2์ผ ~ 12์ 8์ผ -> 12์ 1์ฃผ์ฐจ12์ 9์ผ ~ 12์ 15์ผ -> 12์ 2์ฃผ์ฐจ12์ 16์ผ ~ 12์ 22์ผ -> 12์ 3์ฃผ์ฐจ12์ 23์ผ ~ 12์ 29์ผ -> 12์ 4์ฃผ์ฐจ12์ 30์ผ ~ .. [ํธ๋ฌ๋ธ์ํ ] 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 3 4 5 6 ๋ค์