์ธ๋ถ Open API์ ํต์ ํ๋ ์๋น์ค์์ “์คํจ”๋ ํผํ ์ ์์ต๋๋ค. ๋ฌธ์ ๋ ์คํจ๊ฐ ๋ฐ์ํ์ ๋, ์์คํ ์ด ๊ทธ ์คํจ๋ฅผ ์ด๋ป๊ฒ ๋ค๋ฃจ๋๋์ ๋๋ค.
ํ ์ค Runner's High ์ฒซ๋ฒ์งธ ์ธ์ ์ด ๋ฃ๊ณ ๊ทธ ๋ค์๋ 12์ 17์ผ, ์คํ๋ง์ผ ์ธ๋ถ ์์ง์ฒ์ธ SSG์ ์ฅ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค. SSG ์ ๊ด๋ จ๋ ๋ชจ๋ ์ฌ๋ด ๊ธฐ๋ฅ์ด ๋ง๋น ๋๊ณ , ์๋ฌ ๋ก๊ทธ๋ ๋ฌด์ํ ์์ฌ ํ ์๋ฌ ๋ฉ์ ์ ๋ฐฉ์ ์๋ฟ์ด ์์ต๋๋ค.

์ฅ์ ์์ฒด๋ ์ธ๋ถ ์ฌ์ ์ด์์ง๋ง, ๋ฌธ์ ๋ “์ธ๋ถ ์ฅ์ ” ๊ทธ ์์ฒด๊ฐ ์๋๋ผ, ์ฅ์ ์ํฉ์์ ์ฐ๋ฆฌ ์์คํ ์ด ์คํจ๋ฅผ ๋ค๋ฃจ๋ ๋ฐฉ์์ด์์ต๋๋ค.
์ด๋ฒ ๊ธ์ ๊ทธ๋์ ์ฅ์ ๋ฅผ ๊ณ๊ธฐ๋ก, HTTP Client timeout์ ์ฌ์ค์ ํ๊ณ , ์คํจ ์ retry ๊ตฌ์กฐ์ backoff/jitter ์ ์ฑ
์ ๋์
ํ์ผ๋ฉฐ, ์ธ๋ถ ์ฅ์ ๊ฐ ์์ฌ๋ ๋ ์์คํ
์ด ์๋์ผ๋ก ๊ธฐ๋ฅ์ ์ฐจ๋จํ๋ fallback(์ํท ๋ธ๋ ์ด์ปค) ํ๋ก์ธ์ค๋ฅผ ๋ง๋ ๊ฒฝํ์ ์ ๋ฆฌํ ๊ธ์
๋๋ค.
๋๋ถ์ด, ์์ธ ์ฒ๋ฆฌ ๋์๋ก ์ธํด ์ฌ์ฉ์ ํ๋ฉด์ ์๋ฌ ๋ฌธ๊ตฌ๊ฐ ๊ทธ๋๋ก ๋ ธ์ถ๋๊ฑฐ๋ ์ด๋ ฅ์ด “์งํ์ค”์ผ๋ก ๋จ๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด, TypeScript ๋ฉ์๋ ๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ์ฌ์ฉํด ์ง์ ์ ์ ์ ์ญ ์์ธ ์ฒ๋ฆฌ๋ฅผ ๊ฑธ๊ณ (Global Exception Handler), ์์ธ ์ ์ฑ ์ ํ ๊ณณ์ผ๋ก ๋ชจ์ผ๋ ๊ตฌ์กฐ๋ก ๋ฆฌํฉํ ๋งํ ๋ด์ฉ๊น์ง ํจ๊ป ๋ด์์ต๋๋ค.
์ด๋ฒ ์์ ์ ํต์ฌ์ ๋จ์ํ “์คํจ ์ฒ๋ฆฌ ๊ฐ์ ”์ด ์๋๋๋ค. ์ฌ์ฉ์ ๊ฒฝํ์ ์ ํดํ๋ ๊ทผ๋ณธ ์์ธ์ด ์คํฌ๋ํ ๋ชจ๋ ๋ด๋ถ์ ‘์์ธ ์ฒ๋ฆฌ ๋ถ์์ ์ฑ’์ ์์์ ์ ํํ ์ง์ด๋ด๊ณ , ์๋ฌ ์ฒ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ์ผ๊ด๋ ์ ์ฑ ๊ธฐ๋ฐ์ผ๋ก ์ฌ์ค๊ณํจ์ผ๋ก์จ ์๋น์ค ์คํจ์จ์ ๋ฎ์ถ๋ ๋์์, ์ฅ์ ์ํฉ์์๋ ์์คํ ์ด ์ค์ค๋ก ๋์ํ ์ ์๋๋ก ์๋ํ๋ ๋ฐฉ์ด ์ฒด๊ณ๊น์ง ๊ตฌ์ถํ ๊ฒ์ ๋๋ค.
์ฆ, ์ด๋ฒ ๊ฐ์ ์ ๋จ๊ธฐ์ ์ธ ์ฅ์ ๋์์ ๋์ด, ๋์ผํ ๋ฌธ์ ๊ฐ ์ฌ๋ฐํ๋๋ผ๋ ํ๋ค๋ฆฌ์ง ์๋ ๊ตฌ์กฐ๋ฅผ ๋ฏธ๋ฆฌ ๋ง๋ จํ ์์ ์ด์์ต๋๋ค.
โ ๏ธSituation - ๋ฌธ์ ์ํฉ ๋ฐ ๋ฐฐ๊ฒฝ
์ฅ์ ๋ ์ธ๋ถ์์ ์์๋์ง๋ง, ๋ฌธ์ ๋ ๋ด๋ถ์์ ์ฆํญ๋๋ค.
“HTTP ์์ฒญ timeout ์ค์ ์ด ๋น ์ง”
์ฒซ ๋ฒ์งธ ๋ฌธ์ ๋ SSG ์ฅ์ ๋ฐ์์ ๋ก๊ทธ๋ฅผ ํ์ ํด ๋ณด๋, HTTP timeout์ด ์๋๋ผ Action timeout์ผ๋ก ํฐ์ง๊ณ ์์๋ค๋ ์ ์ ๋๋ค.
์ฌ๋ด ์คํฌ๋ํ ๋ชจ๋์ ํ ํฝ์ ๊ตฌ๋ ํด ์คํ๋๋ Action์ด ์๊ณ , Action์ ์ ์ฒด ์คํ์ ๋ํ ํ์์์(์ก์ ํ์์์)์ ๊ฐ์ต๋๋ค. ์ ์์ ์ธ ๊ตฌ์กฐ๋ผ๋ฉด, ์ธ๋ถ ์๋ต์ด ์ง์ฐ๋๊ฑฐ๋ ๋๊ฒผ์ ๋๋ HTTP Client timeout์ด ๋จผ์ ๋ฐ์ํ๊ณ “๋คํธ์ํฌ ์คํจ”๋ก ๋ถ๋ฅ๋์ด์ผ ํฉ๋๋ค.

