์ค์ ์ด์ ์ค์ธ ๋ชจ๋ฐ์ผ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฐฑ์๋ ๊ฐ๋ฐ, ๋ฐฐํฌ, ์ด์ ๊ฒฝํ์ ๋ด์ ํฌํธํด๋ฆฌ์ค์ ๋๋ค.
์๋ณธ ๋ ํฌ์งํ ๋ฆฌ๋ ์ค์ด์ ์ค์ธ ์๋น์ค๋ก ๋ณด์์ Private์ผ๋ก ๊ด๋ฆฌ๋๊ณ ์์ต๋๋ค.
1. ์ผ์์ ์์ง (๋ด ๊ธฐ๋ก ์กฐํ)
2. ์๊ฐ์ ์์ฑ (์คํฌํ ์นด๋ฉ๋ผ ์ดฌ์ ๋ฐ ์ ์ฉ)
3. ๊ธฐ๋ก์ ์ฐ๊ฒฐ (์ปค๋ฎค๋ํฐ ํผ๋)
์คํฌํฝ(Stampic) ์ ์ผ์ ์ค ์๊ฐ์ ์ฌ์ง์ ํ์์คํฌํ๋ก ๊ธฐ๋กํ๊ณ ๊ณต์ ํ๋ ๋ชจ๋ฐ์ผ ์ปค๋ฎค๋ํฐ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋๋ค.
| ํญ๋ชฉ | ๋ด์ฉ |
|---|---|
| MVP ๊ฐ๋ฐ | 2025.11 ~ 2026.01 |
| ๊ณ ๋ํ | 2026.01 ~ ํ์ฌ (์งํ ์ค) |
| ์ญํ | ๋ฐฑ์๋ ๊ฐ๋ฐ, ๋ฐฐํฌ, ์ด์ (๋ฐฑ์๋ 2์ธ ์ค 1์ธ) |
| ์ํ | App Store, Google Play ์ค๋ฐฐํฌ ์ด์ ์ค |
| ๋์ ๊ฐ์ ์ | 130๋ช + |
์ด 7๋ช ํ ํ๋ก์ ํธ
| ์ญํ | ์ธ์ |
|---|---|
| PM | 1๋ช |
| ๋์์ด๋ | 2๋ช |
| iOS ๊ฐ๋ฐ์ | 1๋ช |
| Android ๊ฐ๋ฐ์ | 1๋ช |
| ๋ฐฑ์๋ ๊ฐ๋ฐ์ | 2๋ช |
๋ด๋น ์ ๋ฌด
-
์์คํ ์ํคํ ์ฒ ์ค๊ณ: ๋ค์ด๋ฒ ํด๋ผ์ฐ๋ ํ๊ฒฝ ๊ธฐ๋ฐ ์ ์ฒด ์์คํ ์ํคํ ์ฒ ๊ตฌ์ฑ ๋ฐ Presigned URL ์ ๋ก๋ ๋ก์ง ์ค๊ณ
-
์ปค๋ฎค๋ํฐ ๋๋ฉ์ธ ๊ฐ๋ฐ: ์ฌ์ง ๊ณต์ , ์ข์์ ๋ฑ ์ปค๋ฎค๋ํฐ ํต์ฌ ๋น์ฆ๋์ค ๋ก์ง ๋ฐ REST API ๊ตฌํ
-
DB ์ฑ๋ฅ ์ต์ ํ: ์ปค๋ฒ๋ง ์ธ๋ฑ์ค ์ ์ฉ์ ํตํ ๋์ฉ๋ ์ปค๋ฎค๋ํฐ ํผ๋ ์กฐํ ์ฟผ๋ฆฌ ํ๋
-
์ธํ๋ผ ๋ฐ DevOps: GitHub Actions, Docker, Nginx๋ฅผ ํ์ฉํ CI/CD ์๋ํ ํ์ดํ๋ผ์ธ ๋ฐ ๋ธ๋ฃจ-๊ทธ๋ฆฐ ๋ฌด์ค๋จ ๋ฐฐํฌ ํ๊ฒฝ ๊ตฌ์ถ
-
๋ฐฑ์คํผ์ค(Admin) ๊ตฌํ: App Store ์ปค๋ฎค๋ํฐ ์ฌ์ฌ ๊ฐ์ด๋๋ผ์ธ ๋์์ ์ํด ์ ์๋ ์ฌ์ฉ์ ์ ๊ณ ๋ด์ญ์ ๊ฒ์ฆํ๊ณ ์ ์ฑ ์ฝํ ์ธ ๋ฅผ ๊ด๋ฆฌํ๋ Thymeleaf ๊ธฐ๋ฐ ๊ด๋ฆฌ์ ์น ํ์ด์ง ๊ฐ๋ฐ
ํ์ ๋ฐฉ์
- ๊ฒฉ์ฃผ ์์์ผ ์ ๊ธฐ ํ์ ๊ธฐ๋ฐ 2์ฃผ ๋จ์ ์คํ๋ฆฐํธ๋ก MVP ์ถ์ ํ ์ง์ ๊ณ ๋ํ ์ค
- iOS, Android ๊ฐ๋ฐ์์์ REST API ์ค๊ณ ๋ฐ ์กฐ์จ
- Swagger ๊ธฐ๋ฐ API ๋ฌธ์ํ๋ก iOS, Android ๊ฐ๋ฐ์์์ ๋ช ์ธ ๊ณต์
- ๋์์ด๋์์ ํผ๋๋ฐฑ ๋ฃจํ๋ฅผ ํตํ UI/UX ๊ธฐ๋ฐ API ์๋ต ์ค๊ณ
- ๋ฐฑ์๋ ํ์๊ณผ์ ์ฝ๋ ๋ฆฌ๋ทฐ ๋ฐ ์์คํ ์ํคํ ์ฒ ์ค๊ณ
- GitHub PR ๊ธฐ๋ฐ ๊ฐ๋ฐ ํ๋ก์ธ์ค (์ปค๋ฐ ์ปจ๋ฒค์ , ๋ธ๋์น ์ ๋ต)
| ๋ถ๋ฅ | ๊ธฐ์ |
|---|---|
| Backend | Spring Boot 3.5.6, Java 17 |
| API | JWT, OAuth2, Swagger |
| ORM | JPA, QueryDSL |
| Database | MySQL |
| Admin | Thymeleaf |
| Storage | ๋ค์ด๋ฒ ํด๋ผ์ฐ๋ Object Storage |
| Analytics | Amplitude |
| Monitoring | Prometheus, Grafana |
| DevOps | Docker, Nginx, Certbot, GitHub Actions |
| Cloud | ๋ค์ด๋ฒ ํด๋ผ์ฐ๋ ํ๋ซํผ |
ํต์ฌ ์ค๊ณ ํฌ์ธํธ
- ์ด๋ฏธ์ง ์ ๋ก๋ ์ ์๋ฒ๋ฅผ ๊ฑฐ์น์ง ์๊ณ ํด๋ผ์ด์ธํธ -> Object Storage ์ง์ ์ ๋ก๋ (Presigned URL)
- ์ ๋ก๋ ์๋ฃ ํ ์๋ฒ์ ๋ฉํ๋ฐ์ดํฐ๋ง ์ ์ฅ -> ์๋ฒ ๋ถํ ์ต์ํ
- ์ ํ๋ ์๋ฒ ๋ฆฌ์์ค ํ๊ฒฝ ๋ด์์ ์ต์ ์ ๊ฐ์ฉ์ฑ์ ํ๋ณดํ๊ธฐ ์ํด ๋จ์ผ ์ธ์คํด์ค ๋ด Nginx ํฌํธ ์ค์์นญ ๊ธฐ๋ฐ์ ๋ธ๋ฃจ-๊ทธ๋ฆฐ ๋ฌด์ค๋จ ๋ฐฐํฌ ํ์ดํ๋ผ์ธ ๊ตฌ์ถ
๋ฌธ์ ์ํฉ
๋๋ฏธ ๋ฐ์ดํฐ(๊ฒ์๊ธ 100,100๊ฑด / ์ข์์ 2,409,198๊ฑด) ๊ธฐ๋ฐ ๋ถํ ํ
์คํธ ๊ฒฐ๊ณผ
์ปค๋ฎค๋ํฐ ํผ๋ ์กฐํ API ํ๊ท ์๋ต ์๊ฐ์ด ์ฝ 4,000ms(4์ด) ๋ก ํ์ธ๋จ.
๊ฒ์๊ธ ์ ๋ ฌ(published_at DESC, image_id DESC) ๋ฐ ๊ฒ์๊ธ๋ณ ์ข์์ ์ ์ง๊ณ ์๋ธ์ฟผ๋ฆฌ๋ก ์ธํด
๋๋์ ๋ฐ์ดํฐ ์ค์บ์ด ๋ฐ์ํ๋ฉฐ ์ ์ฒด ํผ๋ ์กฐํ ์ฑ๋ฅ์ ๋ณ๋ชฉ์ด ๋ฐ์ํ๋ ๊ฒ์ผ๋ก ํ๋จ๋จ.
์คํ๊ณํ ๋ถ์ (EXPLAIN)
| type | key | rows | Extra | |
|---|---|---|---|---|
| ์ ์ฉ ์ | ALL | NULL | 2,402,103 | Using where |
| ์ ์ฉ ํ | ref | idx_image_like_image_user | 27 | Using index |
- ์ ์ฉ ์ : ์ข์์ ํ ์ด๋ธ ์ ์ฒด ํ ์ค์บ (์ธ๋ฑ์ค ๋ฏธ์ฌ์ฉ)
- ์ ์ฉ ํ: ์ปค๋ฒ๋ง ์ธ๋ฑ์ค๋ก 27๊ฑด๋ง ์ฐธ์กฐ, ํ ์ด๋ธ ์ ๊ทผ ์์ด ์ฟผ๋ฆฌ ์๊ฒฐ
ํด๊ฒฐ ๋ฐฉ์ ๊ฒํ
๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ ๊ณ ๋ คํจ.
| ๋ฐฉ๋ฒ | ์ฅ์ | ๋จ์ |
|---|---|---|
| ๋ฐ์ ๊ทํ (์ข์์ ์ ์ปฌ๋ผ ๋ณ๋ ๊ด๋ฆฌ) | ์กฐํ ์ ์ง๊ณ ๋ถํ์, ๋งค์ฐ ๋น ๋ฆ | ๋ฐ์ดํฐ ์ ํฉ์ฑ ๊ด๋ฆฌ ๋ณต์ก, ์ฐ๊ธฐ ๋ถํ ์ฆ๊ฐ |
| ์ปค๋ฒ๋ง ์ธ๋ฑ์ค | ๊ตฌ์กฐ ๋ณ๊ฒฝ ์์ด ์ฑ๋ฅ ๊ฐ์ ๊ฐ๋ฅ | ๋ฐ์ดํฐ๊ฐ ๋งค์ฐ ๋ง์์ง ๊ฒฝ์ฐ ํ๊ณ ์กด์ฌ |
- ํ์ฌ ์๋น์ค ๊ท๋ชจ์์๋ ๋๊ท๋ชจ ํธ๋ํฝ์ด ๋ฐ์ํ ๊ฐ๋ฅ์ฑ์ด ๋ฎ๊ณ ๋ฐ์ ๊ทํ๋ก ์ธํ ๋ฐ์ดํฐ ์ ํฉ์ฑ ๊ด๋ฆฌ ๋ณต์ก๋๊ฐ ๋ ํฐ ๋ฆฌ์คํฌ๋ผ๊ณ ํ๋จํ์ฌ ์ปค๋ฒ๋ง ์ธ๋ฑ์ค ์ ์ฉ.
ํด๊ฒฐ
- WHERE, SELECT, ORDER BY ์ปฌ๋ผ์ ๋ชจ๋ ํฌํจํ๋ ์ปค๋ฒ๋ง ์ธ๋ฑ์ค ์ค๊ณ
- ํ ์ด๋ธ ์ ๊ทผ ์์ด ์ธ๋ฑ์ค๋ง์ผ๋ก ์ฟผ๋ฆฌ ์๊ฒฐ๋๋๋ก ๊ตฌ์กฐ ๊ฐ์
- QueryDSL์ ํ์ฉํ ์ต์ ํ๋ ์ฟผ๋ฆฌ ์์ฑ
๐ ์๋ต ์๊ฐ ์ธก์ ๊ฒฐ๊ณผ: 4,000ms -> 25ms (ํด๋ฆญํ์ฌ ํผ์น๊ธฐ)
์ ์ฉ ์ โ 10ํ ์์ฒญ ํ๊ท ์ฝ 4,000ms
์ ์ฉ ํ โ 10ํ ์์ฒญ ํ๊ท ์ฝ 25ms
๊ฒฐ๊ณผ
โก 4,000ms -> 25ms (160๋ฐฐ ๊ฐ์ )
โ
์ข์์ ํ
์ด๋ธ ์ค์บ rows: 2,402,103 -> 27
โ
๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ถํ ๊ฐ์
โ
์ฌ์ฉ์ ํผ๋ ์๋ต ์๋ ๋ํญ ํฅ์
๋ฌธ์ ์ํฉ
- ์ด๋ฏธ์ง ์ค์ฌ ์๋น์ค ํน์ฑ์ ๋ค์์ ์ด๋ฏธ์ง ํ์ผ ์ ๋ก๋๊ฐ ๋น๋ฒํ๊ฒ ๋ฐ์
- ์๋ฒ ์ง์ ์
๋ก๋ ๋ฐฉ์์ ์ ์ฌ์ ํ๊ณ
- ์๋ฒ ๋ฉ๋ชจ๋ฆฌ, ๋คํธ์ํฌ ๋ถํ ์ฆ๊ฐ
ํด๊ฒฐ
์๋ฒ ํด๋ผ์ด์ธํธ ์
๋ก๋ ์๋ฃ ํ
Presigned URL ๋ฐ๊ธ -> Object Storage ์ง์ ์
๋ก๋ -> ์๋ฒ์ ๋ฉํ๋ฐ์ดํฐ ์ ์ฅ
- ์ ํจ์๊ฐ 1๋ถ์ผ๋ก ์ค์ โ ์ค์ ์ ๋ก๋ ์๋ฃ๊น์ง ์์ด ๋ด์ธ๋ก ์ถฉ๋ถํ๋ฉฐ ์ ํจ์๊ฐ์ ์ต์ํํ์ฌ URL ์ ์ถ ์ ๋ฌด๋จ ์ ๋ก๋ ํผํด๋ฅผ ๋ฐฉ์ง
๊ฒฐ๊ณผ
โ
์๋ฒ ๋ถํ ์ต์ํ
โ
์ด๋ฏธ์ง ์
๋ก๋ ์์ ์ฑ ํ๋ณด
โ
๋คํธ์ํฌ ํจ์จ ๋ฐ ์๋ต ์๋ ๊ฐ์
โ
Presigned URL ์ ํจ์๊ฐ ์ต์ํ๋ก ๋ณด์ ๊ฐํ
๋ฌธ์ ์ํฉ
- SSL ์ธ์ฆ์ ์๋ ๊ฐฑ์ ๋ก์ง์ ์กด์ฌํ์ผ๋ Nginx๊ฐ ๊ธฐ์กด ์ธ์ฆ์๋ฅผ ๊ทธ๋๋ก ์ฐธ์กฐํ์ฌ ์ ์ธ์ฆ์๊ฐ ๋ฐ์๋์ง ์์
- ๊ฒฐ๊ณผ์ ์ผ๋ก ์ ์ฒด API ์๋ฒ ๋ค์ด ๋ฐ์ (๋ค์ดํ์ ์ฝ 7์๊ฐ)
- ์ธํ๋ผ ๋ด๋น์๊ฐ ๋ณธ์ธ 1์ธ์ด์๋ ๊ด๊ณ๋ก ์ ๋ฌด ์ค ์ค๋ฅ๋ฅผ ์ธ์งํ ํ ํด๊ทผ ์ฆ์ ์กฐ์น
ํด๊ฒฐ
- Nginx ๋ฆฌ๋ก๋๋ก ์ฆ์ ์๋ฒ ๋ณต๊ตฌ
- ์ธ์ฆ์ ๊ฐฑ์ ์ Nginx ์๋ ๋ฆฌ๋ก๋๋๋๋ก ์คํฌ๋ฆฝํธ ์์
- ์ธ์ฆ์ ๋ง๋ฃ ์ AWS Lambda + SNS ์ฐ๋์ผ๋ก ๋ฌธ์ ์๋ฆผ ๋ฐ์ก ๊ตฌ์ฑ
- ์ธ์ฆ์ ์ ํจ๊ธฐ๊ฐ 90์ผ / ์ฐ๊ฐ ์ฝ 4ํ ๋ฐ์ ์ด๋ฒคํธ -> ์๋ฒ๋ฆฌ์ค(Lambda)๋ก ์ฒ๋ฆฌ
๊ฒฐ๊ณผ
โ
๋์ผ ์ฅ์ ์ฌ๋ฐ ๋ฐฉ์ง
โ
์ธ์ฆ์ ๋ง๋ฃ ์ ์ฌ์ ์๋ฆผ์ผ๋ก ์ ์ ๋์ ์ฒด๊ณ ๊ตฌ์ถ
โ
์ ๋น๋ ์ด๋ฒคํธ๋ฅผ ์๋ฒ๋ฆฌ์ค๋ก ์ฒ๋ฆฌํ์ฌ ๋ฆฌ์์ค ํจ์จํ
ํ๊ณ
- ๋จ์ํ ์ค์ ๋๋ฝ์ด ์ ์ฒด ์์คํ ์ ์น๋ช ์ ์ธ ์ฅ์ ๋ก ์ง๊ฒฐ๋ ์ ์์์ ๊ฒฝํํจ.
- ์ด๋ฅผ ํตํด ์๋์ ์ธ ์ด์์ ๋ฐฐ์ ํ๊ณ ํด๋จผ ์๋ฌ๋ฅผ ๋ฐฉ์งํ ์ ์๋ ์๋ํ์ ์ ์ ์ ์ธ ์๋ฆผ ์ฒด๊ณ๊ฐ ํ์์ ์์ ๊น์ด ์ฒด๊ฐํจ.
| ๊ธฐ๋ฅ | ์ค๋ช |
|---|---|
| ํ์ ๊ด๋ฆฌ | Google, Kakao, Apple OAuth2 ์์ ๋ก๊ทธ์ธ, JWT ์ธ์ฆ |
| ์ปค๋ฎค๋ํฐ ํผ๋ | ์ฌ์ง ๊ณต์ , ์กฐํ, ์ข์์ |
| ์ด๋ฏธ์ง ์ ๋ก๋ | Presigned URL ๊ธฐ๋ฐ Object Storage ์ง์ ์ ๋ก๋ |
| API ๋ฌธ์ํ | Swagger |
| ์ด๋ฒคํธ ๋ถ์ | Amplitude ์ฐ๋ |
| ๋ชจ๋ํฐ๋ง | Prometheus + Grafana ์ค์๊ฐ ์๋ฒ ๋ชจ๋ํฐ๋ง |
| ๊ด๋ฆฌ์ ํ์ด์ง | Thymeleaf ๊ธฐ๋ฐ Admin UI |
| SSL ์๋ํ | Certbot + Docker ๊ธฐ๋ฐ ์ธ์ฆ์ ์๋ ๊ฐฑ์ |
| CI/CD | GitHub Actions ๊ธฐ๋ฐ ์๋ ๋ฐฐํฌ |
[GitHub] main/develop ๋ธ๋์น Merge
โ
[GitHub Actions] ์ปค๋ฐ ์ด๋ ฅ ๊ธฐ๋ฐ ์๋ ํ๊ทธ(๋ฒ์ ) ์ถ์ถ ๋ฐ ๋ฆด๋ฆฌ์ฆ ๋
ธํธ ์์ฑ
โ
[GitHub Actions] Docker Image ๋น๋ ๋ฐ Docker Hub ํธ์
โ
[Naver Cloud] ์๋ฒ์์ ์ต์ Docker ์ด๋ฏธ์ง Pull
โ
[Deploy] Nginx ํฌํธ ์ค์์นญ ๊ธฐ๋ฐ ๋ธ๋ฃจ-๊ทธ๋ฆฐ(Blue-Green) ๋ฌด์ค๋จ ๋ฐฐํฌ
๋์ ๊ฐ์
์ : 130๋ช
+
๋ฐฐํฌ ํ๋ซํผ : App Store, Google Play
์ด์๊ธฐ๊ฐ : 2026.01 ~ ํ์ฌ (3๊ฐ์+)
ํ์ฌ : ๊ณ ๋ํ ์งํ ์ค
- ์ต์ ๊ธฐ์ ์คํ ์ค์ ๊ฒฝํ โ ํ์ (Java 8)๊ณผ ๋ค๋ฅธ Spring Boot 3.x, Java 17 ํ๊ฒฝ์ ์ค๋ฌด ์์ค์ผ๋ก ๊ฒฝํ
- ํ ํ์ ๊ฒฝํ โ PM, ๋์์ด๋, iOS, Android, ๋ฐฑ์๋ 7์ธ ํ์์ ํฌ๋ก์ค ํ๋ซํผ API ์ค๊ณ ๋ฐ ์ฝ๋ ๋ฆฌ๋ทฐ ๊ฒฝํ
- ์ ์ฌ์ดํด ๊ฒฝํ โ ์ค๊ณ, ๊ฐ๋ฐ, ๋ฐฐํฌ, ์ด์, ๊ณ ๋ํ๊น์ง ์ ์ฒด ๊ฐ๋ฐ ์๋ช ์ฃผ๊ธฐ ์ฐธ์ฌ
- ํธ๋ ์ด๋์คํ ๊ธฐ๋ฐ ์ค๊ณ ํ๋จ โ ๋ฐ์ ๊ทํ vs ์ปค๋ฒ๋ง ์ธ๋ฑ์ค ๋น๊ต ๋ถ์ ํ ์๋น์ค ๊ท๋ชจ์ ๋ง๋ ๋ฐฉ๋ฒ ์ ํ
- ํด๋ผ์ฐ๋ ์ํคํ ์ฒ โ ๋ค์ด๋ฒ ํด๋ผ์ฐ๋ Object Storage, Presigned URL ๊ธฐ๋ฐ ์ ๋ก๋ ์ค๊ณ ๊ฒฝํ
- ๋ฌด์ค๋จ ๋ฐฐํฌ โ ๋จ์ผ ์ธ์คํด์ค ํ๊ฒฝ์์ Nginx ํฌํธ ์ค์์นญ ๊ธฐ๋ฐ ๋ธ๋ฃจ๊ทธ๋ฆฐ ๋ฐฐํฌ ๊ตฌํ
- ๋ชจ๋ํฐ๋ง ๊ตฌ์ถ โ Prometheus + Grafana ๊ธฐ๋ฐ ์ค์๊ฐ ์๋ฒ ์ํ ๋ชจ๋ํฐ๋ง ๊ฒฝํ
- ์ฅ์ ๋์ ๊ฒฝํ โ ์ด์ ์ค SSL ์ธ์ฆ์ ์ฅ์ ์ง์ ๋์ ๋ฐ ์ฌ๋ฐ ๋ฐฉ์ง ์ฒด๊ณ ๊ตฌ์ถ









