์ธ๋ถ API๋ฅผ ์ฐ๋ํ ๋ ๊ณ ๋ คํ๋ฉด ์ข์ ์ ๋ค
๊ฐ์
์ต๊ทผ ํ๋ก์ ํธ์์ ์ธ๋ถ API๋ฅผ ์ฐ๋ํ๋ ์ผ์ด ๊ต์ฅํ ๋ง์์๋๋ฐ, ์์ ํ๋ฉด์ ์ป์ ๋ค์ํ ๊ฒฝํ๊ณผ ์ง์์ ๊ณต์ ํ๊ณ ์ ์์ฑํ๊ฒ ๋์์ต๋๋ค. ํผ๋๋ฐฑ์ ์ธ์ ๋ ํ์์ด๋ฉฐ ๋๊ธ ๋จ๊ฒจ์ฃผ์๋ฉด ๊ฐ์ฌํ๊ฒ ์ต๋๋ค.
1. I/O์ ํธ๋์ญ์ ์ ๋ถ๋ฆฌํด๋ผ
ํธ๋์ญ์ ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํต์ ํ๊ธฐ ์ํด ์ปค๋ฅ์ ์ ํ์๋ก ํ๋ค. ํ์ง๋ง ์ด ์ปค๋ฅ์ ์ ์์ฑํ๋ ๋ฐ๋ ๊ฝค ๋ง์ ๋น์ฉ์ด ๋ค๋ฉฐ, ๋๋ถ๋ถ ์ด๋ฅผ ์ ์ฝํ๊ธฐ ์ํด ์น ์ ํ๋ฆฌ์ผ์ด์ ์๋ฒ(WAS)๋ ์คํ ์ ๋ฏธ๋ฆฌ ์ผ์ ์์ ์ปค๋ฅ์ ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด ํ์ ์ ์ฅํ๋ค. ๊ทธ๋ฆฌ๊ณ ํด๋ผ์ด์ธํธ์ ์์ฒญ์ด ๋ฐ์ํ๋ฉด ์ด ํ์์ ์ด๋ฏธ ์์ฑ๋์ด ์๋ ์ปค๋ฅ์ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ์์ ์ด์ฉํ๋ค.
๊ทธ๋ฌ๋ ์ปค๋ฅ์ ํ์ ํฌ๊ธฐ๋ ์ ํ๋์ด ์๊ธฐ ๋๋ฌธ์, ๋์์ ์๋ง์ ์์ฒญ๋ค์ด ์ปค๋ฅ์ ํ์ ๊ฐ์ ์ด์์ผ๋ก ์ค๊ฒ ๋๋ค๋ฉด, ์ปค๋ฅ์ ์ ํ๋ํ์ง ๋ชปํ ์์ฒญ๋ค์ ๋ค๋ฅธ ์์ฒญ์ด ๋๋ ์ปค๋ฅ์ ์ด ๋ฐ๋ฉ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ๊ฒ ๋๊ธฐ ๋๋ฌธ์ ์ง์ฐ์ด ๋ฐ์ํ๊ฒ ๋๋ค.
์ด๋ฌํ ์ด์ ๋ก ๋ง์ฝ ํธ๋์ญ์ ๋ด๋ถ์ ์ธ๋ถ API๋ฅผ ํธ์ถํ๋ I/O๋ก์ง์ด ํฌํจ๋์ด ์๋ค๋ฉด, ๋ถํ์ํ๊ฒ ํธ๋์ญ์ ์ ๊ธธ๊ฒ ์ก๊ณ ์์ง ๋ง๋๋ก ํธ๋์ญ์ ๊ณผ I/O ๋ก์ง์ ๋ถ๋ฆฌํ๋ ๊ฒ์ด ์ข๋ค. ๋ค์์ ๋ฐฉ์๋ค์ ์ด์ฉํ๋ฉด ์์ฝ๊ฒ ๋ถ๋ฆฌํ ์ ์๋ค.
- ํผ์ฌ๋ ํจํด(Facade Pattern) ์ฌ์ฉ
- ์ด๋ฒคํธ ์ฌ์ฉ
ํผ์ฌ๋ ํจํด(Facade Pattern)์ ์ฌ์ฉํ๊ธฐ ๋ณต์กํ ํด๋์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๊ธฐ ํธํ๊ฒ ๊ฐ๋จํ ์ธํฐํ์ด์ค(API)๋ก ๊ตฌ์ฑํ๊ธฐ ์ํ ๊ตฌ์กฐ ํจํด์ด๋ค. ๋ณดํต ์์คํ ์ด ๋ณต์กํ๊ฑฐ๋ ์์คํ ์ ์ฌ์ฉํ๊ณ ์๋ ์ธ๋ถ์ ๊ฒฐํฉ๋๊ฐ ๋๋ฌด ๋์ ๋ ์์กด์ฑ์ ๋ฎ์ถ๊ธฐ ์ํด ์ฌ์ฉํ๋ค. ํน์ ์ํ ์์กด์ฑ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์๋ ์ฃผ๋ก ์ฌ์ฉํ๋ค.
@Service
public class FacadeExample {
// ์ธ๋ถ api ์ฐ๋ ํด๋์ค
private ExternalApiService apiService;
// ํธ๋์ญ์
์ ์ฒ๋ฆฌํ๋ ํด๋์ค
private DatabaseService databaseService;
public void saveDataFromExternalService(){
Object data = apiService.getData();
databaseService.save(data);
}
}
์ ์์์์ ํผ์ฌ๋ ํด๋์ค๋ ์ธ๋ถ I/O ๋ฐ์ดํฐ๋ฅผ ์์งํ๊ณ , ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅํ๋ ์ญํ ์ ํ๋ค. ์ด๋ฅผ ํตํด ์ธ๋ถ API ์์ฒญ๊ณผ ํธ๋์ญ์ ์ ๋ถ๋ฆฌํ ์ ์๋ค.
๋ ๋ฒ์งธ๋ ์ด๋ฒคํธ๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด๋ค. ์ด์ ์ ์ด ๊ธ์์ ํ๋ฒ ์ ๋ฆฌํ ์ ์ด ์๋ค.
์ด ๋ฐฉ์์ ํธ๋์ญ์ ์ด ์ฑ๊ณต์ ์ผ๋ก ์ข ๋ฃ๋ ํ์ ํน์ ์์ ์ ์ํํ๋ ๊ฒฝ์ฐ์ ํจ๊ณผ์ ์ด๋ค.
์๋ฅผ ๋ค์ด, ํ์๊ฐ์ ํ ์ถํ ๋ฉ์ผ์ ์ ์กํ๋ ์ธ๋ถ API ํธ์ถ์ด ํ์ํ ์ํฉ์ ๊ฐ์ ํด ๋ณด์. ์ด ๊ฒฝ์ฐ ๋ฐ์ดํฐ์ ์ผ๊ด์ฑ์ ๋ณด์ฅํ๊ธฐ ์ํด ํธ๋์ญ์ ์ด ์ฑ๊ณต์ ์ผ๋ก ์ข ๋ฃ๋ ํ์๋ง ๋ฉ์ผ์ด ์ ์ก๋์ด์ผ ํ๋ค. ์ด๋ฅผ ์ํด ํผ์ฌ๋ ํด๋์ค์์ ๋ก์ง ๋ง์ง๋ง์ ํธ์ถํ๋ ๋ฐฉ๋ฒ์ผ๋ก ์ ์ฉํ ์๋ ์์ง๋ง, ApplicationEventPublisher๋ฅผ ์ฌ์ฉํ์ฌ ํธ๋์ญ์ ์ด ์ฑ๊ณต์ ์ผ๋ก ์ปค๋ฐ๋ ํ์ ์ด๋ฒคํธ ๋ฆฌ์ค๋๊ฐ ์๋ํ๋๋ก ์ค์ ํ ์๋ ์๋ค.
์ธ์ ๋ ์ ๋ต์ ์๊ธฐ ๋๋ฌธ์ ๋ณธ์ธ์ ํ๋ก์ ํธ์ ๊ท์น๊ณผ ์ํฉ์ ์๋ง์ ๋ฐฉ๋ฒ์ผ๋ก ์ ์ฉํ๋ฉด ๋๋ค.
2. ์ค๋ ๋ํ๋ก ์์ฒญ TPS๋ฅผ ์กฐ์ ํด๋ผ
์ธ๋ถ API๋ฅผ ์ฐ๋ํ ๋๋ ์ฐ๋ฆฌ ์๋น์ค์ ์ปดํจํ ํ๊ฒฝ๋ ์ค์ํ์ง๋ง, ์๋๋ฐฉ์ ์ปดํจํ ํ๊ฒฝ์ ํนํ ๊ณ ๋ คํด์ผ ํ๋ค. ์ฐ๋ฆฌ ์๋น์ค๊ฐ ์ด๋น 100๊ฐ์ ์์ฒญ์ ์ฒ๋ฆฌํ ์ ์๋๋ผ๋, ์๋๋ฐฉ ์๋ฒ๋ ์ด๋น 10๊ฐ์ ์์ฒญ๋ง ์ฒ๋ฆฌํ ์ ์๋ค๋ฉด ํด๋น ์๋ฒ์ ๋ถํ๋ฅผ ๊ฐํ๊ฒ ๋๊ธฐ ๋๋ฌธ์ด๋ค.
์ด๋ฐ ์ํฉ์์๋ ์ธ๋ถ API ์์ฒญ์ ์ํ ๋ณ๋์ ์ค๋ ๋ ํ์ ์์ฑํ์ฌ ์์ฒญ ์ฒ๋ฆฌ๋(TPS)์ ์กฐ์ ํ๋ ๊ฒ์ด ํจ๊ณผ์ ์ด๋ค.
๋ณ๋๋ก ์ค๋ ๋ ํ์ ์ค์ ํ์ง ์๊ณ ์ฌ์ฉํ๋ค๋ฉด ๊ณตํต ํ(common pool)์ ์ฌ์ฉํ ๊ฒ์ด๋ค. ์ด ๊ฒฝ์ฐ, ์ฐ๋ฆฌ ์ปดํจํ ํ๊ฒฝ์ด ํ์ฉํ๋ ํ ์ธ๋ถ API์ ์ ํ ์์ด ์์ฒญ์ ๋ณด๋ด๊ฒ ๋ ๊ฒ์ด๋ค. ์ด๋ ๊ฒ ๋๋ฉด ์ธ๋ถ API๋ฅผ ์ ๊ณตํ๋ ์๋ฒ์ ํ์ฉ์น ์ด์์ผ๋ก ์์ฒญ์ด ๊ฐ๊ฒ ๋์ด ํด๋น ์๋ฒ์ ์ปดํจํ ์๋๊ฐ ๋๋ ค์ง ์ ์๋ค. ๋ํ ์๋น์ค A๊ฐ ์ฅ์ ๋ฅผ ์ผ์ผํค๋ฉด์ ์๋ต์ด ์ง์ฐ๋๋ฉด ํ์ ๋จ์ ์ฌ์ฉ ๊ฐ๋ฅํ ์ปค๋ฅ์ ์ด ์ค์ด๋ค๋ฉด์ ์๋น์ค B์ C์ ์ฐ๋๋ ๋๊ธฐ ์ํ์ ๋์ด๊ฒ ๋๋ ์ฐ์ ์ง์ฐ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๊ฒ ๋๋ค.
์ด๋ฌํ ๋ฌธ์ ๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด ์ ์์์ฒ๋ผ ๊ฐ ์ฐ๋ API๋ง๋ค ๋ณ๋์ ์ค๋ ๋ ํ์ ์ง์ ํ๋ฉด ์์ฝ๊ฒ ํด๊ฒฐํ ์ ์๋ค. ์์ ๊ฒฝ์ฐ์์๋ ์๋น์ค A๊ฐ ์ฅ์ ๋ฅผ ์ผ์ผ์ผ๋ ๊ฐ ์ฐ๋ ์๋น์ค๋ ๋ ๋ฆฝ์ ์ธ ์ค๋ ๋ ํ์ ๊ฐ๊ธฐ ๋๋ฌธ์, ์๋น์ค B์ C์ ์ฐ๋์ ์๋น์ค A์ ์ํ์ ์ํฅ์ ๋ฐ์ง ์๋๋ค.
๋ํ ๋์์ ๋ง์ ์์ฒญ์ด ๋ค์ด์ค๋๋ผ๋, ์ค๋ ๋ ํ์ ์ง์ ๋ ์ค๋ ๋ ์๋งํผ๋ง ๋์์ ์์ ์ ์ฒ๋ฆฌํ ์ ์๊ณ , ๋๋จธ์ง ์์ฒญ๋ค์ ํ์์ ๋๊ธฐํ๊ธฐ ๋๋ฌธ์ ์ธ๋ถ API ์๋ฒ์ ๊ฐํด์ง๋ ๋ถํ๋ฅผ ์กฐ์ ํ ์ ์๋ค.
์ค์ ์ฌ๋ก๋ก๋ ํ ์ค๋ฑ ํฌ ๋์ถ ์์คํ ๊ฐ๋ฐ ๊ณผ์ ์์๋ ์ดํด๋ณผ ์ ์๋ค.(SLASH 22 - ํ ์ค๋ฑ ํฌ์ ์์ ํ ์๋ก์ด ๋์ถ ์์คํ )
3. ๋น๋๊ธฐ์ ๋ณ๋ ฌ ์ฒ๋ฆฌ๋ฅผ ๊ณ ๋ คํด๋ผ
ํ๋์ ๋ก์ง์์ ์ฌ๋ฌ ๊ฐ์ ์ธ๋ถ API๋ฅผ ์์ฐจ์ ์ผ๋ก ํธ์ถํ๋ ๊ฒฝ์ฐ, ์ฒ๋ฆฌ์๊ฐ์ด ์๋นํ ์์๋ ์ ์๋ค. ์ด๋ ๋น๋๊ธฐ์ ๋ณ๋ ฌ์ฒ๋ฆฌ๋ฅผ ์ ์ฉํ๋ฉด ์ ์ฒด์ ์ธ ์ฒ๋ฆฌ ์๊ฐ์ ํฌ๊ฒ ๋จ์ถํ ์ ์๋ค.
Java์์๋ CompletableFuture๋ฅผ ํ์ฉํ์ฌ ๋น๋๊ธฐ์ ๋ณ๋ ฌ ์ฒ๋ฆฌ๋ฅผ ๊ตฌํํ ์ ์๋ค. CompletableFuture ์ฌ์ฉ๋ฒ์ ๋ํด์๋ ์ด์ ๊ธ์์ ์์ฑํ ์ ์ด ์๋ค.
CompletableFuture๋ฅผ ์ฌ์ฉํ ๋๋ ์ฃผ์์ ์ด ์๋๋ฐ, ๋ณ๋์ ์ค๋ ๋ ํ์ ์ง์ ํด์ฃผ์ง ์์ผ๋ฉด fork join pool์ด ์ฌ์ฉ๋๋ค๋ ์ ์ด๋ค. fork join pool์ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ญ์์ ์ฌ์ฉํ๋ ํ๋ก, ๋คํธ์ํฌ I/O ์์ ๊ณผ ๊ฐ์ด ๋๊ธฐ ์๊ฐ์ด ๊ธด ์์ ์์๋ ์ค๋ ๋๊ฐ ๋ธ๋กํน๋์ด ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ค๋ฅธ ๋ถ๋ถ์ ์ํฅ์ ์ค ์ ์์ผ๋ฏ๋ก I/O ์์ฃผ์ ์์ ์ผ ๊ฒฝ์ฐ ๋ณ๋์ ์ค๋ ๋ํ์ ๊ผญ ์ง์ ํด ์ฃผ๋ ๊ฒ์ด ์ข๋ค.
์ค๋ ๋ ํ์ ํฌ๊ธฐ๋ CPU Bound ์์ ์ ๊ฒฝ์ฐ ์ผ๋ฐ์ ์ผ๋ก (์ฝ์ด + 1)๋งํผ์ ์ง์ ํด ์ค๋ค. ํ์ง๋ง I/O Bound ์์ ์์๋ ์ฝ์ด ์์ 2๋ฐฐ, 3๋ฐฐ, 4๋ฐฐ ํน์ ๊ทธ ์ด์์ ์ํฉ์ ๋ฐ๋ผ ์ง์ ํ๋ค. ํฌ๊ธฐ๋ฅผ ๊ฒฐ์ ํ๊ธฐ๊ฐ ์ด๋ ค์ธ ๋๋ ์๋์ ๊ณต์์ ์ฐธ๊ณ ํ๋ ๊ฒ๋ ์ข๋ค.
Nthreads = Ncpu * Ucpu * (1 + W/C)
- Ncpu๋ ์ฌ์ฉ ๊ฐ๋ฅํ CPU ์ฝ์ด ์๋ฅผ ์๋ฏธํ๋ฉฐ, Runtime.getRuntime().availableProcessors()๊ฐ ๋ฐํํ๋ ๊ฐ์ ์ฌ์ฉํ๋ค.
- Ucpu๋ CPU ํ์ฉ ๋น์จ๋ก, 0๊ณผ 1 ์ฌ์ด์ ๊ฐ์ ๊ฐ์ง๋ค.
- W/C๋ ๋๊ธฐ ์๊ฐ๊ณผ ๊ณ์ฐ ์๊ฐ์ ๋น์จ์ ์๋ฏธํ๋ค.
๊ทธ๋ ๋ค๋ฉด ์ค๋ ๋ํ์ ๊ฐ์๋ฅผ ๋ฌด์์ ๋ง์ด ๋๋ฆฌ๋ฉด ์ฑ๋ฅ์ด ์ข์์ง๊น? ๊ทธ๊ฑด ๋ ์๋๋ค. CPU ์ฝ์ด์์ ์คํ๋๋ ์ค๋ ๋๊ฐ ๋ค๋ฅธ ์ค๋ ๋๋ก ๋ฐ๋ ๋๋ง๋ค Context Switching์ด ๋ฐ์ํ๋ฉฐ ์ด๋ก ์ธํด CPU ์๊ฐ์ด ์ถ๊ฐ๋ก ์์๋๋ค. ๋ฐ๋ผ์ CPU ์ฝ์ด ์๋ฅผ ์ด๊ณผํ๋ ์ค๋ ๋๋ฅผ ์์ฑํ๋ฉด Context Switching์ผ๋ก ์ธํ ์ค๋ฒํค๋๊ฐ ์ฆ๊ฐํ๊ฒ ๋๊ณ ํน์ ๊ฐ์ ์ด์๋ถํฐ๋ ์ฑ๋ฅ์ด ์คํ๋ ค ์ ํ๋ ์ ์๋ค.
4. ์ํท ๋ธ๋ ์ด์ปค๋ฅผ ํตํด ํ๋ฆ์ ์ ์ดํด๋ผ
์ธ๋ถ API๋ฅผ ์ฌ์ฉํ ๋ ํน์ API์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ฌ ์๋ฌ๊ฐ ๋๊ฑฐ๋ ์๋ต์ด ์ง์ฐ๋๋ ์ํฉ์์ ๊ณ์ํด์ ํด๋น ์ธ๋ถ API๋ฅผ ํธ์ถํ๋ค๋ฉด ์ฐ๋ฆฌ ์ ํ๋ฆฌ์ผ์ด์ ์ ์๋ต๋ ์ง์ฐ๋๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๋ค. ์ด๋ฐ ๊ฒฝ์ฐ ์ํท๋ธ๋ ์ด์ปค๋ฅผ ํ์ฉํ์ฌ ํ๋ฆ์ ์ ์ดํ ์ ์๋ค.
์ํท ๋ธ๋ ์ด์ปค๋ ์ ๊ธฐ ํ๋ก์์ ๊ณผ๋ถํ๊ฐ ๋ฐ์ํ๋ฉด ํ๋ก๋ฅผ ๋์ด ํผํด๋ฅผ ์ต์ํํ๋ ์๋ฆฌ์์ ์์ด๋์ด๋ฅผ ์ป์ ํจํด์ด๋ค. API ํธ์ถ์ ๋ฌธ์ ๊ฐ ์๊ฒจ ์๊ณ์น ์ด์์ ์ง์ฐ์๋ต์ด๋ ์๋ฌ์จ์ด ๋ฐ์ํ๋ค๋ฉด ํด๋น API ํธ์ถ์ ๋ ์ด์ ํ์ง ์๊ณ , ์ฆ์ ์๋ฌ๋ฅผ ๋ฐํํ์ฌ ์ธ๋ถ ์๋น์ค์ ๋ํ ๋ถํ์ํ ํธ์ถ์ ๋ฐฉ์งํ๊ณ ์ฐ๋ฆฌ ํด๋ผ์ด์ธํธ์๊ฒ ๋น ๋ฅด๊ฒ ์๋ต์ ๋ณด๋ผ ์ ์๋ค. ๋ํ ์ธ๋ถ API A๋ฅผ B๋ก ๋์ฒด๊ฐ ๊ฐ๋ฅํ๋ค๋ฉด A์ ํธ์ถ์ ์ค๋จํ๊ณ B๋ฅผ ํธ์ถํ๋๋ก ์ ์ดํ ์๋ ์๋ค.
์ํท ๋ธ๋ ์ด์ปค๋ ํฌ๊ฒ ์ธ ๊ฐ์ง ์ํ๋ฅผ ๊ฐ์ง๋ค.
- Closed ์ํ: ์ ์์ ์ผ๋ก ์๋ํ๋ ์ํ์ด๋ค. API ํธ์ถ์ด ์ ์ด๋ฃจ์ด์ง๊ณ , ์๋ฌ์จ์ด ํน์ ์๊ณ์น ์ดํ์ผ ๊ฒฝ์ฐ ์ด ์ํ๋ฅผ ์ ์งํ๋ค.
- Open ์ํ: API ํธ์ถ์ ๋ฌธ์ ๊ฐ ์๊ฒจ ์๋ฌ์จ์ด ์๊ณ์น๋ฅผ ์ด๊ณผํ๋ฉด, ์ํท ๋ธ๋ ์ด์ปค๋ Open ์ํ๊ฐ ๋๋ค. ์ด ์ํ์์๋ ๋ชจ๋ API ํธ์ถ์ ์ฐจ๋จํ๊ณ , ์ฆ์ ์๋ฌ ์๋ต์ ๋ฐํํ๋ค.
- Half-Open ์ํ: Open ์ํ์์ ์ผ์ ์๊ฐ์ด ์ง๋๋ฉด, ์ํท ๋ธ๋ ์ด์ปค๋ Half-Open ์ํ๊ฐ ๋๋ค. ์ด ์ํ์์๋ ์ผ๋ถ API ํธ์ถ์ ํ์ฉํ์ฌ ์ธ๋ถ ์๋น์ค๊ฐ ์ ์์ผ๋ก ๋ณต๊ตฌ๋์๋์ง๋ฅผ ํ์ธํ๋ค. ์ด๋ API ํธ์ถ์ด ์ฑ๊ณตํ๋ฉด ์ํท ๋ธ๋ ์ด์ปค๋ ๋ค์ Closed ์ํ๋ก ๋์๊ฐ๊ณ , ์คํจํ๋ฉด Open ์ํ๋ฅผ ์ ์งํ๋ค.
์ํท ๋ธ๋ ์ด์ปค๋ฅผ ๊ตฌํํ๊ธฐ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก๋ Netflix์ Hystrix, Resilience4J ๋ฑ์ด ์์ผ๋ ํ์ฉํ๋ฉด ์ข๋ค.
5. Rate Limit์ ๊ฑธ์ด๋ผ
์ผ์ ์๊ฐ ๋์ ๋์ผํ ์์ฒญ์ด ์ง๋์น๊ฒ ๋ง์ด ๋ค์ด์ค๋ ๊ฒ์ ์ ์ดํ๊ฑฐ๋, ํน์ ๊ธฐ๊ด์์ ์ผ์ ์๊ฐ ๋์ API ํธ์ถ ํ์๋ฅผ ์ ํํ๋ ๋ฑ์ ์ํฉ์์ Rate Limit ๊ธฐ๋ฅ์ ์ ์ฉํ๋ฉด ์ข์ ์ ํ์ด ๋ ์ ์๋ค.
์ฒ๋ฆฌ์จ ์ ํ์ ์ํ ๋ค์ํ ์๊ณ ๋ฆฌ์ฆ์ด ์์ผ๋ฉฐ ๊ฐ๊ฐ์ ์ํฉ์ ์๋ง๊ฒ ์ ์ฉํ๋ฉด ๋๋ค.
- ํ ํฐ ๋ฒํท ์๊ณ ๋ฆฌ์ฆ: ๋ฒํท์ ์ผ์ ์๊ฐ๋ง๋ค ํ ํฐ์ด ์์ด๊ณ , ์์ฒญ์ด ๋ค์ด์ฌ ๋๋ง๋ค ํ ํฐ์ ์ฌ์ฉํ๋ ๋ฐฉ์์ด๋ค. ๋ฒํท์ ํ ํฐ์ด ์๋ค๋ฉด ์์ฒญ์ ๋ฐ์ง ์์ผ๋ฉฐ, ์ผ์ ํ ์๋๋ก ์์ฒญ์ ์ฒ๋ฆฌํ๋ ๋ฐ ์ ํฉํ๋ค.
- ๋์ถ ๋ฒํท ์๊ณ ๋ฆฌ์ฆ: ๋ฒํท์ ์์ฒญ์ด ์์ด๊ณ ์ผ์ ์๋๋ก ๋ฒํท์์ ๋์ถ๋์ด ์ฒ๋ฆฌ๋๋ ๋ฐฉ์์ด๋ค. ๋ฒํท์ด ๊ฐ๋ ์ฐผ์ ๋ ์ถ๊ฐ๋ก ๋ค์ด์ค๋ ์์ฒญ์ ๊ฑฐ๋ถ๋๋ฉฐ, ์์ฒญ์ ํญ๋ฐ์ ์ธ ์ฆ๊ฐ๋ฅผ ๋ง๋ ๋ฐ ์ ์ฉํ๋ค.
- ๊ณ ์ ์๋์ฐ ์๊ณ ๋ฆฌ์ฆ: ์๊ฐ์ ์ผ์ ํ ์๋์ฐ๋ก ๋๋๊ณ , ๊ฐ ์๋์ฐ์์ ์ฒ๋ฆฌํ ์ ์๋ ์์ฒญ์ ์๋ฅผ ์ ํํ๋ ๋ฐฉ์์ด๋ค. ์๋์ฐ๊ฐ ๋ฐ๋๋ฉด ์์ฒญ ์๋ ์ด๊ธฐํ๋๋ฉฐ, ๊ตฌํ์ด ๊ฐ๋จํ์ง๋ง ์๋์ฐ ๋ณ๊ฒฝ ์์ ์ ์์ฒญ์ด ๋ชฐ๋ฆด ์ ์๋ ๋ฌธ์ ๊ฐ ์๋ค.
- ์ฌ๋ผ์ด๋ฉ ๋ก๊ทธ ์๊ณ ๋ฆฌ์ฆ: ๊ณ ์ ์๋์ฐ ์๊ณ ๋ฆฌ์ฆ์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ ๋ฐฉ์์ผ๋ก, ๊ฐ ์์ฒญ์ ๋ก๊ทธ๋ก ๊ธฐ๋กํ๊ณ ์ผ์ ์๊ฐ ๋์์ ๋ก๊ทธ ์๋ฅผ ํ์ธํ์ฌ ์์ฒญ์ ์ ํํ๋ค. ์ด ๋ฐฉ์์ ์ ํํ ์์ฒญ ์๋ฅผ ์ ์งํ ์ ์์ง๋ง, ๋ก๊ทธ๋ฅผ ๊ด๋ฆฌํ๋ ๋ฐ ์ถ๊ฐ์ ์ธ ๋น์ฉ์ด ๋ ๋ค.
- ์ฌ๋ผ์ด๋ฉ ์๋์ฐ ์๊ณ ๋ฆฌ์ฆ: ๊ณ ์ ์๋์ฐ์ ์ฌ๋ผ์ด๋ฉ ๋ก๊ทธ๋ฅผ ๊ฒฐํฉํ ๋ฐฉ์์ผ๋ก, ์๋์ฐ๋ฅผ ์ผ์ ๊ฐ๊ฒฉ์ผ๋ก ์ฌ๋ผ์ด๋ฉํ๋ฉด์ ์์ฒญ์ ์ ํํ๋ค. ์ด ๋ฐฉ์์ ๊ณ ์ ์๋์ฐ์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ณ ์ฌ๋ผ์ด๋ฉ ๋ก๊ทธ๋ณด๋ค ํจ์จ์ ์ผ๋ก ์์ฒญ์ ๊ด๋ฆฌํ ์ ์๋ค.
Guava, Resilience4j, Bucket4j ๋ฑ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํ์ฉํ๋ฉด, Rate Limit ๊ธฐ๋ฅ์ ์ฝ๊ฒ ๊ตฌํํ ์ ์๋ค. ์ธํฐ๋ท์ ์ด์ ๊ดํ ๋ค์ํ ์๋ฃ๋ค์ด ๋ง์ผ๋ ์์ธํ ํ์ต์ ์ํ๋ค๋ฉด ์ฐพ์๋ณด๊ธธ ๋ฐ๋ผ๋ฉฐ, ์ฑ ์ผ๋ก ํ์ตํ๊ณ ์ถ๋ค๋ฉด ๊ฐ์ ๋ฉด์ ์ฌ๋ก๋ก ๋ฐฐ์ฐ๋ ๋๊ท๋ชจ ์ค๊ณ ์์คํ ์ค๊ณ ๊ธฐ์ด 1๊ถ์์ ์ฐพ์๋ณผ ์ ์๋ค.
6. ํ์์์์ ์ค์ ํด๋ผ
Java์์ RestTemplate๋ WebClient๋ฅผ ์ฌ์ฉํ ๋, ํ์์์์ ๋ช ์์ ์ผ๋ก ์ค์ ํ์ง ์์ผ๋ฉด ๋ฌด์ ํ์ผ๋ก ์ค์ ๋๋ค. ์ด๋ฌํ ์ํฉ์์ ๋์์ ๋๊ธฐํ๋ ์ธ๋ถ ์ฐ๋ ๊ฐ์๊ฐ ๋ง์์ง๋ฉด, ๋ด ์๋น์ค์ ์๋๋ ์ ์ฐจ ๋๋ ค์ง๊ฒ ๋๋ฉฐ ์ต์ ์ ๊ฒฝ์ฐ ๋ชจ๋ ์ค๋ ๋๊ฐ ๋๊ธฐ ์ํ์ ๋น ์ ธ ๋ค๋ฅธ ํด๋ผ์ด์ธํธ ์์ฒญ์ ์๋ตํ ์ ์๋ ์ค๋ ๋๊ฐ ๋จ์์์ง ์๊ฒ ๋๋ค. ๋ฐ๋ผ์ ํ์์์ ์ค์ ์ ๋ฐ๋์ ํ์ํ๋ค.
๋ณดํต ์ฐ๊ฒฐ ํ์์์(Connection Timeout)๊ณผ ์ฝ๊ธฐ ํ์์์(Read Timeout)์ 1์ด์์ 5์ด ์ด๋ด๋ก ์ค์ ํ๋ค. ์ผ๋ฐ์ ์ผ๋ก ์ ์์ ์ธ ํต์ ์ธ ๊ฒฝ์ฐ ๋๋ถ๋ถ ์ด ์์ ์๋ฃ๋๊ธฐ ๋๋ฌธ์ด๋ค. ํ์ง๋ง ์ํฉ์ ๋ฌ๋ผ์ง ์ ์์ผ๋ฏ๋ก, ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํฉ์ ์๋ง๊ฒ ์ ์ฉํ๋ฉด ๋๋ค.
- ์ฐ๊ฒฐ ํ์์์(Connection Timeout): ํด๋ผ์ด์ธํธ๊ฐ ์๋ฒ์ ์ฐ๊ฒฐ์ ์๋ํ๊ณ , ์ฐ๊ฒฐ์ด ์ฑ๊ณตํ ๋๊น์ง์ ์๊ฐ์ ์๋ฏธํ๋ค. ๋คํธ์ํฌ ์ํ๋ ์๋ฒ์ ๊ฐ์ฉ์ฑ ๋ฑ์ ๋ฐ๋ผ ๋ณํ ์ ์๋ค.
- ์ฝ๊ธฐ ํ์์์(Read Timeout): ์๋ฒ์ ์ฐ๊ฒฐ์ด ์ฑ๊ณตํ ํ, ํด๋ผ์ด์ธํธ๊ฐ ์๋ต์ ๊ธฐ๋ค๋ฆฌ๋ ์๊ฐ์ ์๋ฏธํ๋ค. ์ธ๋ถ ์๋น์ค์ ์ฒ๋ฆฌ ์๋์ ๋ฐ๋ผ ๋ณํ ์ ์๋ค.
7. ์บ์ฑ ์ฒ๋ฆฌ๋ฅผ ๊ณ ๋ คํด๋ผ
์ธ๋ถ API๋ก๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ์กฐํํด์ค๋ ๊ฒฝ์ฐ, ํด๋น ๋ฐ์ดํฐ๊ฐ ์ค์๊ฐ ์ฑ์ด ์ง์ ๊ฐ์ด ์๋๋ผ๋ฉด ๋งค๋ฒ ์์ฒญ์ ๋ณด๋ด๋ ๊ฒ๋ณด๋ค๋ ์บ์ฑ๋ ๊ฐ์ ์๋ตํ๋ ๊ฒ๋ ์ข์ ๋ฐฉ๋ฒ์ด๋ค. API ์ฐ๋ ๊ณผ์ ์ ์๋ฌด๋ฆฌ ์ต์ ํํ๋๋ผ๋ ์ ์ด์ ๋ถํ์ํ ํธ์ถ์ ์ค์ด๋ ๊ฒ์ด ๊ฐ์ฅ ํจ์จ์ ์ธ ๋ฐฉ๋ฒ์ผ ์ ์๋ค๋ ๊ฒ์ ๋ช ์ฌํ์.
8. ์ฌ์๋ ์ฒ๋ฆฌํด๋ผ
API ํต์ ์ ๋คํธ์ํฌ ์ด์ ๋ฑ์ผ๋ก ๊ฐํ์ ์ผ๋ก ์คํจํ ์ ์๋ค. ๊ทธ๋ฌ๋ฏ๋ก ํ ๋ฒ์ ํธ์ถ์ด ์คํจํ์ ๋ ์ฆ์ ์คํจ ์๋ต์ ๋ฐํํ๊ธฐ๋ณด๋ค๋, ์ผ์ ํ์๋งํผ ์์ฒญ์ ์ฌ์๋ํ๋ ๊ฒ์ด ๋ ํจ์จ์ ์ผ ์ ์๋ค.
Spring์ ์ด๋ฐ ์ฌ์๋ ์ฒ๋ฆฌ๋ฅผ ์ฝ๊ฒ ๊ตฌํํ ์ ์๋๋ก spring-retry ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ RetryTemplate์ ์ ๊ณตํ๋ค. RestTemplate์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ์๋ RetryTemplate์ ๊ตฌํํด์ผ ํ๋ฉฐ, WebClient๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ์๋ WebClient ์์ฒด์์ ์ฌ์๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ๊ธฐ ๋๋ฌธ์ ๋ณ๋๋ก ๊ตฌํํ ํ์ ์์ด ์ฌ์๋ ํ์๋ง ์ง์ ํด ์ฃผ๋ฉด ๋๋ค.
์๋๋ RestTemplate์ WebClient์์ ์ฌ์๋ ๋ก์ง์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด๋ค.
@Configuration
class RestTemplateConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplateBuilder()
.setConnectTimeout(Duration.ofSeconds(5))
.setReadTimeout(Duration.ofSeconds(5))
.additionalInterceptors(clientHttpRequestInterceptor())
.build();
}
public ClientHttpRequestInterceptor clientHttpRequestInterceptor() {
return (request, body, execution) -> {
RetryTemplate retryTemplate = new RetryTemplate();
retryTemplate.setRetryPolicy(new SimpleRetryPolicy(3));
try {
return retryTemplate.execute(context -> execution.execute(request, body));
} catch (Throwable throwable) {
throw new RuntimeException(throwable);
}
};
}
}
WebClient webClient = WebClient.create("http://example.com");
webClient.get()
.uri("/some-data")
.retrieve()
.bodyToMono(String.class)
.retryWhen(Retry.backoff(3, Duration.ofSeconds(1))) // ์ฌ์๋ ํ์์ ๊ฐ๊ฒฉ ์ค์
.subscribe();