๊ทธ๋ฐ๋ฐ ์ค์ ๋ก๊ทธ๋ ๊ทธ๋ ์ง ์์์ต๋๋ค. ํต์ ์ด ๋๊ธด ๊ฒ ์๋๋ผ “Action ๋ด๋ถ ๋ก์ง์ด ์ค๋ ๊ฑธ๋ ค์ ์คํจ”์ฒ๋ผ ๊ธฐ๋ก๋๊ณ ์์์ต๋๋ค.
์์ธ์ ์ถ์ ํด๋ณด๋ ํ ํ ์์
์ผ๋ก ์ธํด ๋ชจ๋ HTTP ๊ธฐ๋ณธ timeout์ด ์ก์
ํ์์์๊ณผ ๊ฐ์ ๊ฐ์ผ๋ก ๋ง์ถฐ์ ธ ์์๊ณ , ์ผํ๋ชฐ ์ ๋ฐ ์ธ๋ถ ํต์ ์ฝ๋๊ฐ ๊ทธ ๊ธฐ๋ณธ๊ฐ์ ๊ทธ๋๋ก ์ ์ฉ๋ฐ๊ณ ์์์ต๋๋ค. ๊ฒฐ๊ณผ์ ์ผ๋ก ํต์ ์คํจ๊ฐ ์ ๋ ๋๊ธฐ์ง ์๊ณ , ์ ์ฒด ์์
์ด ๋์ด์ง๋ค๊ฐ Action timeout์ผ๋ก ๋๋๋ฒ๋ฆฌ๋ ๊ตฌ์กฐ๊ฐ ๋์ด ์์์ต๋๋ค.
์คํจ ์์ธ ๋ถ๋ฅ๊ฐ ํ๋ ค์ง๋ ์๊ฐ, ํ์ ์ฒ๋ฆฌ๋ ํ๋ ค์ง๋๋ค. “ํต์ ์คํจ์ ๋ํ ๋์”๊ณผ “์
๋ฌด ์คํจ์ ๋ํ ๋์”์ ๋ค๋ฅผ ์๋ฐ์ ์๋๋ฐ, ์ฐ๋ฆฌ๋ ๊ทธ ๋์ ์์ด๋ฒ๋ฆฐ ์ํ์์ต๋๋ค.
“๊ฐํ์ ์ธ ๋จ์ ์๋ต ์ค๋ฅ์๋ ๊ทธ๋๋ก ์คํจ ์ฒ๋ฆฌํจ.”
timeout ๊ด๋ จํด ๋ก์ง์ ํ์ ํ๋ฉด์ ํ์ธํ ๋ ํ๋์ ์ค์ํ ์ฌ์ค์ ์์ฒญ ์คํจ ์ ์ฆ์ ์คํจ ํ์ ํ๊ณ ์์๊ณ , ๋ฆฌํธ๋ผ์ด ๊ตฌ์กฐ๊ฐ ์กํ ์์ง ์๋ค๋ ์ ์ ๋๋ค. ๋คํธ์ํฌ๋ ์ธ์ ๋ ํ๋ค๋ฆฌ๊ณ , ์ธ๋ถ Open API๋ ๊ฐํ์ ์ผ๋ก 500 ๋ ์๋ฌ๋ 429(Too Many Request)๋ฅผ ๋ฐํํ ์ ์์ต๋๋ค.
์ด๋ฐ ์คํจ๋ ์ผ๋ฐ์ ์ผ๋ก “ํ ๋ฒ ๋” ์๋ํ๋ฉด ์ฑ๊ณตํ๋ ๊ฒฝ์ฐ๊ฐ ๋งค์ฐ ๋ง์ต๋๋ค. ๊ทธ๋ฐ๋ฐ ์ฐ๋ฆฌ๋ ์คํจ๋ฅผ ๋ฐ๋ ์๊ฐ ๋ฐ๋ก ์คํจ ํ์ ์ฒ๋ฆฌ๋ฅผ ํด๋ฒ๋ ธ์ต๋๋ค. ์ฌ์ฉ์๋ ํ์ ์ด์์ผ๋ก ์คํจ๋ฅผ ๊ฒฝํํ๊ณ , ์ ์ฒด์ ์ธ ์๋น์ค ์ฑ๊ณต๋ฅ ์ ๋จ์ด์ง๋ ๋ฌธ์ ๋ฅผ ํ์ ํ์ต๋๋ค.
“์ธ๋ถ ์ฅ์ ๋ฐ์์์๋ ์ฌ์ฉ์์ ์์ฒญ์ ๊ณ์ ๋ค์ด์ ์คํจ๊ฐ ํญ๋ฐํ๋ ๊ตฌ์กฐ”
์ธ ๋ฒ์งธ ๋ฌธ์ ๋ ์ธ๋ถ ์ฅ์ ๊ฐ ๋ฐ์ํ์ ๋, ๊ด๋ฆฌ์๊ฐ ๊ธฐ๋ฅ์ ๋ง๊ธฐ ์ ๊น์ง ์ฌ์ฉ์๋ ๊ณ์ ์์ฒญ์ ๋ณด๋ผ ์ ์์๊ณ ๊ทธ ๋ชจ๋ ์์ฒญ์ด ์คํจ๋ก ๋์๊ฐ๋ฉด์ ๋ก๊ทธ๊ฐ ํญ๋ฐํ๋ ๊ตฌ์กฐ์๋ค๋ ์ ์ ๋๋ค. ์ธ๋ถ ์๋ฒ๊ฐ ์ฃฝ์๋๋ฐ๋ ์ฌ์ฉ์๋ ๊ทธ ์ฌ์ค์ ๋ชจ๋ฅธ ์ฑ ๊ธฐ๋ฅ์ ๊ณ์ ์ฌ์ฉํฉ๋๋ค. ๊ทธ๋ฌ๋ฉด ์คํจ ์์ฒญ์ด ๊ณ์ ๋์ ๋๊ณ , ๋ก๊ทธ๋ ํญ๋ฐ์ ์ผ๋ก ์์ ๋๋ค.
์ฌ์ฉ์๋ “์ฐ๋ฆฌ ์๋น์ค๊ฐ ๊ณ ์ฅ ๋ฌ๋ค”๊ณ ์คํดํ ์ ์๊ณ , ๋ด๋ถ์ ์ผ๋ก๋ ๋ชจ๋ํฐ๋ง๊ณผ ์ด์ ๋ถ๋ด์ด ์ปค์ง๋๋ค. ์ธ๋ถ ์๋ฒ ์ ์ฅ์์๋ ์ฅ์ ์ํฉ์์ ๋ถํ์ํ ์ฌ์์ฒญ์ด ๊ณ์ ๋ค์ด์ค๋ ํ๋ณต์ ๋ฐฉํดํ๋ ๋ฐฉํฅ์ด ๋ ์๋ ์์ต๋๋ค. ์ฆ, ์ฅ์ ์ํฉ์์ ์คํจ๋ฅผ ์ค์ฌ์ผํ๋๋ฐ, ์คํ๋ ค ์ ๋์ฒํ์ง ๋ชปํ๊ณ ๋ฐฉ์นํ๋ ๊ตฌ์กฐ์์ต๋๋ค.
“์์ธ ์ฒ๋ฆฌ ๋์๋ก ์ธํด ์ฌ์ฉ์ ๊ฒฝํ์ด ์ง์ ์ ์ผ๋ก ๊นจ์ง๊ณ ์์์.”
์คํฌ๋ํ ๋ชจ๋ ๋ด์ try/catch๋ก ์์ธ๋ฅผ ์ ๋๋ก ๊ฐ์ธ์ง ๋ชปํ ๊ฒฝ๋ก๊ฐ ์กด์ฌํด, ์ด๋ค ๊ฒฝ์ฐ์๋ ์๋ฌ ๋ฉ์์ง๊ฐ ๊ทธ๋๋ก ์ฌ์ฉ์ ํ๋ฉด์ ๋ ธ์ถ๋๊ธฐ๋ ํ์ต๋๋ค. ๋ ํฐ ๋ฌธ์ ๋ “์ด๋ ฅ”์ด์์ต๋๋ค. ์ฐ๋ฆฌ ์ ๋ฌด ํ๋ฆ์ ๋ง์ง๋ง ๋จ๊ณ์์ ์ฑ๊ณต/์คํจ ์ด๋ ฅ์ ์ ๋ฐ์ดํธํ๋ ํ ํฝ์ ๋ฐํํด ์ฌ์ฉ์์๊ฒ ์์ ๊ฒฐ๊ณผ๋ฅผ ๋จ๊น๋๋ค.
๊ทธ๋ฐ๋ฐ ์์ธ๊ฐ ์ค๊ฐ์์ throw ๋๊ณ ์ฒ๋ฆฌ๋์ง ์์ผ๋ฉด ๋ก์ง์ด ๋น์ ์ ์ข ๋ฃ๋๋ฉด์, ์ด๋ ฅ ์ ๋ฐ์ดํธ ํ ํฝ์ด ๋ฐํ๋์ง ๋ชปํด ์ด๋ ฅ์ด ‘์งํ์ค’์ผ๋ก ๋จ๋ ์ผ์ด์ค๊ฐ ๊ฐํ์ ์ผ๋ก ๋ฐ์ํ์ต๋๋ค. ์ฌ์ฉ์๋ ์ด๋ฏธ ์คํจํ ์์ ์ “์์ง๋ ์งํ์ค์ธ์ง”, “์คํจํ ๊ฑด์ง” ์ ์ ์์ต๋๋ค. ์ด๊ฑด ๋จ์ ๋ฒ๊ทธ๊ฐ ์๋๋ผ ์๋น์ค ์ ๋ขฐ๋ฅผ ๋ฌด๋๋จ๋ฆฌ๋ ๋ฌธ์ ๋ผ๊ณ ์๊ฐํฉ๋๋ค.


