ํ๋ก์ ํธ (19) ์ธ๋ค์ผํ ๋ฆฌ์คํธํ @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๋ฅผ ์ฌ์ฉํ๊ณ ์์ผ๋ฉฐ.. [๊ฒฐ์ ์น์ธ ํ๋ก์ธ์ค ์ค๊ณ] ๊ฒฐ์ ์น์ธ ์์ฒญ๊ณผ DB ํธ๋์ญ์ ์ ์์๊ฐ์ ์ฅ๋จ์ ์ ๋น๊ต ๋ถ์ ์ฌ์ด๋ ํ๋ก์ ํธ ์ค, ์์ ์์ฝ์ ํ ๋์ ๊ฒฐ์ ํ๋ก์ธ์ค๋ฅผ ๊ตฌํ์ค์ด์์ต๋๋ค. ์์ฝ์ ํ์ ํ ๋, ๊ฒฐ์ ํ๋ก์ธ์ค๋ ๋ค์ ์ฌ์ง์ฒ๋ผ ์ฌ๋ฌ ํ๋ก์ธ์ค๋ก ๋๋์ด ์ง๋๋ค. ์ด ๋, ์ ๊ฐ ๊ณ ๋ คํ ๊ฒ์ ์ด 5๊ฐ์ง์ด๋ฉฐ ์ด์ ๋ํด ์ค๋ช ์ ์งํํฉ๋๋ค. ๊ฒฐ์ ํ๋ก์ธ์ค์ ํธ๋์ญ์ ์ค์ ๋ฒ์'๊ฒฐ์ ์น์ธ์ ์ํ PG์ฌ API ํธ์ถ'๊ณผ ํธ๋์ญ์ ์ ์์'๊ฒฐ์ ์น์ธ์ ์ํ PG์ฌ API ํธ์ถ'์ ๋๊ธฐ/๋น๋๊ธฐ ์ค ์ ํ ๋์์ฑ ์ ์ด ๋ฐฉ๋ฒ์์ก ๋ถ์กฑ์ผ๋ก ์ธํ ๊ฒฐ์ ์น์ธ ์คํจ๋ ํธ๋์ญ์ ๋กค๋ฐฑ ์ ๋ฐ์ํ๋ ๊ฒฝ์ฐ๋ฅผ ์ด๋ป๊ฒ ์ฒ๋ฆฌํ ๊ฒ์ธ์ง 1. ๊ฒฐ์ ํ๋ก์ธ์ค์ ํธ๋์ญ์ ์ค์ ๋ฒ์'๊ฒฐ์ ์น์ธ์ ์ํ PG์ฌ API ํธ์ถ' ์ ๋คํธ์ํฌ๋ฅผ ํตํด PG์ฌ์๊ฒ POST ์์ฒญ์ ํตํด ๊ฒฐ์ ๋ฅผ ์น์ธ ๋ฐ๋ ๊ณผ์ ์ผ๋ก ํธ๋์ญ์ ์ ํฌํจ๋์ด ํธ๋์ญ์ ์ด ๊ธธ์ด์ง๊ฒ ๋๋ค๋ฉด ๋ค์๊ณผ ๊ฐ.. ๋ก์ปฌ์์ Docker๋ฅผ ํ์ฉํ Prometheus & Grafana ์ฐ๋ ๋ฐฉ๋ฒ OSํ๊ฒฝ์ ๊ตฌ์ ๋ฐ์ง ์๋ ๋ชจ๋ํฐ๋ง ๊ตฌ์ถ์ ์๊ฐํ๋ ๊ธ์ ๋๋ค.Docker-compose, Actuator, ํ๋ก๋ฉํ ์ฐ์ค, ๊ทธ๋ผํ๋์ ๋ํ ๊ธฐ๋ณธ ์ค๋ช ๊ณผ ๋ชจ๋ํฐ๋ง ์ํคํ ์ฒ์ ๋ํ ์ค๋ช ์ ํ์ง ์๊ณ ์ฐ๋ํ๋ ๋ฐฉ๋ฒ๋ง ์๊ฐํฉ๋๋ค.ํ๋ก๋ฉํ ์ฐ์ค & ๊ทธ๋ผํ๋ ๋์ ์๊ฐ Jmeter ๋ฅผ ์ฌ์ฉํด์ ์ฌ์ด๋ ํ๋ก์ ํธ์ ๋ถํํ ์คํธ๋ฅผ ์งํํด๋ณด๋ ค๊ณ ๊ณํ์ค์ ๋๋ค.์ด๋ค ๋ถํํ ์คํธ๋ฅผ ์์ํ์ ๋ ํฐ์บฃ์ ์ฐ๋ ๋ ํ์ ๋ฌธ์ ์ธ์ง, DB ์ปค๋ฅ์ ํ์ด ๋ฌธ์ ์ธ์ง, ๋ด ๋ ธํธ๋ถ CPU ๋ฌธ์ ์ธ์ง, ๋ฉ๋ชจ๋ฆฌ ๋ฌธ์ ์ธ์ง๋ฅผ ํ์ธํ๊ณ ์ถ์๊ณ ํด๋น ๋ฌธ์ ์ ๋ง๊ฒ ํด๊ฒฐ์ ํ๊ณ ์ถ์์ต๋๋ค. ์คํ๋ง๋ถํธ์์ ์ง์ํ๋ ๊ฐ๋จํ ๋ชจ๋ํฐ๋ง ๋ชจ๋์ธ Actuator ๋ ๋ฉํธ๋ฆญ(์งํ)๋ค์ด ์ ์ฅ์ด ๋์ง ์๋ ์ ๊ณผ ๋ชจ๋ํฐ๋ง ์๋ฒ๋ฅผ ์ค์ ์ด์ํ๋ ๊ฒ์ฒ๋ผ ์๋ฒ๋ฅผ ๊ตฌ์ถํ๊ณ ์ถ์๊ธฐ ๋๋ฌธ์ ํ๋ก๋ฉํ .. [๋ก๊ทธ์ธ ๋ฐ ์ธ๊ฐ] Interceptor์์ ArgumentResolver๋ก ๋ฆฌํฉํ ๋งํ๊ธฐ [์๋ก ]์์ด๋น์ค๋น ํด๋ก ํ๋ก์ ํธ๋ฅผ ์งํํ๋ฉฐ, ๋ก๊ทธ์ธ ํ์๋ง '์์ ๋ฑ๋ก' ๊ณผ '์์ ์์ฝ' ์ ํ ์ ์๊ธฐ ์ํด(์ธ๊ฐ๋ฅผ ์ฃผ๊ธฐ ์ํด) ๋ก๊ทธ์ธํ ํ์์ ๋์์ผ๋ก ์ธ์ ์ ์ฌ์ฉํด์ stateful ํ๊ฒ ๊ตฌํ ํ์ต๋๋ค.@PostMapping("/login") public ApiResponse login(@RequestBody @Valid MemberLoginRequest request, HttpSession httpSession) { memberService.login(request.toServiceRequest()); // ๋ก๊ทธ์ธ์ ์ฑ๊ณตํ๋ฉด httpSession.setAttribute(LOGIN_MEMBER, true.. [ํธ๋ฌ๋ธ ์ํ ] ํ ์คํธ๋ก ์์๋ณด๋ ์ปจํธ๋กค๋ฌ์์ HttpSession ์ฌ์ฉ ์ ์ฃผ์์ Junit5 ๋ฐ Mock ์ ๋ํด ์ค๋ช ๋๋ฆฌ์ง ์๋ ์ ์ํด ๋ถํ๋๋ฆฝ๋๋ค.ํ ์คํธ ์ฝ๋๋ณด๋ค๋ ์ปจํธ๋กค๋ฌ์์ HttpSession ์ ์ฌ์ฉํ ๋์ ์ฃผ์์ ์ ์์๋ณด๋ ์๊ฐ์ ๊ฐ์ ธ๊ฐ์ จ์ผ๋ฉด ์ข๊ฒ ์ต๋๋ค. ์ปจํธ๋กค๋ฌ์์ ํ๋ผ๋ฏธํฐ๋ก HttpSession ์ ์ฃผ์ ๋ฐ์์ ์ฌ์ฉํ ๋ ์ฃผ์ํ ์ ์ด ์์ต๋๋ค. ์ ์ฃผ์ํด์ ์ฌ์ฉํด์ผ ํ๋์ง HttpSession ๊ณผ HttpServletRequest.getSession() ์ ์ฐจ์ด๋ฅผ ํ ์คํธ ์ฝ๋๋ก ์์๋ณด๊ฒ ์ต๋๋ค. โญ HttpSession ๋ฅผ ๋ฉ์๋์ ํ๋ผ๋ฏธํฐ๋ก ์ฆ์ ์ฃผ์ ๋ฐ๊ธฐ์ฝ๋ ์ค๋ช - ํ์์ด ์ธ์ฆ ์ฝ๋๋ฅผ ์๋ชป ์ ๋ ฅํด์ ์ด๋ฉ์ผ ๊ฒ์ฆ์ ์คํจํ๋ฉด if ๋ฌธ์ด ๊ฑฐ์ง์ด ๋ฉ๋๋ค.- Session ์ ๊ฐ์ ์ค์ ํ์ง ์๊ณ , ๋ฉ์๋๊ฐ ์ข ๋ฃ๋ฉ๋๋ค.@GetMapping("/email/authenticat.. [๋ก๊ทธ์ธ ๋ฐ ํ์๊ฐ์ ] ์ฌ์ฉ์ ํธ์์ฑ์ ๊ณ ๋ คํ ์ด๋ฉ์ผ ์ธ์ฆ ๊ธฐ๋ฐ ๋ก๊ทธ์ธ/ํ์๊ฐ์ ์๊ฐ ์๊ตฌ์ฌํญ ์๊ฐAirbnb ์ฌ์ดํธ์์ ๋ก๊ทธ์ธํ๊ธฐ ์ํด ์ด๋ฉ์ผ์ ์ ๋ ฅํ์ ๋์ด๋ฉ์ผ์ด ์กด์ฌํ๋ค๋ฉด ๋น๋ฐ๋ฒํธ๋ฅผ ์ ๋ ฅํ๋ ์ฐฝ์ ๋์์ฃผ๊ณ ,์ด๋ฉ์ผ์ด ์กด์ฌํ์ง ์๋๋ค๋ฉด ํด๋น ์ด๋ฉ์ผ์ ๊ฐ์ง๊ณ ํ์๊ฐ์ ์ ํ๋๋ก ์งํ์ํต๋๋ค.๊ณ ๋ฏผ ํฌ์ธํธ1. A์ฌ์ฉ์์ B์ฌ์ฉ์๊ฐ ๋์์ ๊ฐ์ ์ด๋ฉ์ผ๋ก ํ์๊ฐ์ ์ ํ ๋, ๋๊ตฌ์ ์ด๋ฉ์ผ์ ์ ํจํ๊ฒ ๋ณผ ๊ฒ์ธ๊ฐ? ์ฒ์์๋ ๋ก๊ทธ์ธํ๊ธฐ ์ํด ์ด๋ฉ์ผ์ ๋จผ์ ์ ๋ ฅํ ์ฌ์ฉ์๋ง ์ฒ๋ฆฌ๋์ผ ํ๋ค ์๊ฐํ์ต๋๋ค.๊ทธ๋์ ๋์์ ์ด๋ฉ์ผ์ ์ ๋ ฅํ์ ๋์ ์ผ์ด์ค๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํด ์ฑ๊ธ ์ค๋ ๋์ธ Redis ์ ๋จผ์ ๋ค์ด์จ ์ด๋ฉ์ผ์ ์ ์ฅ ํ ์ ์์ง๋ง, ์ดํ์ ์์ฒญํ ์ฌ์ฉ์ ์ ์ฅ์์๋ ํ์๊ฐ์ ํ์ง๋ ์์๋๋ฐ ๋น๋ฐ๋ฒํธ๋ฅผ ์ ๋ ฅํ๋ ์ฐฝ์ ๋์์ฃผ๋ ๊ฒ์ ์ฌ์ฉ์๋ก ํ์ฌ๊ธ ๋ถํธํ๋ค๊ณ ํ๋จํ์ต๋๋ค. ๊ทธ๋ฌ๋, ๋ฉ์ผ ์๋ฒ์ API๋ฅผ ์ฌ์ฉํ๋ค๋ฉด.. [ํธ๋ฌ๋ธ ์ํ ] jakarta.mail.internet.addressexception: local address contains control or whitespace ๊ตฌ๊ธ๋ง ํด๋ ๋์ค์ง ์๋ ์๋ฌ๋ฅผ ํด๊ฒฐํ๋ ๊ณผ์ ์ ์๊ฐํ๋ฉฐ, ์ ๋ฐ์ํ๊ณ ์ด๋ป๊ฒ ํด๊ฒฐํ๋์ง ์๊ฐํ๋ ๊ธ์ ๋๋ค.SMTP ๊ธฐ๋ฅ์ ๋ํด ์ค๋ช ํ์ง ์์ต๋๋ค.์๋ก ์์ด๋น์ค๋น์ ํ์๊ฐ์ ํ ๋, ํ์์ด ์ ๋ ฅํ ์ด๋ฉ์ผ์ด ์ ์ ์ด๋ฉ์ผ์ธ์ง ํ์ธํ๊ณ ์ ์ธ์ฆ๋ฒํธ๋ฅผ ๋ณด๋ด๊ณ ์ ํ์ต๋๋ค.๊ทธ๋์, ์๋์ ๊ฐ์ ์ฝ๋๋ก ๋ค์ด๋ฒ ์๋ฒ์ ๋ฉ์ผ์ ๋ณด๋์ผ๋, `jakarta.mail.internet.addressexception: local address contains control or whitespace` ์๋ฌ๊ฐ javaMailSender.send(message) ์์ ๋ฐ์ํ์์ต๋๋ค.public void sendVerificationEmail(String memberEmail) { try { SimpleMai.. ์ด์ 1 2 3 ๋ค์