๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

ํ”„๋กœ์ ํŠธ

(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..