๐Task - ํด๊ฒฐํด์ผ ํ๋ ๊ณผ์ ๋ฐ ๋ชฉํ
๋ชฉํ๋ “์ฑ๊ณต๋ฅ ์ ์ฌ๋ฆฌ๋ ๊ฒ”์ด ์๋๋ผ “์คํจ๋ฅผ ํต์ ํ๋ ๊ฒ”
“์ธ๋ถ ํต์ ๊ณผ์ ์์ด ์ ์ ํ timeout ์ฒ๋ฆฌ”
์ธ๋ถ ํต์ ์์ ๋ฐ๋์ HTTP timeout์ ์ ๋ฌด ํน์ฑ์ ๋ง๊ฒ ์ค์ ํด์ผ ํ์ต๋๋ค. ์ธ๋ถ ์๋ฒ๊ฐ ์ฅ์ ์ผ ๋, ์์คํ ์ด ์ค๋ ์๊ฐ ์๋ต์ ๊ธฐ๋ค๋ฆฌ๋ฉฐ ๋ฆฌ์์ค๋ฅผ ์ ์ ํ๋ ๊ฑด ์ด์์ ์ผ๋ก ๋งค์ฐ ๋ญ๋น์ ๋๋ค.
ํต์ ๋จ๊ณ์์ ์ ์ ํ ์๊ฐ๋ง ๊ธฐ๋ค๋ฆฌ๊ณ ๋์ด์ผ “์คํจ๊ฐ ์คํจ๋ก ๋ถ๋ฅ”๋๊ณ , ํ์ ์กฐ์น(์ฌ์๋/์ฐจ๋จ/์ฌ์ฉ์ ์๋ด)๊ฐ ์ ๊ตํด์ง ์ ์์ต๋๋ค. ๋ํ Action timeout ์๋ฌ์ ํต์ timeout ์๋ฌ๋ ๋ฐ์ ์์ธ๊ณผ ํ์ ์กฐ์น๊ฐ ๋ค๋ฅด๋ฏ๋ก, ์๋ก ๋ค๋ฅด๊ฒ ๋ช ํํ ๋ถ๋ฆฌํด์ผ ํ์ต๋๋ค.
“Retry ๊ตฌ์กฐ ์ค๊ณ”
๊ฐํ์ ์คํจ๋ฅผ ํก์ํ๊ธฐ ์ํ ๋ฆฌํธ๋ผ์ด ๊ตฌ์กฐ ์ค๊ณ๊ฐ ํ์ํ์ต๋๋ค. ๋จ, ๋ฌด์์ ๋ฆฌํธ๋ผ์ดํ๋ฉด ์ธ๋ถ์ ๋ถํ๋ฅผ ์ฃผ๊ณ ์ฅ์ ๋ฅผ ์ ํ์ํฌ ์ ์์ผ๋ฏ๋ก, ์ด๋ค ์คํจ์ ๋ฆฌํธ๋ผ์ดํ ์ง, ์ด๋ค ์ ๋ฌด๋ ๋ฆฌํธ๋ผ์ดํ๋ฉด ์ ๋๋์ง(๋ณด์ ์ ์ฑ ์ผ๋ก IP ์ฐจ๋จ ์ํ์ด ํฐ ์นด๋/์ํ ์คํฌ๋ํ), ๊ทธ๋ฆฌ๊ณ ๋ช ๋ฒ๊น์ง ์๋ํ ์ง(๋ฌดํ ์ฌ์๋ ๊ธ์ง) ๋ฑ ์ ์ฑ ์ ์ ์ํ๊ณ ๋์ ํด์ผ ํ์ต๋๋ค.
“Fallback ์ ๋ต ๋์ ”
๋จผ์ ๋ค์ ๊ฐ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ ๋ ์ด๋ป๊ฒ ๋๋นํ ๊ฒ์ธ๊ฐ? ์ฅ์ ๋์์ ์์ด ์ด๋ป๊ฒ ์๋ํ ์ฒ๋ฆฌ๋ฅผ ํ ์ ์์ ๊ฒ์ธ๊ฐ์ ๋ํด ๊ณ ๋ฏผํ์ต๋๋ค. ์ธ๋ถ ํน์ ๋ฆฌ์์ค ์๋ฒ ์ฅ์ ์ “๋ค๋ฅธ ์๋ฒ๋ก ๋ณด๋ด๋ ์ด์ํ”๋ ํ์ค์ ์ผ๋ก ์ด๋ ต๊ธฐ ๋๋ฌธ์, ์ฐ๋ฆฌ๊ฐ ํ ์ ์๋ Fallback์ ๋ช ํํ์ต๋๋ค. ์ฅ์ ๊ฐ ์์ฌ๋๋ ์๊ฐ ์์คํ ์ด ์๋์ผ๋ก ๊ธฐ๋ฅ์ ์ฐจ๋จํด ๋ ๋ง์ ์ฌ์ฉ์๊ฐ ์คํจ๋ฅผ ๊ฒฝํํ๊ธฐ ์ ์ ์์ฒญ ์์ฒด๋ฅผ ๋ง์์ผ ํ์ต๋๋ค.
์ด๊ฑด ๋จ์ ํธ์๊ฐ ์๋๋ผ, ์ฅ์ ์ํฉ์์ ๋ด๋ถ/์ธ๋ถ ๋ฆฌ์์ค๋ฅผ ๋ณดํธํ๋ ์ด์ ์ ๋ต์ ๋๋ค. ํนํ ์๋ฒฝ์ ์ค์ผ์ค์ด ๋๋ฉฐ ์๋์ผ๋ก ์๋น์ค๊ฐ ๋์ ํ ๋ ์ธ๋ถ ์๋ฒ ์ ๊ฒ๊ณผ ๊ฒน์ณ ์ฐ์ ์คํจ๊ฐ ๋ฐ์ํ๋ ๊ฒฝ์ฐ, ์ฌ๋์ด ์์์ฑ๊ณ ๋ง๊ธฐ ์ ์ ์์คํ ์ด ๋จผ์ ์ฐจ๋จํด์ฃผ๋ ๊ฒ ํจ์ฌ ์์ ํฉ๋๋ค.
“์์ธ ์ฒ๋ฆฌ ๋์๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ ์ ์ญ์ ์ธ ์๋ฌ ์ฒ๋ฆฌ”
์์ธ ์ฒ๋ฆฌ ๋์๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ ์ ์ญ์ ์ธ ์๋ฌ ์ฒ๋ฆฌ(๊ธ๋ก๋ฒ ์ต์ ์ ํธ๋ค๋ฌ)๊ฐ ํ์ํ์ต๋๋ค. ์ฌ์ฉ์์๊ฒ ์๋ฌ ์๋ฌธ์ด ๋ ธ์ถ๋๋ ๋ฌธ์ ๋ฅผ ๋ง๋ ๊ฒ์ ๊ธฐ๋ณธ์ด๊ณ , ๋ ์ค์ํ ๊ฑด “์ด๋ค ์์ธ๊ฐ ๋ฐ์ํ๋๋ผ๋ ์ด๋ ฅ ์ ๋ฐ์ดํธ/์คํจ ํ์ /ํ์ค ๋ฉ์์ง ์๋ต์ด ๋ณด์ฅ๋๋ ๊ตฌ์กฐ”๋ฅผ ๋ง๋๋ ๊ฒ์ ๋๋ค. ์์ธ ์ฒ๋ฆฌ ์ ์ฑ ์ด ์ฝ๋ ๊ณณ๊ณณ์ ํฉ์ด์ ธ ์์ผ๋ฉด, ์ธ์ ๊ฐ ๋ฐ๋์ ๋์๊ฐ ์๊น๋๋ค. ๊ทธ๋์ ์์ธ ์ฒ๋ฆฌ ์์ฒด๋ฅผ ํ๋์ ๊ด์ฌ์ฌ๋ก ๋ถ๋ฆฌํด, ์ง์ ์ ์์ ์ ์ญ์ ์ผ๋ก ์ฒ๋ฆฌํด์ผ ํ์ต๋๋ค.
๐จ๐งAction - ํ๋ ๋ฐ ์์
์ ์ฑ ์ ๋จผ์ ํฉ์ํ๊ณ , ๊ณตํต ๊ณ์ธต์ผ๋ก ๋์ด์ฌ๋ ค “ํ ๋ฒ์ ์ ์ฉ”
“ํ์ ์์ ์ค์ ๋ฐ ๋ฆฌํธ๋ผ์ด ๊ตฌ์กฐ, ํด๋ฐฑ ํ๋ก์ธ์ค ์ ์ฑ ๊ตฌ์ ํ ํ๋ด ์ ์”
SSG ๊ด๋ จ ์๋ฌ๋ก๊ทธ๋ฅผ ํ์ ํ๋ฉด์ ์คํฌ๋ํ ๋ชจ๋์ ๋ด์ ์กด์ฌํ๋ ๋ฌธ์ ์ ๋ค์ ๋จผ์ ๋ฆฌ์คํธ์ ํ์ต๋๋ค. ์ด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๊ฐ์ ํ ์ ์๋ ์ ๊ณผ ๊ธฐ๋ํจ๊ณผ๋ฅผ ์ ๋ฆฌํด ๊ธ๋ก ์์ฑํ๊ณ , ASIS ๊ตฌ์กฐ์ TOBE ๊ตฌ์กฐ๋ฅผ ๋์ํํ์ฌ ์ฒจ๋ถ ํ์ต๋๋ค. ๊ธ์ ํต์ฌ์ ๋ชจ๋ ๋ฌธ์ ๋ฅผ ๋ฐ๋ก ๋ณด๋ ๊ฒ์ด ์๋๋ผ ๊ทผ๋ณธ์ ์ธ ๋ฌธ์ ์ธ ์คํจ์ฒ๋ฆฌ๋ฅผ ์ ์ฒด ํ์ดํ๋ผ์ธ์ผ๋ก ๋ณด๋ ๊ด์ ์ ๋๋ค. ๊ธ์ ์ ์์ ํํ๋ก ๋ค๋ฌ์ด ํ์ฅ๋ ๋ฐ ๋ถ๋ฌธ์ฅ๋๊ณผ ํ์๋ฅผ ์งํํ๊ณ , ์ ์ฉ ๋ฒ์/์ ์ฑ /์ด์ ๋ฐฉ์๊น์ง ํฉ์ํ ๋ค ๋จ๊ณ์ ์ผ๋ก ๊ตฌํ์ ๋ค์ด๊ฐ์ต๋๋ค.
“ํ์ ์์ ์ค์ ๋ฐ ๋ฆฌํธ๋ผ์ด ๊ตฌ์กฐ ์ค๊ณ”
๊ฐ์ฅ ๋จผ์ ์๋ ๊ฒ์ HTTP timeout๊ณผ ๋ฆฌํธ๋ผ์ด์์ต๋๋ค. ์คํฌ๋ํ ๋ชจ๋์ ์ผํ๋ชฐ ์ ๋ฌด ํ์์๋ ์ธ๋ถ ํต์ ์ ์ํํ๋ ์์ค ํ์ผ์ด ์ฝ 138๊ฐ ์กด์ฌํฉ๋๋ค. ์ด ๊ตฌ์กฐ์์ “๊ฐ ํ์ผ์ ๋ฆฌํธ๋ผ์ด ๋ฃ๊ธฐ”๋ ์ ์ง๋ณด์ ๊ด์ ์์ ์คํจํ๋ ์ ๊ทผ์ ๋๋ค. ๋ฆฌํธ๋ผ์ด ์ ์ฑ ์ ‘๊ณตํต ์ ์ฑ ’์ด๊ธฐ ๋๋ฌธ์, ๊ตฌํ๋ ๋ฐ๋์ ‘๊ณตํต ๊ณ์ธต’์ ์์ด์ผ ์ ์ง๋ณด์๊ฐ ํธ๋ฆฌํ๋ค๊ณ ์๊ฐํ์ต๋๋ค.
๊ทธ๋์ ์ ๋ ๊ฐ ํต์ ๊ตฌํ์ฒด์ ๋ก์ง์ ํฉ๋ฟ๋ฆฌ์ง ์๊ณ , ๋ถ๋ชจ ํด๋์ค์ HTTP ์์ฒญ์ Sendํ๋ ๋ฉ์๋์ retry๋ฅผ ๊ตฌํํด 138๊ฐ ํ์ผ์ ํ ๋ฒ์ ์ ์ฉ๋๋๋ก ๋ง๋ค์์ต๋๋ค. timeout ๊ฐ์ config๋ก ๊ด๋ฆฌํ๊ณ , ์์ง์ฒ ํน์ฑ์ ๋ฐ๋ผ ๋ฆฌํธ๋ผ์ด ํ์๋ฅผ ์กฐ์ ๊ฐ๋ฅํ ์ ์๋๋ก ๋ฆฌํธ๋ผ์ด๋ ์์ง์ฒ ์ ๋ฌด ๋ช ์ธ์์ ์ค์ ํ ์ ์๋๋ก ํ์ต๋๋ค.
๋ฆฌํธ๋ผ์ด ๊ท์น์ ๋จ์ํ์ง๋ง ๋ช ํํ๊ฒ ์ก์์ต๋๋ค.
- ๋คํธ์ํฌ ์์ธ(ํ์์์/์ปค๋ฅ์ ๋ฌธ์ ๋ฑ)
- 429 ์๋ต ๋๋5xx ๋ ์๋ต

