"To Myongji (๋ช ์ง๋ํ๊ต ํ์๋ค์ ์ํด)" ํฌ๋ช ์ง๋ ํ์ํ๋น ์งํ ๋ด์ญ์ ํฌ๋ช ํ๊ฒ ๊ณต๊ฐํ์ฌ ํ์ ์ฌํ์ ์ ๋ขฐ๋ฅผ ํ๋ณตํ๊ธฐ ์ํ ํ์ํ๋น ํตํฉ ๊ด๋ฆฌ ํ๋ซํผ์ ๋๋ค. ๊ต๋ด ํก๋ น ์ฌ๊ฑด์ ๊ณ๊ธฐ๋ก ๊ธฐํ๋์์ผ๋ฉฐ , ๊ธฐ์กด ์์ ๋ฐฉ์์ ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ ํ๊ณ๋ฅผ ๊ธฐ์ ์ ์ผ๋ก ๊ทน๋ณตํ๊ณ ์ ์์๋์์ต๋๋ค.
๐ง Backend
-
๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ ํ๋ณด ๋ฐ ์๋ํ
๋จ์ CRUD๋ฅผ ๋์ด, ์๋น์ค ๋์ ์ฅ๋ฒฝ์ ๋ฎ์ถ๊ณ ์ ๋ขฐ๋๋ฅผ ๋์ด๊ธฐ ์ํด 4๊ฐ์ง ์ ๋ก๋ ํ์ดํ๋ผ์ธ์ ๊ตฌ์ถํ์ต๋๋ค.
- Tossbank PDF ๊ฒ์ฆ (Trust): PDF ๋ด ๊ณ ์ ๋ฒํธ๋ฅผ ํ์ฑํ์ฌ ์ง์ ์ฌ๋ถ๋ฅผ ํ์ธํ๊ณ , ๊ฒ์ฆ๋ ๋ด์ญ์ ์ธ์ฆ ๋งํฌ๋ฅผ ๋ถ์ฌํ์ฌ ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ ๋ณด์ฅํ์ต๋๋ค.
- AI OCR (Convenience): ๋ชจ๋ฐ์ผ ์์์ฆ ์ด๋ฏธ์ง๋ฅผ ํ ์คํธ๋ก ์๋ ๋ณํํ์ฌ ํ์ํ ๊ฐ๋ถ์ ์ฅ๋ถ ์์ฑ ์๊ณ ๋ฅผ ํ๊ธฐ์ ์ผ๋ก ๋จ์ถํ์ต๋๋ค.
- Batch CSV Upload (Onboarding): ๊ธฐ์กด ์์ ๊ธฐ๋ฐ ์ฅ๋ถ ๋ฐ์ดํฐ๋ฅผ ํ ๋ฒ์ ๋ง์ด๊ทธ๋ ์ด์ ํ ์ ์๋๋ก ์ง์ํ์ฌ ์ ๊ท ํ์ํ์ ์๋น์ค ๋์ ์ฅ๋ฒฝ ์ ๊ฑฐํ์ต๋๋ค.
- ์๊ธฐ ์ ๋ ฅ (Basic): ์์ธ ์ผ์ด์ค๋ฅผ ๋๋นํ ๊ธฐ๋ณธ์ ์ธ ์ง์ ์ ๋ ฅ ๊ธฐ๋ฅ ์ ๊ณตํฉ๋๋ค.
- ๊ณ ์ฑ๋ฅ ์กฐํ ๋ฐ ์บ์ฑ ์ ๋ต
- ์บ์ ์ ์ค๋ฅ ์ต์ ํ: ์กฐํ ์๋ ํฅ์์ ์ํด ํ์ด์ง(Pagination) ์ฒ๋ฆฌ๋ฅผ ์ํํ๊ณ , ์บ์ฑ ๋จ์๋ฅผ ํ์ด์ง๋ณ๋ก ์ธ๋ถํํ์ฌ ์บ์ ์ ์ค๋ฅ (Hit Rate)์ ๋์์ต๋๋ค.
- Cache Stampede ๋ฐฉ์ง: Redis ์ ์ฉ ์ sync = true ์ค์ ์ ํ์ฉํ์ฌ, ์ ๊ต์ ๋์ ์ ์ ์ ๋ฐ์ํ๋ ๋๋์ DB ๋ถํ(Cache Miss ์ํฉ)๋ฅผ 1ํ์ ์กฐํ๋ก ์ต์ํํ์ต๋๋ค.
- ๋ณตํฉ ์ธ๋ฑ์ค ์ ์ฉ: (student_club_id, date DESC, id DESC) ์ธ๋ฑ์ค๋ก filesort ๋น์ฉ์ ์ ๊ฑฐํ๊ณ t3 ์ธ์คํด์ค์ ์์ ํจ์จ์ฑ์ ๊ทน๋ํํ์ต๋๋ค.
- ์ธํ๋ผ ๋ชจ๋ํฐ๋ง ๋ฐ ๋น์ฉ ์ต์ ํ (FinOps)
- RDS to MySQL Container ๋ง์ด๊ทธ๋ ์ด์ : AWS ์ ์ฑ ๋ณํ์ ๋์ํ์ฌ RDS ๋์ EC2 ๋ด Docker MySQL ํ๊ฒฝ์ผ๋ก ์ด์ ํจ์ผ๋ก์จ ์ ์ง ๋น์ฉ์ 50% ์ด์ ์ ๊ฐํ์ต๋๋ค.
- Alloy ๊ธฐ๋ฐ ํตํฉ ๋งคํธ๋ฆญ ์์ง: Grafana Alloy๋ฅผ ํ์ฉํด Prometheus ๋งคํธ๋ฆญ(CPU, RAM)๊ณผ Loki ๋ก๊ทธ๋ฅผ ๋์์ ์์งํ์ฌ ์ธํ๋ผ ๊ฐ์ฉ์ฑ ์ค์๊ฐ ๋ชจ๋ํฐ๋ง์ ๊ตฌํํ์ต๋๋ค.
- OOM ๋ฐฉ์ง: ์ ์ฌ์ t3.micro ํ๊ฒฝ์์ ๊ฐ์ฉ RAM ํ๋ณด๋ฅผ ์ํด ๋ฆฌ๋ ์ค Swap ๋ฉ๋ชจ๋ฆฌ๋ฅผ 3GB๋ก ์ฆ์คํ๊ณ ๋ฆฌ์์ค ํ ๋น์ ์ต์ ํํ์ต๋๋ค.
- ์ฝ๋ ํ์ง ๋ฐ ์์ ์ฑ (Reliability)
- ํ ์คํธ ์ฝ๋ ์๋ํ: * ๋จ์ ํ ์คํธ(Unit Test): JUnit5์ Mockito๋ฅผ ํ์ฉํ์ฌ ์๋น์ค ๋ ์ด์ด์ ๋น์ฆ๋์ค ๋ก์ง์ ๋ ๋ฆฝ์ ์ผ๋ก ๊ฒ์ฆํ์ต๋๋ค.
- ํตํฉ ํ ์คํธ(Integration Test): API ์๋ํฌ์ธํธ๋ถํฐ DB ์ฐ๋๊น์ง์ ์ ์ฒด ํ๋ก์ธ์ค๋ฅผ ๊ฒ์ฆํ์ฌ ๋ฐฐํฌ ์์ ์ฑ ํ๋ณดํ์ต๋๋ค.
- ๊ฐ์ฌ(Audit) ์์คํ : ๋ฐ์ดํฐ์ ์์ฑ/์ญ์ ์์จ์ฑ์ ๋ณด์ฅํ๋, ์์ ๋ฐ ์ญ์ ๋ฐ์ ์ ๋ก๊ทธ๋ฅผ ํตํด ์ด๋ ฅ์ ์ถ์ ํ๋ ํฌ๋ช ํ ๊ฐ์ ์ฒด๊ณ ๊ตฌ์ถํ์ต๋๋ค.
- [Performance] ์ธ๋ฑ์ฑ ๋ฐ ์บ์ฑ์ ํตํ ์กฐํ ์ฑ๋ฅ 12.5๋ฐฐ ๊ฐ์ .
-
๋ฌธ์ : 13,000๋ช ์ฌํ์ ๋์ ์ ์ ์, t3.micro์ ์์ ํ๊ณ๋ก ์ธํ CPU ํฌ๋ ๋ง ๊ณ ๊ฐ ๋ฐ ์๋ฒ ์ ์ง ์ํ.
-
์์ธ: ๊ธฐ์กด ์ธ๋ฑ์ค๊ฐ ์ ๋ ฌ ์กฐ๊ฑด(date, id)์ ํฌํจํ์ง ์์ DB ๋ฉ๋ชจ๋ฆฌ ๋ด ๊ฐ์ ์ ๋ ฌ(Using filesort)์ด ๋ฐ์ํ์ฌ CPU ๋ถํ ๊ฐ์ค.
-
ํด๊ฒฐ: (student_club_id, date DESC, id DESC) ๋ณตํฉ ์ธ๋ฑ์ค๋ก ์ ๋ ฌ ์ฐ์ฐ์ ์ ๊ฑฐํ๊ณ , Redis์ sync=true ์ค์ ์ ์ ์ฉํ์ฌ Cache Stampede(์บ์ ๋ง๋ฃ ์ DB ๋ถํ ์ ๋ฆผ) ํ์์ ๋ฐฉ์ง.
-
์ฑ๊ณผ: DB CPU ์ ์ ์จ 23.8% โ 0.42% โ 24.96% โ 0.57% ๊ฐ์, ์๋ต ์๊ฐ 254ms โ 20ms โ 81ms โ 35ms๋ก ๊ฐ์ .
- [FinOps] RDS ๋ง์ด๊ทธ๋ ์ด์ ๋ฐ ๋ฉ๋ชจ๋ฆฌ ํ๊ณ(OOM) ๊ทน๋ณต
-
๋ฌธ์ : AWS ํ๋ฆฌํฐ์ด ๋ง๋ฃ๋ก ์ธํ ์ $40 ์ด์์ ๋น์ฉ ๋ถ๋ด ๋ฐ ์๋น์ค ์ข ๋ฃ ์๊ธฐ.
-
๊ธฐ์ ์ ๋๊ด: RAM 1GB ํ๊ฒฝ์์ Spring, MySQL, Redis, Monitoring ์คํ ๋์ ๊ตฌ๋ ์ OOM Killer์ ์ํ ์์ ๋ค์ด ๋ฐ์.
-
ํด๊ฒฐ: RDS๋ฅผ ์ ๊ฑฐํ๊ณ EC2 ๋ด Docker MySQL๋ก ๋ง์ด๊ทธ๋ ์ด์ ํ์ฌ ๋น์ฉ์ 50% ์ด์ ์ ๊ฐ. ๋ถ์กฑํ ๋ฌผ๋ฆฌ ๋ฉ๋ชจ๋ฆฌ๋ ๋ฆฌ๋ ์ค Swap(3GB) ์ฆ์ค๊ณผ Docker deploy.resources.limits ์ค์ ์ ํตํ ์ปจํ ์ด๋๋ณ ์์ ๊ฒฉ๋ฆฌ๋ก ํด๊ฒฐ.
-
์ฑ๊ณผ: ์ถ๊ฐ ํ๋์จ์ด ๋น์ฉ ์์ด ์๋น์ค ๊ฐ์ฉ์ฑ(Availability) ํ๋ณด ๋ฐ ์ด์๋น ์ต์ ํ.
- [Infrastructure] Nginx-Certbot ์ํ ์์กด์ฑ ํด๊ฒฐ (SSL ๋ฐ๊ธ)
-
๋ฌธ์ : Nginx๋ ์ธ์ฆ์๊ฐ ์์ผ๋ฉด ๊ตฌ๋๋์ง ์๊ณ , Certbot์ Nginx๊ฐ ๋ ์์ด์ผ ์ธ์ฆ์๋ฅผ ๋ฐ๊ธ๋ฐ๋ ๊ต์ฐฉ ์ํ(Deadlock) ๋ฐ์.
-
ํด๊ฒฐ: standalone ๋ชจ๋๋ฅผ ํ์ฉํ์ฌ Nginx๋ฅผ ์ผ์ ์ค์งํ ์ํ์์ Certbot์ด ์ง์ 80ํฌํธ๋ฅผ ์ ์ ํด ์ธ์ฆ์๋ฅผ ์ ๋ฐ๊ธ ๋ฐ๋๋ก ์กฐ์น. ์ดํ ๋ณผ๋ฅจ ๋ง์ดํธ๋ก ์ธ์ฆ์๋ฅผ ๊ณต์ ํ์ฌ Nginx ์ ์ ๊ธฐ๋ ์ฑ๊ณต.
-
๊ฒฐ๊ณผ: Docker ํ๊ฒฝ์์์ HTTPS ๊ตฌ์ถ ์๋ํ ๋ฐ ์๋ฒ ์ด์ ํ๋ก์ธ์ค ์ ๋ฆฝ.
- [Monitoring] absent() ํจ์๋ฅผ ํ์ฉํ "๋ฐ์ดํฐ ์ฆ๋ฐ" ์๋ฆผ ๊ตฌ์ถ
-
๋ฌธ์ : ์ปจํ ์ด๋ ๋ค์ด ์ ๋ฐ์ดํฐ ์์ง ์์ฒด๊ฐ ์ค๋จ๋์ด, ์ผ๋ฐ์ ์ธ ์๊ณ์น(up == 0) ์๋ฆผ์ด 'No Data' ์ํ๋ก ๋น ์ง๋ฉฐ ์๋ฆผ์ด ๋ฌด๋ ฅํ๋จ.
-
ํด๊ฒฐ: Prometheus์ absent() ํจ์๋ฅผ ๋์ . "๋ฐ์ดํฐ๊ฐ ์กด์ฌํ์ง ์๋ ์ํฉ" ์์ฒด๋ฅผ ์กฐ๊ฑด์ผ๋ก ์ค์ ํ์ฌ ์ปจํ ์ด๋ ์๋ฉธ ์์๋ ๋์ค์ฝ๋ ์๋ฆผ์ด ์ค๋๋ก ์ฟผ๋ฆฌ ์ต์ ํ.
-
๊ฒฐ๊ณผ: ์ฅ์ ์ธ์ง ์๋ ํฅ์ ๋ฐ ์ปจํ ์ด๋ ์ ์ง ํ 1๋ถ ์ด๋ด ๋์ ์ฒด๊ณ ๊ตฌ์ถ.
- [Search] Full-Text Search ๋์ ์ ํตํ ๊ฒ์ ํจ์จํ
-
๋ฌธ์ : LIKE %keyword% ์ฌ์ฉ ์ ๋ฐ์ดํฐ ์์ ๋น๋กํ ์ฑ๋ฅ ์ ํ ๋ฐ ํ๊ตญ์ด ๋จ์ด ์ผ๋ถ ๊ฒ์(์: '์ํ') ์ ์ธ๋ฑ์ค ๋ฏธ์ ์ฉ ๋ฌธ์ .
-
ํด๊ฒฐ: MySQL Full-Text Index์ **n-gram parser(token_size=2)**๋ฅผ ๋์ ํ์ฌ 2๊ธ์ ๋จ์์ ํ ํฐ ์์ธ ์์ฑ. RDS ํ๋ผ๋ฏธํฐ(ft_min_word_len) ์ต์ ํ ๋ณํ.
-
๊ฒฐ๊ณผ: ๋๋ ๋ฐ์ดํฐ์ ์์๋ ์ ์ฐํ ํค์๋ ๊ฒ์ ์ง์ ๋ฐ ์ผ์ ํ ์กฐํ ์๋ ๋ณด์ฅ.
๐ ์์์ฆ ๊ด๋ฆฌ ์์คํ
- ์๋ ๊ฒ์ฆ ๋ฑ๋ก: ํ ์ค๋ฑ ํฌ PDF ํ์ฑ ๋ฐ AI OCR์ ํตํ ์๋ ๊ธฐ์ .
- ๋ฐ์ดํฐ ์ถ์ถ: ์๋ณ ์ฅ๋ถ ๋ฐ์ดํฐ CSV ๋ค์ด๋ก๋ ๊ธฐ๋ฅ.
- ํ์ด์ง ์กฐํ: Redis ์บ์ฑ์ด ์ ์ฉ๋ ๊ณ ์ฑ๋ฅ ์์์ฆ ๋ชฉ๋ก ์กฐํ.
๐ฅ ์์ ์ธ์ฆ ๋ฐ ๋ณด์
- ์ธ๊ฐ ์์คํ : ํ์ฅ ๋ฐ ๋ถ์ ์ ๋ณด๋ฅผ ๊ด๋ฆฌ์๊ฐ ์ฌ์ ์ ๋ฑ๋กํ์ฌ ์์ ๋งค์นญ ํ ๊ฐ์ ํ์ฉ .
- ๋ก๊ทธ ์ถ์ : Grafana Loki๋ฅผ ํตํ ๋ฏผ๊ฐ ์ก์ (์์ /์ญ์ ) ์ค์๊ฐ ๋ก๊น ๋ฐ ๊ฐ์ฌ.
| ์งํ | ๊ฐ์ ์ (Full Scan) | ๊ฐ์ ํ (Index + Cache) | ๊ฐ์ ํจ๊ณผ |
|---|---|---|---|
| DB CPU ์ฌ์ฉ๋ฅ | 24.96% | 0.57% | ์ฝ 98% ๊ฐ์ |
| ํ๊ท ์๋ต ์๊ฐ | 81ms | 35ms | ์ฝ 2.3๋ฐฐ ํฅ์ |
| ์ฒ๋ฆฌ๋ (Iterations) | 7,955ํ | 9,780ํ | ์ฝ 23% ์ฆ๊ฐ |


