๋ถ๋ฆฌ๋ฐฐ์ถ์ ์ฝ๊ฒ, ์ค์ฒ์ ๋ณด์์ผ๋ก ์ด์ด์ง๋๋ก ์ฌ์ฉ์ ๊ฒฝํ์ ํ๋ฆ์ ์์ ์ ์ผ๋ก ๋ท๋ฐ์นจํ๋ ReDO Backend์ ๋๋ค.
ReDO๋ ๋ถ๋ฆฌ๋ฐฐ์ถ ์ ๋ณด๋ฅผ ์ฝ๊ณ ๋น ๋ฅด๊ฒ ์ ๊ณตํ๊ณ , ์ค์ฒ์ ๋ํ ๋ณด์์ ํตํด ์ฌ์ฉ์์ ํ๋์ ์ ๋ํ๋ ์๋น์ค์ ๋๋ค.
- ๊ธฐ๊ฐ : 2026.06.29 ~ 2026.08.21
- ์ธ์ : Backend 5๋ช
- ๋ชฉํ : AI ๊ธฐ๋ฐ ์ ๋ณด ์ ๊ณต๊ณผ ๋ฆฌ์๋ ์์คํ ์ ๊ฒฐํฉํ์ฌ ๋ถ๋ฆฌ๋ฐฐ์ถ์ ์ผ์์ ์ต๊ด์ผ๋ก ๋ง๋ค์ด ์ง์์ ์ธ ํ๊ฒฝ ๋ณดํธ ์ฐธ์ฌ๋ฅผ ์ด๋์ด๋ด๋ ๊ฒ
- ํต์ฌ ํ๋ฆ : AI ๋ถ๋ฆฌ๋ฐฐ์ถ ์ ๋ณด โ AI ๋ถ๋ฆฌ๋ฐฐ์ถ ์ธ์ฆ โ ํฌ์ธํธ ์ ๋ฆฝ โ ๋ฆฌ์๋ ๊ตฌ๋งค โ ๊ธฐ์ฌ๋ ์๊ฐํ
| ์ฒ์งํ | ์๋ํ | ์ฑ๋ฏผ์ | ํ๊ฑด์ฐ | ์ด์ ์ฐ |
|---|---|---|---|---|
| ํ์๊ฐ์ ยท๋ก๊ทธ์ธยทํ๋กํ | AI ๋ถ๋ฆฌ๋ฐฐ์ถ ์ ๋ณด | AI ๋ถ๋ฆฌ๋ฐฐ์ถ ์ธ์ฆ | ์ธํ๋ผยทํฌ์ธํธยท๋ฆฌ์๋ยท๊ธฐ์ฌ๋ | ์ปค๋ฎค๋ํฐ |
- ์์ด๋ ์ค๋ณต ํ์ธ๊ณผ ์ด๋ฉ์ผ ์ธ์ฆ์ ํตํ ์ผ๋ฐ ํ์๊ฐ์
- ์๋น์ค ์ฝ๊ด ์กฐํ ๋ฐ ํ์ ์ฝ๊ด ๋์ ์ฒ๋ฆฌ
- Google, Kakao, Naver ์์ ํ์๊ฐ์ ๋ฐ ๋ก๊ทธ์ธ
- JWT ๊ธฐ๋ฐ Access Token ๋ฐ๊ธ๊ณผ Refresh Token์ ์ด์ฉํ ํ ํฐ ์ฌ๋ฐ๊ธ
- HttpOnly Cookie์ Redis๋ฅผ ํ์ฉํ Refresh Token ๊ด๋ฆฌ ๋ฐ ๋ก๊ทธ์์
- Redis ์์ ์ฐ์ฐ์ผ๋ก ๋ก๊ทธ์ธ ์คํจ ํ์๋ฅผ ๊ด๋ฆฌํ์ฌ ๋ฐ๋ณต์ ์ธ ๋ก๊ทธ์ธ ์๋ ์ ํ
- ์ฌ์ฉ์ ํ๋กํ ์์ฑ ๋ฐ ์กฐํ
- ๋๋ค์, ํ๋กํ ์ด๋ฏธ์ง, ์บ๋ฆญํฐ ์์
- ํ์ ํํด ์ฌ์ ์กฐํ ๋ฐ ํ์ ํํด ์ฒ๋ฆฌ
- ํ๋ชฉ๋ช ์ ์ด์ฉํ ๋ถ๋ฆฌ๋ฐฐ์ถ ์ ๋ณด ์กฐํ
- ์ดฌ์ํ๊ฑฐ๋ ์ ๋ก๋ํ ์ด๋ฏธ์ง๋ฅผ AI๊ฐ ๋ถ์ํ์ฌ ํ๋ชฉ ์๋ณ
- ์ฌ์ฉ์๊ฐ ์ ๋ ฅํ ๋ฌธ์ ์ํฉ์ ๋ถ์ํ์ฌ ์ ํฉํ ๋ถ๋ฆฌ๋ฐฐ์ถ ์ ๋ณด ์ ๊ณต
- Spring AI์ Gemini๋ฅผ ํ์ฉํ ์ด๋ฏธ์งยทํ ์คํธ ๊ธฐ๋ฐ ์ ๋ณด ํ์
- JSON Schema ๊ธฐ๋ฐ์ ๊ตฌ์กฐํ๋ AI ์๋ต ๊ฒ์ฆ
- AI ๋ถ์ ๊ฒฐ๊ณผ๋ฅผ ์๋น์ค์ ๋ฑ๋ก๋ ํ๋ชฉ ๋ฐ ๋ถ๋ฆฌ๋ฐฐ์ถ ์ ๋ณด์ ์ฐ๊ฒฐ
- ํ๋ชฉ๋ณ ๋ฐฐ์ถ ๋ฐฉ๋ฒ๊ณผ ๋จ๊ณ๋ณ ์ฃผ์์ฌํญ ์ ๊ณต
- ์์ฃผ ํ์ธํ๋ ๋ถ๋ฆฌ๋ฐฐ์ถ ์ ๋ณด ์ฆ๊ฒจ์ฐพ๊ธฐ
- ํ์ ๊ฒฐ๊ณผ์์ ํด๋น ํ๋ชฉ์ ๋ฐฐ์ถ ์ธ์ฆ ๊ธฐ๋ฅ์ผ๋ก ์ฐ๊ฒฐ
- ๋น์ผ ์ธ์ฆ ์ฑ๊ณต ํ์์ ๋จ์ ์ธ์ฆ ๊ฐ๋ฅ ํ์ ์กฐํ
- ์ผ๋ฐ ์ธ์ฆ๊ณผ ๋ถ๋ฆฌ๋ฐฐ์ถ ์ ๋ณด ํ์ ํ ์ธ์ฆ ์ง์
- ์ค์๊ฐ์ผ๋ก ์ดฌ์ํ ๋ฐฐ์ถ ์๋ฃ ์ด๋ฏธ์ง๋ฅผ Gemini VLM์ผ๋ก ํ์
- ์ธ์ฆ ์ฑ๊ณต ์ฌ๋ถ์ ์ธ์ฆ ํ๋ชฉ, ํ์ ๊ฒฐ๊ณผ ๋ฐ ์ธ์ฆ ์ผ์ ์ ๊ณต
- ์ธ์ฆ ๋ฐฉ์์ ๋ฐ๋ฅธ ํฌ์ธํธ ์๋ ์ ๋ฆฝ
- ์ผ๋ฐ ์ธ์ฆ: 50P
- ์ ๋ณด ํ์ ํ ์ธ์ฆ: 100P
- ์ผ์ผ ์ต๋ 3ํ ๋ฐ ๋์ผ ํ๋ชฉ ์ค๋ณต ์ธ์ฆ ์ ํ
- ์ธ์ฆ ์ฑ๊ณต ํ 5๋ถ๊ฐ ์ ๊ท ์ธ์ฆ ์ ํ
- AI ํ์ ์คํจ ์ฌ์ ์ ์ฌ์ดฌ์ ๋ฐฉ๋ฒ ์ ๊ณต
- ์คํจํ ์ธ์ฆ ์ด๋ฏธ์ง์ ์ฌ์ดฌ์ ๋ฐ AI ์ฌ๊ฒ์
- ์ธ์ฆ ์ ์ฉ ๋น๋๊ธฐ ์คํ๊ธฐ์ ํ์์์์ ์ ์ฉํ์ฌ ์ฅ์๊ฐ AI ์์ฒญ ์ ์ด
- ์ธ์ฆ ์ํ ๋ณ๊ฒฝ, AI ํ์ ์ ์ฅ, ํฌ์ธํธ ์ ๋ฆฝ ๋ฐ ๊ธฐ์ฌ๋ ์ด๋ฒคํธ๋ฅผ ํ๋์ ํธ๋์ญ์ ์ผ๋ก ์ฒ๋ฆฌ
- ์ฌ์ฉ์์ ๋ณด์ ํฌ์ธํธ์ ์ด๋ฒ ๋ฌ ์ ๋ฆฝ ํฌ์ธํธ ์กฐํ
- ํฌ์ธํธ ์ ๋ฆฝ ๋ฐ ์ฌ์ฉ ๊ฑฐ๋ ๋ด์ญ ์กฐํ
- ์ ํด ๋ธ๋๋ ๋ฐฐ์ก ์ํ๊ณผ ์ฟ ํฐยท๊ธฐํํฐ์ฝ ์ํ ์ ๊ณต
- ์ํ ์ ํ๋ณ ๋ชฉ๋ก, ์์ธ ์ ๋ณด ๋ฐ ์ฌ์ฉ์๋ณ ์ผ์ผ ์ถ์ฒ ์ํ ์กฐํ
- ์ฃผ์๊ธฐ๋ฐ์ฐ์ ์ง์์๋น์ค API๋ฅผ ์ด์ฉํ ๋ฐฐ์ก์ง ์ฃผ์ ๊ฒ์
- ๋ฐฐ์ก์ง ์์ฑ, ์กฐํ, ์์ ๋ฐ ์ญ์
- ํฌ์ธํธ๋ฅผ ์ฌ์ฉํ ๋ฆฌ์๋ ๊ตฌ๋งค
- ๋ฆฌ์๋ ๊ตํ ๋ด์ญ๊ณผ ๋ฐฐ์กยท์ฟ ํฐ ์ฒ๋ฆฌ ์ํ ์กฐํ
Idempotency-Key์ DB ์ ๋ํฌ ์ ์ฝ์ ํ์ฉํ ๋์ผ ๊ตฌ๋งค ์์ฒญ์ ์ค๋ณต ์ฒ๋ฆฌ ๋ฐฉ์ง- ์ํ ๋จ์ Redisson ๋ถ์ฐ ๋ฝ์ผ๋ก ๋์ผ ์ํ์ ๋์ ๊ตฌ๋งค ์์ฒญ ์ ์ด
- ์ฌ์ฉ์์ ์ํ ๋ฐ์ดํฐ์ DB ๋น๊ด์ ๋ฝ์ ์ ์ฉํ์ฌ ํฌ์ธํธ์ ์ฌ๊ณ ์ ํฉ์ฑ ๋ณด์ฅ
- ์ฌ์ฉ์์ ๋์ ๋ถ๋ฆฌ๋ฐฐ์ถ ์ธ์ฆ ํ์ ์กฐํ
- ์ธ์ฆ ํ์์ ๋ฐ๋ฅธ 8๋จ๊ณ ํ๊ฒฝ ๊ธฐ์ฌ ๋ง์ผ์คํค ์ ๊ณต
- ํ์ฌ ๋ฌ์ฑํ ๊ฒฐ๊ณผ๋ฌผ๊ณผ ๋ค์ ๋ชฉํ๊น์ง ๋จ์ ์ธ์ฆ ํ์ ํ์
- ์ ์ฒด ์๋น์ค ์ฐธ์ฌ์ ์ ์กฐํ
- ๋ค๋ฅธ ์ฌ์ฉ์์ ์ต๊ทผ ๋ถ๋ฆฌ๋ฐฐ์ถ ์ธ์ฆ ํ๋์ ํผ๋ ํํ๋ก ์ ๊ณต
- ์ปค์ ๊ธฐ๋ฐ ํ์ด์ง๋ค์ด์ ์ ํ์ฉํ ๊ธฐ์ฌ๋ ํผ๋ ์ด์ด๋ณด๊ธฐ
- Cache-Aside ๋ฐฉ์์ผ๋ก ๊ธฐ์ฌ๋ ์ด๋ฒคํธ์ ์ฐธ์ฌ์ ์๋ฅผ Redis์ ์บ์ฑ
- ๋ฐ์ดํฐ ํน์ฑ์ ๋ฐ๋ผ ์๋ก ๋ค๋ฅธ TTL์ ์ ์ฉํ์ฌ ์บ์ ์ต์ ์ฑ๊ณผ ์กฐํ ์ฑ๋ฅ ๊ด๋ฆฌ
- Redis ์ฅ์ ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์กฐํ๋ก ์ ํํ์ฌ ๊ธฐ์ฌ๋ ๊ธฐ๋ฅ ์ ์ง
- ์ ๋ณด ๊ณต์ , ํ๊ฒฝ ์ค์ฒ, ๋ฆฌ์๋ ํ๊ธฐ ์นดํ ๊ณ ๋ฆฌ๋ณ ๊ฒ์๊ธ ์กฐํ
- ๊ฒ์๊ธ ๋ชฉ๋ก ๋ฐ ์์ธ ์ ๋ณด ์กฐํ
- ์ ๋ชฉ, ๋ด์ฉ ๋ฐ ์ฌ๋ฌ ์ฅ์ ์ด๋ฏธ์ง๋ฅผ ํฌํจํ ๊ฒ์๊ธ ๋ฑ๋ก
- ๋ด๊ฐ ์์ฑํ ๊ฒ์๊ธ ์์ ๋ฐ ์ญ์
- ๊ฒ์๊ธ๋ณ ๋๊ธ ์กฐํ, ๋ฑ๋ก, ์์ ๋ฐ ์ญ์
- ๊ฒ์๊ธ ์ข์์ ๋ฐ ์ข์์ ์ทจ์
- ๋ด๊ฐ ์์ฑํ ๊ฒ์๊ธ๊ณผ ๋๊ธ ๋ชจ์๋ณด๊ธฐ
- ๊ฒ์๊ธ ์ต์ ์ ํ์ด์ง๋ค์ด์ ๊ณผ ๋๊ธ ์ปค์ ํ์ด์ง๋ค์ด์
- ๊ฒ์๊ธ๋ณ ๋๊ธ ์์ ๋ํ ์ด๋ฏธ์ง๋ฅผ ์ผ๊ด ์กฐํํ์ฌ N+1 ๋ฌธ์ ๋ฐฉ์ง
- ์ปค๋ฎค๋ํฐ ์ด๋ฏธ์ง๋ฅผ AWS S3์ ์ ์ฅํ๊ณ ๋ค์ค ์ ๋ก๋ ์คํจ ์ ๋ณด์ ์ญ์ ์ฒ๋ฆฌ
- ๋ฌธ์
- Gemini API๋ ๋คํธ์ํฌ์ ๋ชจ๋ธ ์ํ์ ๋ฐ๋ผ ์๋ต์ด ์ง์ฐ๋์ด ์ ํ๋ฆฌ์ผ์ด์ ์์ฒญ ์ฒ๋ฆฌ ์์์ ์ฅ์๊ฐ ์ ์ ํ ์ ์์์ต๋๋ค.
- AI๊ฐ ์๋น์ค์ ์กด์ฌํ์ง ์๋ ํ๋ชฉ์ ์์ฑํ๊ฑฐ๋ ์ฝ์๋ JSON ํ์๊ณผ ๋ค๋ฅธ ์๋ต์ ๋ฐํํ ๊ฐ๋ฅ์ฑ์ด ์์์ต๋๋ค.
- ํด๊ฒฐ
- AI ํธ์ถ ์ ์ฉ Executor์ ๋ฐฐ์ถ ์ธ์ฆ ์ ์ฉ Thread Pool์ ๋ถ๋ฆฌํ์ฌ ์ผ๋ฐ API ์์ฒญ๊ณผ AI ํ์ ์์ ์ ์คํ ์์์ ๊ฒฉ๋ฆฌํ์ต๋๋ค.
- ํธ์ถ ์ ํ ์๊ฐ๊ณผ ์ธ์ฆ ์ ์ฒด ์ ํ ์๊ฐ์ ๋ณ๋๋ก ์ค์ ํ๊ณ , ์๊ฐ ์ด๊ณผ์ Provider ์ค๋ฅ๋ฅผ ๋๋ฉ์ธ ์์ธ๋ก ๋ณํํ์ต๋๋ค.
- ์๋น์ค DB์ ๋ฑ๋ก๋ ํ๋ชฉ ๋ชฉ๋ก์ ํ๋กฌํํธ์ ์ ๊ณตํ์ฌ ํด๋น ๋ชฉ๋ก์์๋ง ๊ฒฐ๊ณผ๋ฅผ ์ ํํ๋๋ก ์ ํํ์ต๋๋ค.
- ์ ํฉํ ํ๋ชฉ์ด ์์ผ๋ฉด
NOT_FOUND๋ฅผ ๋ฐํํ๋๋ก ํ๊ณ , JSON Schema๋ฅผ ์ ์ฉํ์ฌ ์๋ต ํ์์ ๊ฒ์ฆํ์ต๋๋ค.
- ํจ๊ณผ
- ์ธ๋ถ AI ์๋น์ค์ ์๋ต ์ง์ฐ์ด ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฒด๋ก ํ์ฐ๋๋ ๋ฒ์๋ฅผ ์ค์์ต๋๋ค.
- AI ํ ๋ฃจ์๋ค์ด์ ๊ณผ ๋น์ ํ ์๋ต์ ์ ์ดํ์ฌ ์๋น์ค ๋ฐ์ดํฐ์ ์ผ์นํ๋ ๊ฒฐ๊ณผ๋ง ์ ๊ณตํ ์ ์๊ฒ ๋์์ต๋๋ค.
- ๋ฌธ์
- ๋์ผ ์ํ์ ๊ตฌ๋งค ์์ฒญ์ด ๋์์ ๋ค์ด์ค๋ฉด ์ํ ์ฌ๊ณ ๊ฐ ์์๊ฐ ๋๊ฑฐ๋ ํฌ์ธํธ๊ฐ ์ค๋ณต ์ฐจ๊ฐ๋ ์ ์์์ต๋๋ค.
- ๋คํธ์ํฌ ์ง์ฐ์ด๋ ์ฌ์ฉ์ ์ฌ์์ฒญ์ผ๋ก ๋์ผํ ๊ตฌ๋งค ์์ฒญ์ด ์ฌ๋ฌ ๋ฒ ์ฒ๋ฆฌ๋ ๊ฐ๋ฅ์ฑ์ด ์์์ต๋๋ค.
- ํด๊ฒฐ
- ์ํ ID ๋จ์์ Redisson ๋ถ์ฐ ๋ฝ์ ์ ์ฉํ์ฌ ๋์ผ ์ํ์ ๋ํ ๊ตฌ๋งค ์์ฒญ์ ์์ฐจ์ ์ผ๋ก ์ฒ๋ฆฌํ์ต๋๋ค.
- ํธ๋์ญ์ ๋ด๋ถ์์ ์ฌ์ฉ์์ ์ํ์ DB ๋น๊ด์ ๋ฝ์ ์ ์ฉํ๊ณ ํฌ์ธํธ, ์ํ ์ํ ๋ฐ ์ฌ๊ณ ๋ฅผ ๋ค์ ๊ฒ์ฆํ์ต๋๋ค.
- ์์ฒญ๋ณ
Idempotency-Key๋ฅผ ๋ฐ๊ณ ์ฌ์ฉ์ ID์ ๋ฉฑ๋ฑ์ฑ ํค ์กฐํฉ์ DB ์ ๋ํฌ ์ ์ฝ์ ์ ์ฉํ์ต๋๋ค.
- ํจ๊ณผ
- ๋ค์ค ์ธ์คํด์ค ํ๊ฒฝ์์๋ ์ํ ์ฌ๊ณ ์ ์ฌ์ฉ์ ํฌ์ธํธ์ ์ ํฉ์ฑ์ ์ ์งํ์ต๋๋ค.
- ๋์ผ ์์ฒญ์ ์ค๋ณต ์ฒ๋ฆฌ์ ์๋ก ๋ค๋ฅธ ์ํ์ ๋์ ๊ตฌ๋งค๋ก ๋ฐ์ํ ์ ์๋ ํฌ์ธํธ ์ค๋ณต ์ฌ์ฉ์ ๋ฐฉ์งํ์ต๋๋ค.
- ๋ฌธ์
- ๊ธฐ์ฌ๋ ํผ๋ ์กฐํ๋ง๋ค ์ด๋ฒคํธ์ ์ฌ์ฉ์ ํ๋กํ ๋ฐ ์ ์ฒด ์ฐธ์ฌ์ ์๋ฅผ ๋ฐ๋ณต ์กฐํํ์ฌ DB ๋ถํ๊ฐ ์ฆ๊ฐํ ์ ์์์ต๋๋ค.
- Redis ์ฅ์ ๊ฐ ๊ธฐ์ฌ๋ ๊ธฐ๋ฅ ์ ์ฒด์ ์ฅ์ ๋ก ์ด์ด์ง์ง ์๋๋ก ๋ณ๋์ ์คํจ ๊ฒฝ๋ก๊ฐ ํ์ํ์ต๋๋ค.
- ํด๊ฒฐ
- Cache-Aside ๋ฐฉ์์ผ๋ก ๊ธฐ์ฌ๋ ์ด๋ฒคํธ๋ฅผ ์บ์ฑํ๊ณ , ์บ์์ ์๋ ์ด๋ฒคํธ๋ง DB์์ ์ผ๊ด ์กฐํํ ๋ค ๋ค์ ์ ์ฅํ์ต๋๋ค.
- ๊ธฐ์ฌ๋ ์ด๋ฒคํธ์๋ 30๋ถ, ๋ณ๊ฒฝ ๊ฐ๋ฅ์ฑ์ด ๋์ ์ ์ฒด ์ฐธ์ฌ์ ์์๋ 1๋ถ์ TTL์ ์ ์ฉํ์ต๋๋ค.
- ํผ๋์ ํ์ํ ์ฌ์ฉ์ ํ๋กํ์ ์ฌ์ฉ์ ID ๋ชฉ๋ก์ผ๋ก ์ผ๊ด ์กฐํํ์ต๋๋ค.
- Redis ์กฐํ ๋๋ ์ ์ฅ์ ์คํจํ๋ฉด DB์์ ๋ฐ์ดํฐ๋ฅผ ์กฐํํ๋๋ก Fail-Open ๊ตฌ์กฐ๋ฅผ ์ ์ฉํ์ต๋๋ค.
- ํจ๊ณผ
- ๊ธฐ์ฌ๋ ๋ฐ์ดํฐ์ ์ฌ์ฉ์ ํ๋กํ์ ๋ฐ๋ณต ์กฐํ๋ฅผ ์ค์ฌ DB ์ ๊ทผ๋์ ๊ฐ์์์ผฐ์ต๋๋ค.
- Redis ์ฅ์ ๊ฐ ๋ฐ์ํ๋๋ผ๋ DB ์กฐํ๋ฅผ ํตํด ๊ธฐ์ฌ๋ ๊ธฐ๋ฅ์ ๊ณ์ ์ ๊ณตํ ์ ์๊ฒ ๋์์ต๋๋ค.
- ๋ฌธ์
- ๊ฒ์๊ธ๋ณ ๋๊ธ ์์ ๋ํ ์ด๋ฏธ์ง๋ฅผ ์กฐํํ๊ธฐ ์ํด ๊ฒ์๊ธ๋ง๋ค ์ถ๊ฐ ์ฟผ๋ฆฌ๊ฐ ์คํ๋์์ต๋๋ค.
- ๊ฒ์๊ธ์ด N๊ฐ์ผ ๋
1 + 2N๊ฐ์ ์ฟผ๋ฆฌ๊ฐ ๋ฐ์ํ์ฌ 10๊ฐ ๊ฒ์๊ธ ์กฐํ ์ ์ด 21๊ฐ์ ์ฟผ๋ฆฌ๊ฐ ํ์ํ์ต๋๋ค.
- ํด๊ฒฐ
- ๋จผ์ ํ์ด์ง์ ํ์ํ ๊ฒ์๊ธ ๋ชฉ๋ก์ ํ์ ํ ๋ค ํด๋น ๊ฒ์๊ธ์ ๋๊ธ ์์ ์ด๋ฏธ์ง๋ฅผ ๊ฐ๊ฐ ์ผ๊ด ์กฐํํ์ต๋๋ค.
- ๋๊ธ ์๋
GROUP BY community_id์ง๊ณ ๊ฒฐ๊ณผ๋ฅผ Projection์ผ๋ก ์กฐํํ์ฌ ๊ฒ์๊ธ๋ณ Map์ผ๋ก ๊ตฌ์ฑํ์ต๋๋ค. - ์ด๋ฏธ์ง๋
displayOrder์์ผ๋ก ์กฐํํ๊ณ ๊ฒ์๊ธ๋ณ ๊ฐ์ฅ ์์ ์ด๋ฏธ์ง๋ฅผ ๋ํ ์ด๋ฏธ์ง๋ก ์ ํํ์ต๋๋ค.
- ํจ๊ณผ
- ํ์ด์ง ํฌ๊ธฐ์ ๊ด๊ณ์์ด ์ปค๋ฎค๋ํฐ ๋ชฉ๋ก ์กฐํ ์ฟผ๋ฆฌ๋ฅผ 3๊ฐ๋ก ๊ณ ์ ํ์ต๋๋ค.
- ๊ฒ์๊ธ ์๊ฐ ์ฆ๊ฐํ๋๋ผ๋ ์ถ๊ฐ ์ฟผ๋ฆฌ๊ฐ ๋น๋กํ์ฌ ์ฆ๊ฐํ์ง ์๋๋ก ๊ฐ์ ํ์ต๋๋ค.
- ๋ฌธ์
- S3์ DB๋ ํ๋์ ํธ๋์ญ์ ์ผ๋ก ๋ฌถ์ ์ ์์ด ๋ค์ค ์ด๋ฏธ์ง ์ ๋ก๋์ ์ผ๋ถ๋ง ์ฑ๊ณตํ๋ฉด ๊ณ ์ ๊ฐ์ฒด๊ฐ ๋จ์ ์ ์์์ต๋๋ค.
- ํ๋กํ ์ด๋ฏธ์ง๋ฅผ ๋ณ๊ฒฝํ ๋ ๊ธฐ์กด ์ด๋ฏธ์ง๋ฅผ ๋จผ์ ์ญ์ ํ๋ฉด ์ดํ DB ์ ์ฅ ์คํจ ์ ์ฌ์ฉ์ ์ด๋ฏธ์ง๊ฐ ์ ์ค๋ ์ ์์์ต๋๋ค.
- ํด๊ฒฐ
- ์ ๋ก๋์ ์ฑ๊ณตํ S3 ๊ฐ์ฒด ํค๋ฅผ ์ถ์ ํ๊ณ , ์ดํ ์ฒ๋ฆฌ์์ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ฉด ๋จผ์ ์ ๋ก๋๋ ๊ฐ์ฒด๋ฅผ ์ญ์ ํ๋ ๋ณด์ ๋ก์ง์ ์ ์ฉํ์ต๋๋ค.
- ํ๋กํ ์ด๋ฏธ์ง๋
์ ๊ท ์ด๋ฏธ์ง ์ ๋ก๋ โ DB ๋ฐ์ ๋ฐ URL ์์ฑ โ ๊ธฐ์กด ์ด๋ฏธ์ง ์ญ์ ์์๋ก ์ฒ๋ฆฌํ์ต๋๋ค. - DB ๋ฐ์์ ์คํจํ๋ฉด ์๋ก ์ ๋ก๋ํ ์ด๋ฏธ์ง๋ฅผ ์ ๋ฆฌํ๊ณ , ๋ณด์ ์ฒ๋ฆฌ ์คํจ ์์ธ์ ๋ก๊ทธ๋ก ๋จ๊ธฐ๋๋ก ๊ตฌ์ฑํ์ต๋๋ค.
- ํจ๊ณผ
- ๋ค์ค ์ด๋ฏธ์ง ์ ๋ก๋ ๊ณผ์ ์์ ๋ฐ์ํ ์ ์๋ ๊ณ ์ ๊ฐ์ฒด๋ฅผ ์ค์์ต๋๋ค.
- ํ๋กํ ์ด๋ฏธ์ง ๋ณ๊ฒฝ ์คํจ ์ ๊ธฐ์กด ์ด๋ฏธ์ง๋ฅผ ์ ์งํ์ฌ ์ฌ์ฉ์ ๋ฐ์ดํฐ ์ ์ค ๊ฐ๋ฅ์ฑ์ ๋ฎ์ท์ต๋๋ค.
- ๋ฌธ์
- ์๋ฒ์ ์ง์ ์ ์ํ๊ธฐ ์ ๊น์ง ์ ํ๋ฆฌ์ผ์ด์ ์ฅ์ ์ EC2ยทRedis ์์ ๋ถ์กฑ์ ๋น ๋ฅด๊ฒ ํ์ ํ๊ธฐ ์ด๋ ค์ ์ต๋๋ค.
- ์ปจํ ์ด๋ ๋ก๊ทธ ์์ง์ ์ํ Docker Socket ๊ถํ ๋ ธ์ถ๊ณผ EC2 ๊ฐ ๋ก๊ทธ ์ ์ก ๊ตฌ๊ฐ์ ๋ณด์์ ๊ณ ๋ คํด์ผ ํ์ต๋๋ค.
- ์ผ์์ ์ธ ์งํ ๋๋ฝ์ผ๋ก ๋์ผํ Grafana ์ฅ์ ์๋ฆผ์ด ๋ฐ๋ณต๋๋ ๋ฌธ์ ๋ ์์์ต๋๋ค.
- ํด๊ฒฐ
- Prometheus๋ก Spring Boot ์ ํ๋ฆฌ์ผ์ด์ , EC2 ๋ฐ Redis ๋ฉํธ๋ฆญ์ ํตํฉ ์์งํ์ต๋๋ค.
- Grafana Alloy, Loki, Grafana๋ฅผ ์ด์ฉํด ์ปจํ ์ด๋ ๋ก๊ทธ ์์ง๊ณผ ์ด์ ๋์๋ณด๋๋ฅผ ๊ตฌ์ถํ์ต๋๋ค.
- Docker Socket Proxy๋ฅผ ์ ์ฉํ์ฌ Alloy์ ํ์ํ ์กฐํ ๊ถํ๋ง ์ ํ์ ์ผ๋ก ์ ๊ณตํ์ต๋๋ค.
- Service EC2์ Monitoring EC2 ์ฌ์ด์ ๋ก๊ทธ ์ ์ก์ TLS์ Basic Auth๋ฅผ ์ ์ฉํ์ต๋๋ค.
- Grafana์ No Data ์ฒ๋ฆฌ, ํ๊ฐ ๋๊ธฐ์๊ฐ ๋ฐ ์๋ฆผ ์ ์ฑ ์ ์กฐ์ ํ๊ณ ์ฅ์ ยท๋ณต๊ตฌ ์๋ฆผ์ Discord๋ก ์ ์กํ์ต๋๋ค.
- ํจ๊ณผ
- ์ ํ๋ฆฌ์ผ์ด์ ๋ก๊ทธ์ ์ธํ๋ผ ๋ฉํธ๋ฆญ์ ํ๋์ ๋์๋ณด๋์์ ํ์ธํ ์ ์๊ฒ ๋์์ต๋๋ค.
- Docker Socket๊ณผ ๋ก๊ทธ ์ ์ก ๊ฒฝ๋ก์ ๋ณด์์ ๊ฐํํ๊ณ ์ฅ์ ์๋ฆผ์ ์ ํ๋์ ์ ๋ขฐ๋๋ฅผ ๋์์ต๋๋ค.
| ๋๋ฉ์ธ | Base Path | ์ฃผ์ ๊ธฐ๋ฅ |
|---|---|---|
| ์ธ์ฆ | /api/auth |
ํ์๊ฐ์ , ๋ก๊ทธ์ธ, ์์ ๋ก๊ทธ์ธ, ํ ํฐ ์ฌ๋ฐ๊ธ, ๋ก๊ทธ์์ |
| ์ฌ์ฉ์ | /api/users |
ํ๋กํ ๊ด๋ฆฌ, ํ์ ํํด |
| ์ฝ๊ด | /api/terms |
์๋น์ค ์ฝ๊ด ์กฐํ |
| ๋ถ๋ฆฌ๋ฐฐ์ถ ์ ๋ณด | /api/guides |
๊ฐ์ด๋ ์กฐํ, AI ๊ฒ์, ์ฆ๊ฒจ์ฐพ๊ธฐ |
| ๋ถ๋ฆฌ๋ฐฐ์ถ ์ธ์ฆ | /api/certification |
์ธ์ฆ ์ ์ฑ ์กฐํ, ์ ๊ท ์ธ์ฆ, ์ฌ์ดฌ์ |
| ํฌ์ธํธ | /api/rewards/points |
๋ณด์ ํฌ์ธํธ ๋ฐ ๊ฑฐ๋ ๋ด์ญ ์กฐํ |
| ๋ฆฌ์๋ ์ํ | /api/rewards/products |
์ํ ๋ชฉ๋ก, ์์ธ, ๋ฏธ๋ฆฌ๋ณด๊ธฐ |
| ๋ฆฌ์๋ ๊ตํ | /api/rewards/redemptions |
์ํ ๊ตํ ๋ฐ ๊ตํ ๋ด์ญ ์กฐํ |
| ๋ฐฐ์ก์ง | /api/shipping-addresses |
์ฃผ์ ๊ฒ์ ๋ฐ ๋ฐฐ์ก์ง ๊ด๋ฆฌ |
| ๊ธฐ์ฌ๋ | /api/contributions |
๋์ ๊ธฐ์ฌ๋, ์ ์ฒด ๊ธฐ์ฌ๋ ํผ๋ |
| ์ปค๋ฎค๋ํฐ | /api/community |
๊ฒ์๊ธ, ๋๊ธ, ์ข์์ |
์ ์ฒด API ๋ช ์ธ์ ์์ฒญยท์๋ต ์์๋ Swagger์์ ํ์ธํ ์ ์์ต๋๋ค.
- Swagger UI: https://redo-backend.site/swagger-ui/index.html#/
- ๋ก์ปฌ Swagger UI:
http://localhost:8080/swagger-ui/index.html
Back/
โโโ .github/
โ โโโ ISSUE_TEMPLATE/
โ โโโ workflows/
โ โ โโโ ci-cd.yml
โ โโโ CONTRIBUTING.md
โ โโโ PULL_REQUEST_TEMPLATE.md
โโโ gradle/
โโโ k6/
โ โโโ config/ # ์คํ ํ๋กํ ๋ฐ ์ฑ๋ฅ ๊ธฐ์ค
โ โโโ lib/ # ์ธ์ฆ, HTTP ์์ฒญ, ์์ ์ฅ์น
โ โโโ scenarios/ # ๋๋ฉ์ธ๋ณ ๋ถํ ํ
์คํธ
โโโ monitoring/
โ โโโ alloy/ # ์ปจํ
์ด๋ ๋ก๊ทธ ์์ง
โ โโโ grafana/ # ๋์๋ณด๋ ๋ฐ ์๋ฆผ ํ๋ก๋น์ ๋
โ โโโ loki/ # ๋ก๊ทธ ์ ์ฅ์
โ โโโ loki-proxy/ # Loki TLSยท์ธ์ฆ ํ๋ก์
โ โโโ prometheus/ # ๋ฉํธ๋ฆญ ์์ง ์ค์
โโโ src/
โ โโโ main/
โ โ โโโ java/com/redo/
โ โ โ โโโ domain/
โ โ โ โ โโโ certification/
โ โ โ โ โโโ community/
โ โ โ โ โโโ contribution/
โ โ โ โ โโโ point/
โ โ โ โ โโโ recycleGuide/
โ โ โ โ โโโ reward/
โ โ โ โ โโโ term/
โ โ โ โ โโโ user/
โ โ โ โโโ global/
โ โ โ โโโ ai/
โ โ โ โโโ apiPayload/
โ โ โ โโโ config/
โ โ โ โโโ redis/
โ โ โ โโโ s3/
โ โ โ โโโ security/
โ โ โ โโโ util/
โ โ โโโ resources/
โ โ โโโ application.yaml
โ โ โโโ application-certification.yaml
โ โโโ test/
โโโ .env.example
โโโ build.gradle
โโโ compose.yaml
โโโ Dockerfile
โโโ gradlew
โโโ settings.gradle
- Java 17
- MySQL
- Redis
- AWS S3 Bucket
- Gmail SMTP ๊ณ์ ๋ฐ App Password
- Gemini API Key (AI ๊ธฐ๋ฅ ์ฌ์ฉ ์)
- ๋๋ก๋ช ์ฃผ์ API Key (๋ฐฐ์ก์ง ์ฃผ์ ๊ฒ์ ๊ธฐ๋ฅ ์ฌ์ฉ ์)
AI ๊ธฐ๋ฅ์ ์ฌ์ฉํ์ง ์๋ ๊ฒฝ์ฐ GEMINI_ENABLED=false๋ก ์คํํ ์ ์์ต๋๋ค. ์ด ๊ฒฝ์ฐ ์ด๋ฏธ์งยทํ
์คํธ ๊ธฐ๋ฐ ๋ถ๋ฆฌ๋ฐฐ์ถ ์ ๋ณด ํ์๊ณผ AI ๋ฐฐ์ถ ์ธ์ฆ ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
git clone https://github.com/REDO-Team/Back.git
cd Backcp .env.example .env์ฃผ์ ํ๊ฒฝ๋ณ์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
| ํ๊ฒฝ๋ณ์ | ์ค๋ช |
|---|---|
DB_URL |
MySQL JDBC URL |
DB_USERNAME |
MySQL ์ฌ์ฉ์๋ช |
DB_PASSWORD |
MySQL ๋น๋ฐ๋ฒํธ |
JWT_SECRET |
JWT ์๋ช Secret |
MAIL_USERNAME |
์ด๋ฉ์ผ ์ธ์ฆ ๋ฐ์ก ๊ณ์ |
MAIL_PASSWORD |
Gmail App Password |
S3_BUCKET |
์ด๋ฏธ์ง ์ ์ฅ S3 Bucket |
AWS_REGION |
AWS Region |
JUSO_API_KEY |
๋๋ก๋ช ์ฃผ์ API ์น์ธ ํค |
APP_BASE_URL |
CORS์ Swagger์ ์ฌ์ฉํ ์๋น์ค URL |
GEMINI_ENABLED |
Gemini ๊ธฐ๋ฅ ํ์ฑํ ์ฌ๋ถ |
GEMINI_API_KEY |
Gemini API Key |
GEMINI_MODEL |
์ฌ์ฉํ Gemini ๋ชจ๋ธ |
GEMINI_TIMEOUT |
๋จ์ผ Gemini ํธ์ถ ์ ํ ์๊ฐ |
AWS ์ธ์ฆ ์ ๋ณด๋ ๋ก์ปฌ AWS Profile ๋๋ EC2 IAM Role ๋ฑ AWS SDK ๊ธฐ๋ณธ ์ธ์ฆ ์ฒด์ธ์ ํตํด ์ ๊ณตํฉ๋๋ค.
set -a
source .env
set +a
./gradlew bootRun์ ํ๋ฆฌ์ผ์ด์ ์ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ค์ ํฌํธ๋ฅผ ์ฌ์ฉํฉ๋๋ค.
| ํฌํธ | ์ฉ๋ |
|---|---|
8080 |
Backend API |
9101 |
Actuator Health ๋ฐ Prometheus Metrics |
6379 |
Redis |
์ผ๋ฐ ํ ์คํธ๋ ์ธ๋ถ Gemini API๋ฅผ ํธ์ถํ์ง ์์ต๋๋ค.
./gradlew test์ค์ Gemini API ์ฐ๋ ํ ์คํธ๋ ๋ณ๋ Gradle Task๋ก ๋ถ๋ฆฌ๋์ด ์์ต๋๋ค.
./gradlew geminiIntegrationTestGemini ํตํฉ ํ ์คํธ๋ฅผ ์คํํ๋ ค๋ฉด ์ ํจํ API Key์ ๊ด๋ จ ํ๊ฒฝ๋ณ์๊ฐ ํ์ํฉ๋๋ค.
k6 ํ ์คํธ๋ Docker ๊ธฐ๋ฐ์ผ๋ก ์คํํ์ฌ ํ์์ด ๋์ผํ ๋ฒ์ ๊ณผ ์ฑ๋ฅ ๊ธฐ์ค์ ์ฌ์ฉํ ์ ์๋๋ก ๊ตฌ์ฑํ์ต๋๋ค.
cp k6/.env.example k6/.env
./k6/run.sh scenarios/examples/authenticated-read.js์ ๊ณตํ๋ ์คํ ํ๋กํ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
| ํ๋กํ | ์ฉ๋ |
|---|---|
smoke |
API์ ์๋๋ฆฌ์ค ์ ์ ๋์ ํ์ธ |
load |
์์๋๋ ์ผ๋ฐ ๋ถํ์์ ์ฑ๋ฅ ์ธก์ |
stress |
์์คํ ํ๊ณ์ ๋ณ๋ชฉ ํ์ธ |
๊ณตํต ์ฑ๋ฅ ๊ธฐ์ค์ HTTP ์ค๋ฅ์จ 1% ๋ฏธ๋ง, p95 500ms ๋ฏธ๋ง, p99 1,000ms ๋ฏธ๋ง์ ๋๋ค.
์์ธํ ๊ตฌ์ฑ๊ณผ ์ด์ ๋ฐฉ๋ฒ์ k6 ๋ถํ ํ ์คํธ ์ด์ ๊ฐ์ด๋๋ฅผ ์ฐธ๊ณ ํฉ๋๋ค.
develop ๋ธ๋์น์ ์ฝ๋๊ฐ ๋ฐ์๋๋ฉด GitHub Actions๋ฅผ ํตํด ์๋ ๋ฐฐํฌ๊ฐ ์งํ๋ฉ๋๋ค.
- GitHub Actions๊ฐ Docker ์ด๋ฏธ์ง๋ฅผ ๋น๋
- ์ด๋ฏธ์ง๋ฅผ GitHub Container Registry์ Push
- Self-hosted Runner๊ฐ ๋ฐฐํฌ ์๋ฒ์ ์์ค๋ฅผ ๊ฐฑ์
- Docker Compose๊ฐ ์ ์ด๋ฏธ์ง๋ฅผ Pull
- ์ ํ๋ฆฌ์ผ์ด์ ๊ณผ Redis ๋ฑ ์ด์ ์ปจํ ์ด๋ ์ฌ๊ธฐ๋
- Swagger UI ์๋ต์ ํตํ ๋ฐฐํฌ ์ํ ํ์ธ
- ์ผ์ ๊ธฐ๊ฐ์ด ์ง๋ ๋ฏธ์ฌ์ฉ ์ด๋ฏธ์ง ์ ๋ฆฌ
Spring Boot Actuator์ Micrometer๋ฅผ ํตํด ์ ํ๋ฆฌ์ผ์ด์ ๋ฉํธ๋ฆญ์ ์์งํฉ๋๋ค.
- Prometheus: ์ ํ๋ฆฌ์ผ์ด์ , EC2, Redis ๋ฉํธ๋ฆญ ์์ง
- Grafana: ์ด์ ํํฉ ๋ฐ ๋ถํ ํ ์คํธ ๋์๋ณด๋
- Loki: ์ ํ๋ฆฌ์ผ์ด์ ๊ณผ ์ปจํ ์ด๋ ๋ก๊ทธ ์ ์ฅ
- Grafana Alloy: Docker ์ปจํ ์ด๋ ๋ก๊ทธ ์์ง ๋ฐ ์ ์ก
- Node Exporter: EC2 CPU, Memory, Disk ๋ฉํธ๋ฆญ
- Redis Exporter: Redis ์ํ์ ๋ฉ๋ชจ๋ฆฌ ๋ฉํธ๋ฆญ
- Discord: ์ฅ์ ๋ฐ์ ๋ฐ ๋ณต๊ตฌ ์๋ฆผ
์ด์ ๋์๋ณด๋๋ ๋ค์ ํญ๋ชฉ์ ์ ๊ณตํฉ๋๋ค.
- ์ ํ๋ฆฌ์ผ์ด์ ์์ฒญ ์ฒ๋ฆฌ๋๊ณผ ์๋ต ์๊ฐ
- HTTP ์ค๋ฅ์จ
- JVM Heap๊ณผ Thread ์ํ
- EC2 CPU, Memory, Disk ์ฌ์ฉ๋
- Redis ๋ฉ๋ชจ๋ฆฌ์ ์ฐ๊ฒฐ ์ํ
- k6 ํ ์คํธ๋ณ p95ยทp99 ์๋ต ์๊ฐ
- ์ ํ๋ฆฌ์ผ์ด์ ๋ฐ ์ธํ๋ผ ์ฅ์ ์๋ฆผ
์์ธํ ๊ตฌ์ฑ๊ณผ ์ด์ ๋ฐฉ๋ฒ์ ๋ชจ๋ํฐ๋ง ์ด์ ๊ฐ์ด๋๋ฅผ ์ฐธ๊ณ ํฉ๋๋ค.
- ๊ธฐ๋ณธ ํตํฉ ๋ธ๋์น:
develop - ์ด์ ๋จ์ ๋ธ๋์น ๋ฐ Pull Request ์์ฑ
- CodeRabbit์ ํ์ฉํ ์ฝ๋ ๋ฆฌ๋ทฐ
- ๊ณตํต API ์๋ต๊ณผ ์์ธ ์ฒ๋ฆฌ ๊ท์น ์ ์ฉ
์์ธํ ํ์ ๊ท์น์ .github/CONTRIBUTING.md๋ฅผ ์ฐธ๊ณ ํฉ๋๋ค.
์ฌ๋ฐ๋ฅธ ๋ถ๋ฆฌ๋ฐฐ์ถ์ด ์ผ์์ ์ต๊ด์ด ๋๋๋ก, ReDO โป๏ธ