๋ฌด์์ ์ฌ์๋ํ์ง ์๋๋ก, ๋ฆฌํธ๋ผ์ด๋ ๊ธฐ๋ณธ์ ์ผ๋ก 2ํ๋ก ์ ํํ์ต๋๋ค. ์ฆ ํ ์์ฒญ๋น ์ต๋ 3ํ๊น์ง ์๋ํฉ๋๋ค. ๊ณผ๋ํ ์ฌ์๋๋ ์ธ๋ถ ์ฅ์ ์ํฉ์์ ์คํจ๋ฅผ ํญ๋ฐ์ํค๋ ๋ฐฉํฅ์ด ๋๊ธฐ ๋๋ฌธ์, “์ฑ๊ณต๋ฅ ์์น”๊ณผ “์ฅ์ ์ฆํญ ๋ฐฉ์ง” ์ฌ์ด์์ ๊ท ํ์ ์ก๋ ๊ฒ ์ค์ํ์ต๋๋ค.
์ฌ๊ธฐ์ ํต์ฌ์ “๋ฆฌํธ๋ผ์ด๋ฅผ ์ด๋ป๊ฒ ๊ธฐ๋ค๋ฆฌ๋๋”์ ๋๋ค. ๊ฐ์ ์์ฒญ์ ์ฆ์ ์ฐ์์ผ๋ก ๋ณด๋ด๋ ๋ฐฉ์์ ๊ฑฐ์ ์ต์ ์ ๋๋ค. ์ธ๋ถ ์๋ฒ๊ฐ ์ ๊น ๋ฒ๋ฒ ์ด๊ฑฐ๋ rate limit์ด ๊ฑธ๋ฆฐ ์ํฉ์์๋, ์งง์ ์๊ฐ์ ์์ฒญ์ด ๋ชฐ๋ฆฌ๋ฉด ๋ ์ ํ๋ ๊ฐ๋ฅ์ฑ์ด ํฝ๋๋ค. ๊ทธ๋์ ๋ฆฌํธ๋ผ์ด ๋๊ธฐ์๊ฐ์ ์ง์ ๋ฐฑ์คํ(Exponential Backoff)๋ฅผ ์ฌ์ฉํ์ต๋๋ค. ์คํจ๊ฐ ๋์ ๋ ์๋ก ๋๊ธฐ ์๊ฐ์ ๋๋ ค ์ธ๋ถ ์๋ฒ์ ํ๋ณต ์๊ฐ์ ์ฃผ๊ณ , ๋ฆฌ์์ค๋ ๋ณดํธํ ์ ์๋๋ก ํ์ต๋๋ค.

๊ทธ๋ฆฌ๊ณ ์ง์ ๋ฐฑ์คํ๋ง์ผ๋ก๋ ์ถฉ๋ถํ์ง ์์ต๋๋ค. ๊ฐ์ ์๊ฐ๋์ ์๋ง์ ์์ฒญ์ด ์คํจํ๋ค๋ฉด, ๋ชจ๋ ์์ปค๊ฐ “2์ด ๋ค ์ฌ์๋”์ฒ๋ผ ๋์ผํ ํจํด์ผ๋ก ๊นจ์ด๋ ๋ค์ ์์ฒญ์ ๋ชฐ์๋ฃ์ต๋๋ค. ์ด๊ฑด ์ฅ์ ์ํฉ์์ 2์ฐจ ํญ๋ฐ(์ฌ์๋ ์คํ์ดํฌ)์ ๋ง๋ค ์ ์์ต๋๋ค. ๊ทธ๋์ ๋ฐฑ์คํ ๋๋ ์ด์ ์งํฐ(Jitter)๋ฅผ ๋ฃ์์ต๋๋ค. ์ง์ฐ ์๊ฐ์ 50~150% ๋ฒ์์์ ๋๋คํ๊ฒ ํฉ๋ฟ๋ ค, ์ฌ์๋ ํธ๋ํฝ์ด ํน์ ์๊ฐ์ ์ ๋ฆฌ์ง ์๋๋ก ๋ถ์ฐํ์ต๋๋ค.
const delay = 1000 * 2 ** attempt_count; // 1์ด, 2์ด, 4์ด... ์ง์ ๋ฐฑ์คํ
const delay_ms = delay * (0.5 + Math.random()); // Simple Jitter
sleep(delay_ms);
๋ค๋ง, ๋ชจ๋ ์ ๋ฌด์ ๋ฆฌํธ๋ผ์ด๋ฅผ ์ ์ฉํ์ง ์์์ต๋๋ค. ์นด๋/์ํ์ฒ๋ผ ์๋ต์ ์คํฌ๋ํํด์ ๋ฐ์ดํฐ๋ฅผ ์ถ์ถํ๋ ์ ๋ฌด๋, ์ฆ์ ์์ฒญ์ด ๋ณด์ ์ ์ฑ ์ ์ํด IP ์ฐจ๋จ์ผ๋ก ์ด์ด์ง ์ ์์ต๋๋ค. ์ด ์์ญ์์๋ “์ฑ๊ณต๋ฅ ”์ ์กฐ๊ธ ์ฌ๋ฆฌ๊ธฐ ์ํด ๋ฆฌํธ๋ผ์ด๋ฅผ ๋ฃ๋ ์๊ฐ, “์ฐจ๋จ ๋ฆฌ์คํฌ”๋ผ๋ ๋ ํฐ ๋น์ฉ์ ์น๋ฅผ ์ ์์ต๋๋ค. ๊ทธ๋์ ์ด ์์ญ์ ๋ฆฌํธ๋ผ์ด ์ ์ธ๋ก ์ ์ฑ ์ ํ์ ํ์ต๋๋ค.
์ฆ, ๋ฆฌํธ๋ผ์ด๋ฅผ ๋์ ํ๋ ๋ฌด์กฐ๊ฑด์ด ์๋๋ผ, ์ ๋ฌด ํน์ฑ๊ณผ ๋ฆฌ์คํฌ๋ฅผ ๊ธฐ์ค์ผ๋ก ์ ์ฉ ๋์์ ๊ตฌ๋ถํ์ต๋๋ค.
“Fallback ํ๋ก์ธ์ค๋ก ๊ธฐ๋ฅ ์ฐจ๋จ ์๋ํ๋ฅผ ์ํด ์ํท ๋ธ๋ ์ด์ปค ํจํด์ ํ์ฉ”
์ฐ๋ฆฌ๊ฐ ์ธ๋ถ ๋ฆฌ์์ค ์๋ฒ๋ฅผ ์ด์ํํด ํน์ ์๋ฒ ์ฅ์ ์ ๋ค๋ฅธ ์๋ฒ๋ก ๋ณด๋ด failover ํ ์ ์๋ค๋ฉด ์คํจ์จ์ ๋ฎ์ถ๊ณ ์ฌ์ฉ์์ ๊ฒฝํ์ ์ฆ๋์ํฌ ์ ์์ ๊ฒ์ ๋๋ค. ํ์ง๋ง ์ฐ๋ฆฌ๊ฐ ์ธ๋ถ ์๋ฒ์ ์ด์ํ๋ฅผ ๊ฐ๋ฅ์ผ ํ ์ ์๋ ๋ฐฉ๋ฒ์ ์์ต๋๋ค.
ํ์ค์ ์ธ fallback์ “๋ ์ด์ ์๋ํ์ง ์๋ ๊ฒ”์ ๋๋ค. ์ธ๋ถ๊ฐ ์ฃฝ์๋๋ฐ ๊ณ์ ๋๋ฆฌ๋ ๊ฑด ์ฐ๋ฆฌ๋ ์ํด, ์ธ๋ถ๋ ์ํด, ์ฌ์ฉ์๋ ๋ ํฐ ์ํด์ ๋๋ค. ์ด๋ ๊ฐ์ฅ ์ ๋ง๋ ํจํด์ด ์ํท ๋ธ๋ ์ด์ปค(Circuit Breaker)์ด๋ผ๊ณ ์๊ฐํ์ต๋๋ค. ์ํท ๋ธ๋ ์ด์ปค๋ ์ธ๋ถ ์์กด์ฑ์ด ์ผ์ ๊ธฐ์ค ์ด์ ์คํจํ๋ฉด ํ๋ก๋ฅผ ์ด์ด(Open) ์์ฒญ์ ์ฐจ๋จํ๊ณ , ์ ์ ์ํ(CLOSED), ํ์ ์ํ(HALF_OPEN)๋ฅผ ์ด์ฉํด ์์คํ ์ ๋ณดํธํ๋ ํจํด์ ๋๋ค. ์ ๋ ์ด ํจํด์ ๋จ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก ๋ถ์ด๋ ๊ฒ์ด ์๋๋ผ, ์ฐ๋ฆฌ ์์คํ ์ ์ด์ ๋ฐฉ์์ ๋ง๊ฒ “์ ์ฑ /๋ฃฐ”๋ก ๊ตฌํํ์ต๋๋ค.
์ฒ์์๋ ๊ณต์ฉ ์ ์ฅ์์ธ Redis์ ์์ง์ฒ๋ณ ์คํจ ์นด์ดํธ๋ฅผ ๋์ ํ๊ณ , ์๊ณ์น ์ด๊ณผ ์ ์๋ ์ฐจ๋จํ๋ ๊ตฌ์กฐ๋ฅผ ๋ ์ฌ๋ ธ์ต๋๋ค.
ํ์ง๋ง ์ฌ๋ด์๋ ๋งค ์ด ๋ฃฐ์ ํ๊ฐํ๋ ๊ณต์ฉ ์์คํ ์ด ์ด๋ฏธ ์กด์ฌํ๊ณ , ๋ถ๋ฌธ์ฅ๋ ๊ถ์ ๋ก ๊ทธ ์๋น์ค๋ฅผ ๋จผ์ ํ์ฉํ๊ธฐ๋ก ํ์ต๋๋ค. 12์ 17์ผ SSG ์ฅ์ ๋น์ ๋จ์ ๋ก๊ทธ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก, “์ฌ๋ผ์ด๋ฉ ์๋์ฐ ์๊ณ ๋ฆฌ์ฆ์ ํ์ฉํด, ์ต๊ทผ ์ผ์ ์๊ฐ ์ฌ๋ผ์ด์ค ์์์ ์คํจ๊ฐ ์ผ๋ง๋ ๋ฐ์ํ๋ฉด ์ฅ์ ๋ก ๋ณผ ๊ฒ์ธ๊ฐ”๋ฅผ ๋ฃฐ๋ก ์ ์ํ์ต๋๋ค.
์๋ฌ ๋ก๊ทธ ์คํ์ดํฌ๊ฐ ๋ชฐ๋ ธ์ ๋ 1๋ถ ์ฌ์ด์ 10๊ฑด, ํ๊ท ์ ์ผ๋ก 4.4๊ฑด์ด ๋ฐ์ํ์ต๋๋ค. ์คํจ ์ง๊ณ ์๋์ฐ๋ฅผ 30์ด๋ก ์ก๊ณ , ์คํจ ์นด์ดํธ ์ญ์น ๊ฐ์ 5ํ๋ก ํด๋ณด๊ธฐ๋ก ํ์์ต๋๋ค.
OPEN ์ํ ์ง์์๊ฐ๊ณผ HALF_OPEN ์ ์ด๋ป๊ฒ ํ ์ง์ ๋ํด์๋ ๋ ผ์ํ์ต๋๋ค. ์ํท ๋ธ๋ ์ด์ปค๋ ํ๋ณต ํ๋ ฅ์ฑ ๊ด์ ์์ Half-Open์ ํตํ ์๋ ํ๋ณต ํ์ง๊ฐ ์ผ๋ฐ์ ์ด์ง๋ง, ์ ํฌ ์กฐ์ง์์๋ ์ธ๋ถ ์ฅ์ ์ ์์ธ ํ์ ๊ณผ ์์ ์ฑ ํ์ธ์ด ๋ ์ค์ํ๋ค๊ณ ํ๋จํ์ต๋๋ค.
๊ทธ๋์ ํ์ ์ดํ ๊ฒฐ๋ก ์ “์๋ Half-Open์ผ๋ก ์กฐ๊ธ์ฉ ์ด์ด๋ณด๋ ๋ฐฉ์”์ด ์๋๋ผ, ์ฌ๋์ด ์์ธ์ ํ์ธํ๊ณ , ์์ ์ฑ์ ๊ฐ์์ ์ผ๋ก ํ์ธํ ๋ค ์๋์ผ๋ก ์คํํ๋ ์ด์ ์ ์ฑ ์ด์์ต๋๋ค.
์ด๋ฐ ์ ํ์ ์๋ํ ์์ค์ ์ผ๋ถ ๋ฎ์ถ๋ ๋์ , ๋ถํ์ํ ์ฌํญ๋ฐ์ ๋ง๊ณ ์ด์ ๋ฆฌ์คํฌ๋ฅผ ์ค์ด๋ ๋ฐฉํฅ์ ๋๋ค. ์์คํ ์ค๊ณ์์ ์ด๋ฐ ํธ๋ ์ด๋์คํ๋ ๋ ์กด์ฌํ๊ณ , ์ด๋ฒ์ ์ด์ ์์ ์ชฝ์ ํํ์ต๋๋ค.

์ฐจ๋จ์ด ๋ฐ์ํ๋ฉด, ์ธ๋ถ ์์ง ๊ธฐ๋ฅ on/off๋ฅผ ๊ด๋ฆฌํ๋ Redis ์ํ๊ฐ์ off ๋ก ๋ง๋ค์ด ์ฌ์ฉ์์ ์์ฒญ ์์ฒด๋ฅผ ๋ง์ต๋๋ค. ์ฌ์ฉ์๋ ์ธ๋ถ ์ฌ์ดํธ ๋ณ๊ฒฝ์ผ๋ก ์ธํด ๊ธฐ๋ฅ์ ์ฌ์ฉํ์ง ๋ชปํ๋ค๋ ์๋ฆผ์ฐฝ์ ๋ฐ์ ์ ์์ต๋๋ค.

๊ทธ๋ฆฌ๊ณ “โโ์์ง์ฒ๊ฐ ์์คํ ์ ์ํด ์๋ ์ฐจ๋จ๋์๋ค”๋ ์ด๋ฒคํธ๋ฅผ ํ ๋ด ์๋ฌ ๋ก๊ทธ ์๋ฆผ๋ฐฉ์ผ๋ก ๋ณด๋ด ์ด์์๊ฐ ์ฆ์ ์ธ์งํ ์ ์๊ฒ ํ์ต๋๋ค. ๋ํ ์คํ(์ผ์์ ์ค๋ฅ๋ฅผ ์ฅ์ ๋ก ํ๋จํ๋ ์ผ์ด์ค)์ ๋๋นํด, ์ํท ๋ธ๋ ์ด์ปค๋ฅผ ์๋์ผ๋ก ๋๊ณ ์ผค ์ ์๋ ๊ธฐ๋ฅ๋ ์ ๊ณตํ์ต๋๋ค. ์ธ๋ถ ์๋ฒ์ ์ฅ์ ๊ฐ ๋ฐ์ํด ๋ ๋ค์ ์คํจ ๋ก๊ทธ๊ฐ ๋จ๋๋ค๋ฉด ๊ทธ ์์์ ํ์ ํด ์ค์ ๊ฐ์ ํ๋ํด ๋๊ฐ๊ธฐ๋ก ํ์ต๋๋ค.
“์์ธ ์ฒ๋ฆฌ ๋์๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๊ธ๋ก๋ฒ ์ต์ ์ ํธ๋ค๋ฌ ๊ฐ๋ฐ๊ณผ ์คํฌ๋ํ ๋ชจ๋ ๋ฆฌํฉํ ๋ง”
๊ธฐ์กด ์คํฌ๋ํ ๋ชจ๋์ ์๋ฌ๋ ๊ณต์ฉ PTP ๋ก๊ทธ๋ก๋ง ์์ด๊ณ , ๋ชจ๋ํฐ๋ง ํ์ด ์ฃผ๋ก ๋จผ์ ๋์ํ๋ ๊ตฌ์กฐ์์ต๋๋ค. ํ์ง๋ง ์ด๋ฒ ๊ฐ์ ์ ์ ์ํ๋ ๊ณผ์ ์์, ๋ถ๋ฌธ์ฅ๋๊ป์ “์คํฌ๋ํ/API ํ ์์ฒด ๋ก๊ทธ ํ
์ด๋ธ์ ๋ง๋ค๊ณ ์ด์ ์ฃผ์ฒด๋ฅผ ์ฐ๋ฆฌ ํ์ด ๊ฐ์ ธ๊ฐ์”๊ณ ๊ฒฐ์ ํด์ฃผ์
จ์ต๋๋ค. ์ด๊ฑธ ํตํด ๋ฐ์ํ๋ ๋ฌธ์ ๋ฅผ ํ๋ด์์ ๋จผ์ ๋ชจ๋ํฐ๋งํด ์ฃผ๋์ ์ผ๋ก ๊ฐ์ ํ๋๋ก ์ง์ํ์
จ์ต๋๋ค.
์์
์ ์์์ธ ์ ์๊ฒ ์ ๋ฐ์ ์ธ ๊ถํ์ ์ฃผ์
์ ์ง์ ์คํจ ์ด๋ ฅ ํ
์ด๋ธ์ ์ค๊ณํ๊ณ , ์ด๋ค ๋จ๊ณ์์ ์๋ฌ ๋ฐ์์ ํ์ํ ๊ตฌ๋ถ๊ฐ ๋ฑ์ ์ ํ์ต๋๋ค. ๋ด๋น ๋ชจ๋ํฐ๋ง ๋๋ฃ๊ฐ ํ์์ ์ํ๋ ๊ตฌ๋ถ๊ฐ(์๋ฒ/์ด์์คํดํธ, ๋ฒ์ธ/๊ฐ์ธ, ๋ด๋ถ ์์ค ๋ฌธ์ /์ธ๋ถ ํต์ ๋ฌธ์ ๋ฑ)์ ์คํค๋ง์ ํฌํจํด, ๋ฌธ์ ๊ฐ ํฐ์ก์ ๋ “์์ธ ๋ถ๋ฅ”๊ฐ ๋นจ๋ผ์ง๋๋ก ํ์ต๋๋ค.(๊ด๋ฆฌ์ ํ๋ฉด ๋ ๋๋ง ๋ํ๋ ๋ค๋ฅธ ๊ฐ๋ฐ์ ๋ด๋น์ด๋ผ ๋ฏธ์์ฑ๋์ด ๋ณด์ง ๋ชปํ์ง๋ง dual write ํ์ฌ ์ผ๋จ์ ๊ณต์ฉ ptp ๋ก๊ทธ๋ก ํ์ธํ๊ณ ์์ต๋๋ค.)
์์ธ ์ฒ๋ฆฌ ๋์๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๊ธ๋ก๋ฒ ์ต์ ์ ํธ๋ค๋ฌ๋ฅผ ๋ง๋ค์์ต๋๋ค.
์ ์ญ์ ์ธ ์์ธ ์ฒ๋ฆฌ๋ฅผ ํ ๋ “๊ฐ ํ์ผ์์ ํ๋ ๊ตฌ์กฐ”๋ก ๋์ง ์์์ต๋๋ค. ์ ๋ TypeScript ๋ฉ์๋ ๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ๋ง๋ค์ด ์คํฌ๋ํ ๋ชจ๋์ ์ง์ ์ ์ ์ ์ญ ์์ธ ์ฒ๋ฆฌ๋ฅผ ๊ฑธ์์ต๋๋ค. ์์ด๋์ด๋ Spring Boot์ @RestControllerAdvice์์ ๊ฐ์ ธ์์ต๋๋ค.
try {
// ํธ๋ค๋ฌ(์ปจํธ๋กค๋ฌ ๋ฉ์๋) ํธ์ถ
} catch (Exception ex) {
// ์ฌ๊ธฐ์ "์์ธ ์ฒ๋ฆฌ ์ฒด์ธ"์ผ๋ก ๋๊น
processHandlerException(ex);
}
Spring์์ ์ ์ญ ์์ธ ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅํ ์ด์ ๋, ์ปจํธ๋กค๋ฌ ๊ฐ๊ฐ์ try/catch๋ก ๊ฐ์ธ๊ธฐ ๋๋ฌธ์ด ์๋๋ผ ์์ฒญ์ ์ง์ ์ (DispatcherServlet)์์ ์์ธ๋ฅผ ํ ๋ฒ ์ก์ ๊ณตํต ์ ์ฑ ์ผ๋ก ์๋ต์ ๋งคํํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
์ฆ, “์ง์ ์ ์ Around๋ก ๊ฐ์ผ๋ค”๋ ๋ฐ์์ ๋๋ค.
์ด๋ฅผ ์คํฌ๋ํ ๋ชจ๋๋ก ์ฎ๊ธฐ๋ฉด, ํ ํฝ์ ๊ตฌ๋ ํด ์คํ๋๋ Action์ด “์์ฒญ์ ์ต์ด ์ง์ ์ ” ์ญํ ์ ํฉ๋๋ค. ์คํฌ๋ํ ๋ชจ๋์ ํ ํ๋ฆฟ ๋ฉ์๋ ํจํด์ ์ํด ๋ชจ๋ Action์ ์คํ ํจ์๊ฐ executeCore()๋ก ์ ํด์ ธ ์์ผ๋, ์ ๋ ์ฌ๊ธฐ์ ๋ฉ์๋ ๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ๋ฌ์ executeCore()๋ฅผ Around Advice์ฒ๋ผ ๋ํํ์ต๋๋ค.
export function _global_exception_handle(
target: any,
property_key: string,
descriptor: PropertyDescriptor
) {
const original_method = descriptor.value;
descriptor.value = function (context: IExecutionContext, request: any) {
try {
return original_method.call(this, context, request);
} catch (exception: unknown) {
_globalExceptionHandle(context, exception, request);
}
};
return descriptor;
}
function _globalExceptionHandle(
execution_context: IExecutionContext,
exception: unknown,
request: any
): void {
const global_exception_handler =
execution_context.getFeature<IScrapingGlobalErrorHandlerFeature>(
IScrapingGlobalErrorHandlerFeature
);
if (!(exception instanceof Error)) {
global_exception_handler.handleUnknownThrown?.(exception, request);
return;
}
switch (exception.name ?? '') {
case SCRAPING_ERROR_TYPE.SCRAP_ERROR:
global_exception_handler.handleScrapError(exception, request);
return;
case SCRAPING_ERROR_TYPE.E2E_ERROR:
global_exception_handler.handleE2EError(exception, request);
return;
case SCRAPING_ERROR_TYPE.HTTP_CLIENT_ERROR:
global_exception_handler.handleExternalHttpClientError(exception, request);
return;
case SCRAPING_ERROR_TYPE.ASSITANT_ERROR:
global_exception_handler.handleAssistantError(exception, request);
return;
case SCRAPING_ERROR_TYPE.REDIS_CLIENT_ERROR:
global_exception_handler.handleExternalRedisClientError(exception, request);
return;
case SCRAPING_ERROR_TYPE.NETWORK_ERROR:
global_exception_handler.handleNetworkError(exception, request);
return;
default:
global_exception_handler.handleUnknownError(exception, request);
return;
}
}
์ด ๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ํตํด ์์ธ ์ฒ๋ฆฌ ์ ์ฑ ์ด ๋ฐ๋ ๋๋ง๋ค ๊ด๋ จ๋ ๋ชจ๋ ํ์ผ์ ์ฐพ์ ์์ ํ ํ์๊ฐ ์์ด์ก์ต๋๋ค. ๊ฐ ๋จ๊ณ๋ณ๋ก ์ ํฉํ ์ปค์คํ ์๋ฌ(“์ด๋ค ์คํจ์ธ์ง”, "์ฌ์ฉ์์๊ฒ ๋ณด์ผ ๋ฌธ๊ตฌ"๋ฅผ ํ๋กํผํฐ๋ก ๊ฐ์)๋ฅผ ๋์ง๊ณ , ๊ธ๋ก๋ฒ ํธ๋ค๋ฌ๊ฐ ๊ทธ ์๋ฌ๋ฅผ ๋ถ๋ฅํด ๋ก๊ทธ๋ฅผ ์ ์ฌํ๊ณ , ์ด๋ ฅ์ ์คํจ๋ก ์ ๋ฐ์ดํธํ๋ ํ ํฝ์ sendํ๊ณ , ์ฌ์ฉ์์๊ฒ ๋ณด์ฌ์ค ๋ฉ์์ง๋ฅผ ํ์คํํฉ๋๋ค.(AOP)
์ฆ, ์์ธ ๋ฐ์ ์์ ์ ๊ทธ๋๋ก ์ ์งํ๋ฉด์, ์ฒ๋ฆฌ ์ ์ฑ ๋ง ์ค์์ผ๋ก ๋ชจ์ผ๋ ๊ตฌ์กฐ๊ฐ ๋ฉ๋๋ค.


์ด ๋ฐฉ์์ try/catch + ๋ถ๊ธฐ ๋ก์ง์ด ์์ฌ ์์ด “๋น์ฆ๋์ค ๋ก์ง + ์์ธ ์ฒ๋ฆฌ”๊ฐ ๋ค์ํค๋ ๊ตฌ์กฐ์์, "์๋ฌ ์ฒ๋ฆฌ"๋ผ๋ ๊ด์ฌ์ฌ๋ฅผ ๋ถ๋ฆฌํด ์์ค์ ๊ฐ๋ ์ฑ๊ณผ ์ ์ง๋ณด์์ฑ์ ๋์์ ์ฌ๋ฆฝ๋๋ค.
๋ฌด์๋ณด๋ค ์ค์ํ ๊ฑด, ์ง์ ์ ์์ try/catch๊ฐ ๋ณด์ฅ๋๊ธฐ ๋๋ฌธ์ ์์ธ๊ฐ ์์ด ๋๊ฐ ๋น์ ์ ์ข ๋ฃ๋๋ ์ผ์ด์ค๊ฐ ๊ตฌ์กฐ์ ์ผ๋ก ์๋ฒฝํ๊ฒ ์์ด์ง๋ค๋ ์ ์ ๋๋ค.
๐Result - ๊ฒฐ๊ณผ ๋ฐ ์ฑ๊ณผ
์คํจ๋ ์ค์๊ณ , ๋์๋ ๋งํ๊ณ , ์ด์์ ์๋ํ๋๋ค.
์ด ๊ฐ์ ์ ๊ฒฐ๊ณผ๋ “์์ ์ฑ”์ด๋ผ๋ ์ถ์์ ์ธ ๋จ์ด๋ก๋ง ์ค๋ช ํ๊ธฐ์ ์์ฌ์ธ ์ ๋๋ก ๊ตฌ์ฒด์ ์ด์์ต๋๋ค.
“ํ์์์ ์ค์ ๊ณผ ๋ฆฌํธ๋ผ์ด ์ ์ฉ์ผ๋ก ๋๋ฆฐ ์์ฒญ 2๊ฐ ๊ด์ธก ๋ฐ ์คํจ์จ 95.24% ๊ฐ์”
์ฐ์ , HTTP timeout์ 5์ด๋ก ๋ช ํํ ์ค์ ํ๋ฉด์ “๋๋ฆฐ ์์ฒญ”์ด ๊ด์ธก๋๊ธฐ ์์ํ์ต๋๋ค. ์ด์ ์๋ Action timeout์ ๋ฌปํ ์์ธ์ ๋ณด๊ธฐ ์ด๋ ค์ ๋ ์ง์ฐ์ด, ํต์ ๋จ๊ณ์์ ๋ถ๋ฆฌ๋๋ฉฐ ๋๋ฌ๋ ๊ฒ์ ๋๋ค. ๊ทธ ๊ณผ์ ์์ ์ง์ฐ์จ์ด ๋์ ์์ฒญ 2๊ฑด์ ์ฐพ์ ์กฐ์นํ์ต๋๋ค. ํ๋ ์ด์คํ EMP ์ํ ์กฐํ API๋ ํ ๋ฒ์ ๋ชจ๋ ์ฃผ๋ฌธ์ํ๋ฅผ 500๊ฑด ์กฐํํ๋ฉฐ 10์ด๊ฐ ๊ฑธ๋ฆฌ๊ณ ์์๊ณ , ํ์ฅ๋๊ณผ ์์ ํ 200๊ฑด์ฉ ์กฐํํ๋๋ก ์์ ํ์ต๋๋ค.
์ฟ ํก “์ํ ์ฒ๋ฆฌ์ค” API(์ฃผ๋ฌธ์ํ ๋ณ๊ฒฝ PUT๋ฉ์๋)๋ 50๊ฑด ๋ฐฐ์น ์ฒ๋ฆฌ ์ 6์ด๊ฐ๋ ๊ฑธ๋ฆฌ๋ ๊ฒ์ ํ์ธํ๊ณ , 20๊ฑด์ฉ ๋ณด๋ด๋๋ก ์กฐ์ ํ์ต๋๋ค. ์ด ๊ณผ์ ์์ ์ค์ํ ์ฌ์ค๋ ํ์ธํ์ต๋๋ค.

PUT ๋ฉ์๋ ์์ฒญ์ด๋ผ ๋ฉฑ๋ฑ์ฑ์ด ๋ณด์ฅ๋ ๊ฒ์ด๋ฏ๋ก ํ์์์ ํ ์ฌ์๋ํด๋ ์์ ํ ๊ฒ์ด๋ผ ๊ธฐ๋ํ์ง๋ง, ์ค์ ๋ก๋ “๋ฐฐ์ก์ํ๋ฅผ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค. ์ฃผ๋ฌธ๋ด์ญ์ ํ์ธํด์ฃผ์ธ์” ๊ฐ์ ์คํจ ์ฒ๋ฆฌ๊ฐ ๋ฐ์ํ์ต๋๋ค.
๊ทธ๋์ ํด๋น ์ ํ์ ์์ฒญ์ ๋ฆฌํธ๋ผ์ด ๋์์์ ์ ์ธํ๋ ์ ์ฑ ์ ํ ๋ด์์ ํ์ ํ๊ณ , “๊ธฐ์ ์ ์ผ๋ก ๊ทธ๋ด ๋ฏํ ๊ฐ์ ”๋ณด๋ค “์ค์ ์ธ๋ถ API์ ๋์”์ ๊ธฐ์ค์ผ๋ก ์ ์ฑ ์ ๋ค์ ์ก๋ ๊ณ๊ธฐ๊ฐ ๋์ต๋๋ค.
์ ๋์ ์ผ๋ก ๋ณด๋ฉด, ์์ ์ผ 5์ผ ๊ธฐ์ค HTTP ์์ฒญ ์คํจ ์ผ์ด์ค๊ฐ ๋ฐฐํฌ ์ ์๋ 21๊ฑด ์์์ง๋ง ๋ฐฐํฌ ํ ๋์ผ ์กฐ๊ฑด์์ 1๊ฑด์ผ๋ก ์ค์์ต๋๋ค. ๊ฐ์์จ๋ก ๊ณ์ฐํ๋ฉด ์ฝ 95.24%์ ๋๋ค.


๋จ์ํ ๋ฆฌํธ๋ผ์ด๋ฅผ ๋ฃ์ด์ ์ค์ด๋ ๊ฒ ์๋๋๋ค. timeout์ผ๋ก ์คํจ๋ฅผ ๋น ๋ฅด๊ฒ ๋ถ๋ฅํ๊ณ , retry๋ก ๊ฐํ ์คํจ๋ฅผ ํก์ํ๊ณ , ์ํํ ์ ๋ฌด์ ์ ์ฑ ์ผ๋ก ์ ์ธํ๋ “๊ท ํ ์กํ ์คํจ ์ฒ๋ฆฌ”๊ฐ ์๋ํ ๊ฒฐ๊ณผ์์ต๋๋ค. ์ด ์์น๋ ์ฌ์ฉ์ ๊ฒฝํ์ ์ง์ ์ ์ผ๋ก ๋์ด์ฌ๋ฆฝ๋๋ค. ์ฌ์ฉ์๊ฐ ๋๋ผ๋ ๊ฑด “์ฑ๊ณต/์คํจ์จ”์ด๊ณ , ์ฑ๊ณต๋ฅ ์ ์์ ์์น์ ๋ฐ๋ณต ์ฌ์ฉ ์๋น์ค์์ ์ฒด๊ฐ ์ฐจ์ด๊ฐ ํฌ๊ฒ ๋ํ๋๋ค๊ณ ์๊ฐํฉ๋๋ค.
“7832๊ฐ์ ๊ณ ๊ฐ์ฌ์์ ์ฌ์ฉํ๋ ์ผํ๋ชฐ ๊ธฐ๋ฅ ์์ ํ ๋ฐ ์คํฌ๋ํ ๋ชจ๋ ๋ด ์๋ฌ 100% ์ฒ๋ฆฌ”
๋ํ 7,832๊ฐ์ ๊ณ ๊ฐ์ฌ๊ฐ ์ฌ์ฉํ๋ ์ผํ๋ชฐ ๊ธฐ๋ฅ ๊ด์ ์์๋ ์๋ฏธ๊ฐ ์ปธ์ต๋๋ค. ์์ฒญ ์ง์ ์ ์ ๋ฉ์๋ ๋ฐ์ฝ๋ ์ดํฐ ๊ธฐ๋ฐ ์ ์ญ try/catch๊ฐ ๊ฑธ๋ฆฌ๋ฉด์, ๊ธฐ์กด์ ๋์๋๋ ์์ธ๋ก ์ธํด ์ด๋ ฅ์ด ์งํ์ค์ผ๋ก ๋จ๊ฑฐ๋, ์๋ฌ ๋ฌธ๊ตฌ๊ฐ ๊ทธ๋๋ก ๋ ธ์ถ๋๋ ๋ฌธ์ ๊ฐ ๊ตฌ์กฐ์ ์ผ๋ก ์ ๋ฆฌ๋์์ต๋๋ค.
๋คํธ์ํฌ ๋ฌธ์ ๋ ์ธํ๋ผ ์ฅ์ ๊ฐ ์๋ ์ด์, ์ฌ์ฉ์๋ ์์ ๊ฒฐ๊ณผ๋ฅผ “์ฑ๊ณต/์คํจ๋ก ๋ช ํํ” ํ์ธํ ์ ์๊ณ , ์คํจํ๋๋ผ๋ ์ฌ์ฉ์ ์นํ์ ์ธ ๋ฉ์์ง๋ก ์๋ด๋ฐ๊ฒ ๋ฉ๋๋ค. ์ ์ ์๋ ์๋ฌ๋ default ์คํจ ๋ฌธ๊ตฌ๋ก ์ฒ๋ฆฌํด “์๋ฌ ์๋ฌธ ๋ ธ์ถ” ๋ฌธ์ ๋ฅผ ์ ๊ฑฐํ์ต๋๋ค. ์์ธ ์ฒ๋ฆฌ ์ ์ฑ ์ ์ฝ๋ ๊ณณ๊ณณ์์ ํต์ ํ๋ ๋์ , ์ ์ญ ํธ๋ค๋ฌ ํ๋๋ก ๋ชจ์ ๊ด๋ฆฌํ๋ ๊ตฌ์กฐ๊ฐ ๋๊ธฐ ๋๋ฌธ์ ์ดํ ์ ์ฑ ๋ณ๊ฒฝ๋ ํจ์ฌ ์ฌ์์ก์ต๋๋ค.
“์ด์์์ ํ๋จ์ด ์๋ ์์คํ ์ ์ํด ์๋์ผ๋ก ๊ธฐ๋ฅ ์ฐจ๋จ”
๋ง์ง๋ง์ผ๋ก, ์ํท ๋ธ๋ ์ด์ปค ๊ธฐ๋ฐ ์๋ ์ฐจ๋จ์ “๊ฐ๋ฐ์๋ ์ด์์๊ฐ ํ๋จํด์ ๋ง๋ ์ด์”์์ “์์คํ ์ด ๋จผ์ ๋ณดํธํ๋ ์ด์”์ผ๋ก ์ ํ์์ผ์ค๋๋ค.
์ธ๋ถ ์ฅ์ ๊ฐ ์์ฌ๋๋ฉด ์์ฒญ์ Fail Fast๋ก ์ฐจ๋จํด ๋ ๋ง์ ์ฌ์ฉ์๊ฐ ์คํจ๋ฅผ ๊ฒฝํํ๊ธฐ ์ ์ ๋ณดํธํ ์ ์๊ณ , ๋ก๊ทธ ํญ๋ฐ์ ๋ฐฉ์งํ๋ฉฐ, ์ธ๋ถ ๋ฆฌ์์ค ์๋ฒ์๋ ๋ถํ์ํ ํธ๋ํฝ์ ์ค์ผ ์ ์์ต๋๋ค.
์ด๋ฒ ๊ธ ์์ฑ ์์ ์๋ “์ค์ ์ธ๋ถ ์๋ฒ ๋๊ท๋ชจ ์ฅ์ ์ฌ๋ฐ”์ด ์์ด ๋ก๊ทธ ํญ๋ฐ ์ /ํ ๋น๊ต ์์น๋ฅผ ์์ง ๋ง๋ค์ง ๋ชปํ์ง๋ง, ๊ตฌ์กฐ ์์ฒด๋ ์ฅ์ ๊ฐ ๋ค์ ์ฌ ๋ ํ์คํ๊ฒ ํจ๊ณผ๋ฅผ ๋ณผ ์ ์๋ ํํ๋ก ์ค๋น๋์์ต๋๋ค. ๋ฌด์๋ณด๋ค ์ค์ํ ๊ฑด, ์ฅ์ ๊ฐ ์์ ๋ “์ฌ๋์ด ์์์ฐจ๋ฆด ๋๊น์ง ๊ธฐ๋ค๋ฆฌ๋ ๊ตฌ์กฐ”๊ฐ ์๋๋ผ, ์๋์ผ๋ก ์์คํ ์ด ๋จผ์ ์คํจ๋ฅผ ํต์ ํ๋ ๊ตฌ์กฐ๊ฐ ๋๋ค๋ ์ ์ ๋๋ค.
“์ฃผ๋์ ์ธ ๋ฌธ์ ํด๊ฒฐ ์์ธ์ ๋ฌธ์ ํด๊ฒฐ ๋ฅ๋ ฅ์ ๋ํด ์นญ์ฐฌ”
์ ๊น์ ์ธ๋ถ ์๋ฒ ์ฅ์ ๋ก๋ '์ฅ์ ๊ฐ ํด๊ฒฐ ๋์ผ๋, ๋ค์ ์๋น์ค ์ ์ ๋์'์ผ๋ก ๋๋์ง ์๊ณ , ๊ทผ๋ณธ์ ์ธ ๋ฌธ์ ์ ์ ์ฐพ์๋ด์ด ์ด์ ๋ํด ๊ฐ์ ๋ฐฉ์์ ๋จผ์ ์ฌ๋ด์ ์ ์ํ ์ ์ ๋ํด ๋์ ์นญ์ฐฌ์ ๋ฐ์ ์ ์์์ต๋๋ค.

๋จ์ํ ๋ก๊ทธ๋ฅผ ํ์ ํ๊ณ ๋จ๋ฐ์ฑ์ผ๋ก ์์ตํ๋ ์์ค์ด ์๋๋ผ, “์ ์ด๋ฐ ์ฅ์ ์์ ๋ก๊ทธ๊ฐ ํญ๋ฐํ๋์ง”, “์ ์ฌ์ฉ์์๊ฒ ์๋ฌ๊ฐ ๊ทธ๋๋ก ๋ ธ์ถ๋๋์ง”, “์ ์คํจ ์ด๋ ฅ์ด ‘์งํ์ค’์ผ๋ก ๋จ๋์ง” ๊ฐ์ ๊ตฌ์กฐ์ ์ธ ์์ธ์ ๋๊น์ง ํ๊ณ ๋ค์ด ์ ๋ฆฌํ ํ๋๋ฅผ ์ข๊ฒ ํ๊ฐํด์ฃผ์ จ์ต๋๋ค.
๊ฒฐ๊ณผ์ ์ผ๋ก ์ด๋ฒ ๊ฐ์ ์ ๋จ์ํ ๊ธฐ๋ฅ ํจ์น๊ฐ ์๋๋ผ, ์๋น์ค ์์ ์ฑ๊ณผ ์ฌ์ฉ์ ๊ฒฝํ์ ํจ๊ป ๋์ด์ฌ๋ฆฌ๋ ์คํจ ์ฒ๋ฆฌ ์ฒด๊ณ๋ก ์ด์ด์ก๊ณ , ์ ์ญ์ ์ฅ์ ๋์์ ‘์ฌํ ์ฒ๋ฆฌ’๊ฐ ์๋๋ผ ์ฌ๋ฐ์ ๋ง๋ ๊ตฌ์กฐ ๊ฐ์ ์ผ๋ก ํ์ฅํ๋ ๋ฐฉ์์ ์ฒด๋ํ ์ ์์์ต๋๋ค.
โ๏ธ๋ง๋ฌด๋ฆฌ
์ด๋ฒ ์์
์ HTTP timeout ๊ฐ์ ๋ช ์ด๋ก ๋ฐ๊พธ๊ณ , retry๋ฅผ 2ํ ๋ฃ๋ ์ ๋์ ๋ณ๊ฒฝ์ด ์๋์์ต๋๋ค. ์คํจ๋ฅผ ์ด๋ป๊ฒ ๊ด์ธกํ๊ณ , ์ด๋ป๊ฒ ๋ถ๋ฅํ๊ณ , ์ด๋ป๊ฒ ์ฒ๋ฆฌํ๊ณ , ์ด๋์ ์ ์ฑ
์ ๊ด๋ฆฌํ ์ง๊น์ง ํฌํจํ “์คํจ ์ฒ๋ฆฌ ์ฒด๊ณ”๋ฅผ ๋ง๋ ์์
์ด์์ต๋๋ค.
์ธ๋ถ ์ฅ์ ๋ ์ธ์ ๋ ์ต๋๋ค. ํ์ง๋ง ์ธ๋ถ ์ฅ์ ๊ฐ ์์ ๋ ์ฐ๋ฆฌ ์์คํ
์ด ํด์ผ ํ ์ผ์ ๋ช
ํํฉ๋๋ค. ํต์ ๋จ๊ณ์์ ์ ์ ํ ๋๊ณ , ๊ฐํ ์คํจ๋ ํก์ํ๋ ์ํํ ์
๋ฌด์ ๋ณดํธํ๊ณ , ์ฅ์ ๊ตฌ๊ฐ์์๋ ๋ ํฐ ์คํจ๊ฐ ์ค๊ธฐ ์ ์ ์๋์ผ๋ก ์ฐจ๋จํ๋ฉฐ, ์ด๋ค ์์ธ๊ฐ ๋ฐ์ํด๋ ์ฌ์ฉ์์๊ฒ๋ ์ผ๊ด๋ ๊ฒฐ๊ณผ์ ๋ฉ์์ง๋ฅผ ์ ๊ณตํด์ผ ํฉ๋๋ค.
์ด๋ฒ ๊ฐ์ ์์ ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ ๋ ์ ๋ง ๊ทผ๋ณธ์ ์ธ ๋ฌธ์ ์ ์ ์ฐพ๊ณ (์ฌ๋ด ์๋ฌ ์ฒ๋ฆฌ), ๋ฌธ์ ์ ์ ํด๊ฒฐํ๊ณ (์ ์ ํ ์ ์ฑ ๊ณผ ๊ธฐ์ ์ ์ ๋ต), ๋ ๋ค์ ๊ด๋ จ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ ๋ ๋ฐฉ์ด๋ ์ด๋ป๊ฒ ์๋ํ ํด๋ณผ ์ ์๋์ง(ํด๋ฐฑ ํ๋ก์ธ์ค) ๊ณ ๋ฏผ์ ๋ํ ์ ๋ง์ ๊ตฌํ ๋ฐ ํด๊ฒฐ๋ฐฉ์์ ๋์ถํด ๋ด๋ ์ข์ ๊ฒฝํ์ด๋์ต๋๋ค.
๋๊ธ