LOTTERY ๐ (๋ณต๊ถ ๋น์ฒจ ์ ๋ณด ๊ตฌ๋ ํ ์๋น์ค)
LOTTERY ๐
1. ๊ฐ๋ฐ ๋ชฉ์
๊ฐ์ธ์ ์ธ ์ทจ๋ฏธ(?)๋ก ๋งค์ฃผ ๋ณต๊ถ์ ๊ตฌ๋งคํ๊ณ ์๋ค. ๋ก๋๋ QR์ฝ๋๋ก ๋น์ฒจ ๊ฒฐ๊ณผ๋ฅผ ์์ฝ๊ฒ ์ ๊ณตํด์ฃผ์ง๋ง, (๋ฐฐ์ํ์ง๋ง) ๋น์ฒจ ๊ธ์ก ์ ๋ณด๋ฅผ ์ฐพ๊ณ ์ ํ ๋ ๋ค์ด๋ฒ๋ ๋ํ๋ณต๊ถ ์ฌ์ดํธ๋ก ์ ๊ทผํด์ ๋น์ฒจ ๊ฒฐ๊ณผ๋ฅผ ์ฐพ์๋ด์ผ ํ๋ค.
๋ํ, ์คํผ๋ ๋ณต๊ถ๋ ์ข ์ข ํ๋งค์ ์ ๊ณ ์จ๊ณผ ๋จ์ ๋น์ฒจ ๋งค์๋ฅผ ํ์ธํ๊ณ ์ ๋ต์ (?)์ผ๋ก ์ ๊ทผํด์ ๊ตฌ๋งคํ๊ณ ์๋๋ฐ ์ด๋ฅผ ํ์ธํ๊ณ ์ ๋ํ๋ณต๊ถ ์ฌ์ดํธ ์ ์์ด ์ ์ ๋ง์์ก๋ค.
์ด๋ฐ ํ์๊ฐ ๋นํจ์จ์ ์ด๋ผ ์๊ฐํ๊ณ ์ด๋ โ๊ตฌ๋ ํํ๋ก ๋ฐ์๋ณด๊ฒํ๋ฉด ๋๊ฒ ๋๋ฐ?โ๋ผ๋ ์๊ฐ์ผ๋ก ์ด๋ฒ ํ๋ก์ ํธ๋ฅผ ์งํํ๊ฒ ๋์๋ค.
2. ๊ตฌ์กฐ ์ค๊ณ
์ฐ์ ๊ฐ๋จํ ์๋น์ค์ด๊ณ ํผ์ ๊ฐ๋ฐํ๊ณ ์ธํ๋ผ๋ฅผ ๊ตฌ์ถํ๊ณ ์ด์ํด์ผํ๊ธฐ ๋๋ฌธ์ ์์ฝ๊ฒ ์๋น์ค๋ค์ ํ๋ฐ ๋ชจ์ ๊ด๋ฆฌํ ์ ์๋ ๊ตฌ์กฐ๋ก ๊ตฌํํ๊ณ ์ถ์๋ค.
๋ฐ๋ผ์, Kubernetes๋ฅผ ์๋ก ํ์ตํด์ ์ธํ๋ผ๋ฅผ ๊ตฌ์ถํ๋ ๋ฐฉํฅ๋ณด๋ค๋ ์ต์ํ Docker Compose ๋ฐฉ์์ผ๋ก ๊ฐ๋จํ๊ฒ ์ฌ๋ฌ ์๋น์ค๋ค์ ์ ์ํ๊ณ ๋ฐฐํฌํ๊ณ ์ํ์๋ค.
AWS EC2๋ฅผ ์ฌ์ฉํด์ ์ธ์คํด์ค์ ๋ชจ๋ ์๋น์ค๋ค์ Docker Compose ์ปจํ ์ด๋ ํ๊ฒฝ์ผ๋ก ๊ตฌ์ฑํ๊ณ ์ ํ์์ผ๋ฉฐ ๊ตฌ์ฑํ ์๋น์ค ์ํคํ ์ณ๋ ์๋์ ๊ฐ๋ค.
์ค์ ์์๊ฐ์ ์ํคํ ์ณ๋ก EC2 ์ธ์คํด์ค์์ ๋์ํ๊ณ ์์ผ๋ฉฐ ์ธ๋ถ์ ์ธ ์ฌํญ์ ์๋์์ ์์ธํ ์ค๋ช ํ๊ฒ ๋ค.
2-1. ๋ฆฌ๋ฒ์ค ํ๋ก์ ์๋ฒ (Traefik)
์ฐ์ ์ปจํ ์ด๋ ํ๊ฒฝ์ผ๋ก ์ฌ๋ฌ ์๋น์ค(ํฌ๋กค๋ง ์๋ฒ, API ์๋ฒ ๋ฑ๋ฑ)๋ฅผ ๊ฐ๋ฐํ๊ธฐ๋ก ๊ฒฐ์ ํ์๊ณ ์ด ์๋น์ค๋ค์ ๋ฌถ๊ธฐ ์ํ ๋ฆฌ๋ฒ์ค ํ๋ก์ ์๋ฒ๋ฅผ ์ด๋ค ํ๋ ์์ํฌ๋ฅผ ์ฌ์ฉํ ์ง ์ ํํด์ผ ํ๋ค.
NginX
์ Traefik
์ด ๋ณดํธ์ ์ธ ์ ํ์ง์์ผ๋ฉฐ ๊ทธ ์ค ๋๋ Traefik
์ ์ ํํ์๋ค.
-
์์ฌ์ด ์ค์ ์ผ๋ก ๋์ฌ๋ณด๋ ๊ตฌํ ๊ฐ๋ฅํ ์
์ค์ ์ฌ์ฉ ์ค์ธ ํ๋ฉด ์์ ๐
-
์๋์ผ๋ก Letโs Encrypt ์ธ์ฆ์๋ฅผ ๋ฐ๊ธํ๊ณ ๊ฐฑ์ ํ๋ ๊ธฐ๋ฅ์ด ๋ด์ฅ๋ ์
์ด ์ธ์๋ ์ด๋ฏธ ์ฌ์ฉ ์ค์ด๊ธฐ์ ํ์ต์ ์ํ ์๊ฐ์ ํ ์ ํ์ง ์์๋ ๋๋์ ๋ฑ๋ฑ์ ์ด์ ๋ก ์ ํํ๊ฒ ๋์๋ค.
2-2. ํฌ๋กค๋ง ์๋ฒ (Express)
ํฌ๋กค๋ง ์๋ฒ๋ ์ด๋ ํ ๊ธฐ๋ฅ๋ ์ ๊ณตํ์ง ์๊ณ 365์ผ 24์๊ฐ ๋ด๋ด ์ง์ ํ ์๊ฐ์ ํน์ ํ์ด์ง์ ์ ๊ทผํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์์งํด์ผํ๋ฏ๋ก API ์๋ฒ์ ๋ฐ๋ก ๋ถ๋ฆฌํด์ ๊ตฌ์ฑํ์๋ค.
- ์ฌ๋ฌ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ API ์๋ฒ๊ฐ ๋ถํ๋ฅผ ๊ฒฌ๋์ง ๋ชปํด์ ์ปจํ ์ด๋๊ฐ ์ฌ ์์๋๋๋ผ๋ ํฌ๋กค๋ง ์๋ฒ๋ ํญ์ ์๋ํด์ผํ๋ค.
- API ์๋ฒ๊ฐ ์๋์น ์์ ์๋ฌ๋ก ๋์ํ์ง ์์๋ ํฌ๋กค๋ง ์๋ฒ๋ ํญ์ ์๋ํด์ผํ๋ค.
์ ์กฐ๊ฑด์ ์ถฉ์กฑํด์ผํ๋ฏ๋ก API ์๋ฒ์ ๋ณ๋๋ก ๋ถ๋ฆฌํ์ฌ ํฌ๋กค๋ง ์๋ฒ๋ฅผ ์ค๊ณํ์ฌ ์ฌ์ฉํ์๋ค. ์ด๋ ํ ๊ธฐ๋ฅ๋ ์ ๊ณตํ์ง ์์ผ๋ฏ๋ก ๋จ์ํ๋ค. (์๋ ๊ธฐ๋ฅ๋ง์ ์ฐฉ์คํ ์ํํ๋ค.)
// Routes
app.use('/', indexRouter);
app.use('/health', healthRouter);
// Lotto Crawler
const lottoRule = new schedule.RecurrenceRule();
lottoRule.dayOfWeek = [0, new schedule.Range(0, 6)];
lottoRule.hour = 3;
lottoRule.minute = 0;
lottoRule.tz = 'Asia/Seoul';
lottoSchedule(lottoRule);
// Speetto Crawler
const speettoRule = new schedule.RecurrenceRule();
speettoRule.dayOfWeek = [0, new schedule.Range(0, 6)];
speettoRule.hour = 9;
speettoRule.minute = 0;
speettoRule.tz = 'Asia/Seoul';
๋ฐ๋ผ์, ๋จ์ํ ๊ตฌ์กฐ๊ฐ ํ์ํ๋ฏ๋ก (์๋์ ์ผ๋ก) ๊ตฌ์กฐ๊ฐ ๋ณต์กํ NestJS
๋ณด๋ค๋ ์์ ๋กญ๊ณ ๊ฐ๋จํ ํ๋ ์์ํฌ์ธ Express
๋ฅผ ์ ํํด์ ์ฌ์ฉํ์๋ค.
2-3. API ์๋ฒ (NestJS)
๋ค์์ผ๋ก ์ด๋ฒ ํ๋ก์ ํธ์ ํต์ฌ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ API ์๋ฒ๋ ์ต์ํ ํ๋ ์์ํฌ์ธ NestJS
๋ฅผ ์ฌ์ฉํ์๋ค.
API ์๋ฒ๋ LOTTERY๐์ ์ฃผ์ ๊ธฐ๋ฅ์ ๋ชจ๋ ๋ด๋นํ๋ค.
- LOTTERY๐ Repository์ Watch๋ฅผ ํด๋ฆญํ ์ ์ ๋ค์
Github API
๋ฅผ ์ฌ์ฉํ์ฌ ์ ๊ธฐ ๋ฉ์ผ๋ง ์๋น์ค Bolt
๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ๋ ์ฑ์ ํตํ ์ฌ๋ฌ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ ์๋น์ค- ์ฌ๋ ์ฑ ์ฌ์ดํธ ๋ฌธ์ํ๊ธฐ ๋ฐ ๊ธฐํ ์ธ๋ถ API ์ ๊ณต
์ ๊ธฐ์ ์ธ ์ค์ผ์ค๋ง์ ํตํด์ ๋ฉ์ผ์ด ๋ฐ์ก๋์ด์ผ ํ๊ณ ์ฌ๋ ์ฑ์ ํตํด ์ธ๋ถ์ ์์ฒญ์ ๋ฐ์ ์ ๋ณด๋ฅผ ์ ๋ฌํด์ผ ํ๋ฏ๋ก ๋ค์ค ์ธ์คํด์ค ๊ตฌ์กฐ๋ก ๊ตฌ์ฑ๋์๋ค. (๋ค์ค ์ธ์คํด์ค ํ๊ฒฝ์์ ๋์์ฑ ๋ฌธ์ ๋ ๊ณผ๊ฑฐ ํฌ์คํ ๊ธฐ์ ๋ด์ฉ์ ๋์ ํ์๋ค.)
๐ ๋ค์ค ์ธ์คํด์ค ํ๊ฒฝ์์ ๋์์ฑ์ ํด๊ฒฐํ๊ธฐ ์ํ Redis ๋ถ์ฐ๋ฝ ๊ตฌํํ๊ธฐ
์ด ์ธ์๋ ์์ง ์ฌ๋ฌ ๊ธฐ๋ฅ๋ค์ด ๊ณ์ ๋์ ๋ ์์ ์ด๋ฏ๋ก ์์ง ๊พธ์คํ ๊ฐ๋ฐ์ด ์งํ์ค์ด๊ธฐ๋ ํ๋ค.
- โ๋ฌธ์ํ๊ธฐโ ์์ฑ์ ์ค์๊ฐ ์๋ฆผ ๋ชจ๋ํฐ๋ง ๊ธฐ๋ฅ
- ๋ต๋ณ ๋ํ ์ฌ๋(๊ฐ์ธ ์ฑ๋)์์ ์ด๋ฉ์ผ ํ ํ๋ฆฟ์ ์ฌ์ฉํ์ฌ ๋ต๋ณ ๊ธฐ๋ฅ
- ํ ์คํธ ์ฝ๋ ์์ฑ
2-4. ์บ์ฑ ์๋ฒ (Redis)
ํฌ๋กค๋ง ์๋ฒ์์ ์ป์ ๋ณต๊ถ ๋น์ฒจ ์ ๋ณด๋ค์ ์ ๊ทํ๋ ํ DB์ ์ ์ฅ๋๋ค.
์ต์ ํ์ฐจ ์ ๋ณด๋ค์ ์์ฃผ ์ฌ์ฉ๋ ํ ๋ฐ, ๋งค๋ฒ DB์ ์ ๊ทผํ์ฌ ๊ฐ์ ธ์ค๊ฒ ๋๋ฉด ๋ถํ์ํ ์ปค๋ฅ์ ์ด ๋ฐ์ํ๊ณ DB ์๋ฒ๊ฐ ์ฑ๋ฅ์ด ์ข์ง ์์ผ๋ฏ๋ก (๊ฐ์ธ NAS ์๋ฒ์ ์ฌ๋ ค๋๊ณ ์ฌ์ฉ์ค์ด๋ค.) ์ ๋ณด ์ ๋ฌ์ ๋ฎ์ ์๋๋ก ์ ๊ณต๋ ์ ์๋ค.
-
์ด๋ ์์ ์ฌ๋ด ๋์๊ด ์ฌ๋ ์ฑ ๊ฐ๋ฐ์ ์ด๋ฏธ ๊ฒช์ ์ด์์๋ค.
์ ๋ณด ์ ๋ฌ ์๋๋ฅผ ๋ณด์ฅํ๊ธฐ ์ํด Redis๋ฅผ ํ์ฉํด์ ๋น ๋ฅธ ์๋๋ก ๊ณต์ ํ ์ ์๊ฒ ์ค๊ณํ์๋ค.
- ์ ๋ณด๋ฅผ ์ ์ฅํ๋ ์๋ฒ(ํฌ๋กค๋ง ์๋ฒ)์ ์ ๋ฌํ๋ ์๋ฒ(API ์๋ฒ)๊ฐ ์๋ก ๋ถ๋ฆฌ๋์ด ์ค๊ณ๋์ด ์์ผ๋ฏ๋ก Redis ์บ์ฑ ๋ ์ด์ด๋ฅผ ๋์ด ๋ ์๋ฒ๊ฐ์ ๋ฌผ๋ฆฌ์ ์ธ ๊ฒฉ์ฐจ๋ฅผ ์ต๋ํ ์ขํ๊ณ ์ ๋์ ํ์๋ค.
2-5. ์ ์ ์น์ฌ์ดํธ ํธ์คํ ์๋ฒ (NginX)
์ ์ผ ๋ง์ง๋ง์ ๊ตฌํ๋ ์๋น์ค ์ปจํ ์ด๋์ด๋ค. (๊ธฐํ ๋จ๊ณ์์๋ ๊ณ ๋ ค๋์์ด ์๋์๋ค. ๐ฅฒ)
์ฌ๋ ์ฑ์ ์ฌ๋ ์ฑ ๋๋ ํ ๋ฆฌ์ ๋ฐฐํฌํ๊ณ ์ ์ฑ์ ์ถ์ํ๋ คํ๋ ์ฌ๋ ์ฑ ์๊ฐ ์น ํ์ด์ง๊ฐ ํ์์ ์ผ๋ก ์ ์ถ๋์ด์ผํ๋ค.
- ์ฑ ์ค์น ๋ฒํผ์ ๋ดํฌํด์ผํ๊ณ , ์ด๋ค ์ ๋ณด๋ค์ ์์งํ๊ณ ๊ด๋ฆฌํ๋์ง ๊ทธ๋ฆฌ๊ณ ํผ๋๋ฐฑ์ ๋ฐ์ ์ ์๋ ๊ณ ๊ฐ ์ง์ ํ์ด์ง ๋ํ ๋ดํฌ๋์ด์ผํ๋ค.
๋ฐ๋ผ์, ๊ฐ๋จํ๊ฒ ์ ์ ์น ์ฌ์ดํธ๋ก ์น ์ฌ์ดํธ ํผ๋ธ๋ฆฌ์ฑ ํ ๋ฐฐํฌํ๊ธฐ ์ํ ๋ชฉ์ ์ผ๋ก ์ค๊ณ์ ํฌํจ๋์๋ค.
3. ๊ฐ๋ฐ ๊ณผ์ ์ค ์ด๋ ค์
๋ชจ๋ ๊ณผ์ ์ด ์ํํ์ง ์์์ง๋ง ํ๋๋ง ๊ผฝ์๋ฉด ์ฌ๋ ์ฑ์ ๋ฐฐํฌํ๋ ๊ณผ์ ์ด ์ ์ผ ๋๊ด์ด์๋ค. (์์ง๋ ์ฌ์ฌ ๋ฐ๊ธฐ์ํ ์ต์ ์กฐ๊ฑด์ ์ถฉ์กฑํ์ง ๋ชปํ๋ค. ๐ฎโ๐จ)
์ฌ์ฌ ํผ๋๋ฐฑ ๋ด์์ ๋จผ์ ์กํ์ ์ ์ ์ฌ์ฌ ์ ์ถ์ ๋ชปํ์๋ค. (๋ด์ฉ์ ์์ฝํ๋ฉด ์๋์ ๊ฐ๋ค.)
- ์ฌ๋ ์ฑ ์๊ฐ ์น ํ์ด์ง๊ฐ ์ฌ๋ฐ๋ฅด์ง ์์ ์์์ด๋ค. (โ ์ฌ๋ ์ฑ ์น ํ์ด์ง ๋ฐฐํฌ ์๋ฃ)
- ์ฌ์ฉํ์ง ์๋ ๊ถํ์ด ํฌํจ๋์ด์๋ค. (โ ๋ถํ์ ๊ถํ ์ ๋ฆฌ ์๋ฃ)
- 10๊ฐ ์ด์์ ์ํฌ์คํ์ด์ค์ ์ค์น๋์ด์ผํ๋ค.
๋ค๋ฅธ๊ฑด ์ค์ค๋ก ํด๊ฒฐ์ด ๊ฐ๋ฅํ๋ฐ, 10๊ฐ ์ด์์ ์ํฌ์คํ์ด์ค ์ค์น๋ ํ์ธ์ ๋์์ ๋ฐ์์ผํ๋ค. ๐ฅฒ (ํ๋ก์ ํธ ๊ฐ๋ฐ์ด ์๋ฃ๋๋ฉด ๊ฐ๋ฐ์ ์ปค๋ฎค๋ํฐ ๊ฐ์ ๊ณณ์ ํ๋ณด๋ฅผ ํด๋ณผ๊น ์๊ฐ์ค์ด๋ค.)
์ด ์ธ์๋ โํผ์โ ๊ฐ๋ฐํ๊ธฐ ๋๋ฌธ์ ์ฌ์ฉ์ฑ์ด ํธํ์ง, ์ค์ ๋ก ์ ์ฉํ์ง์ ๋ํ ํ ์คํธ๋ฅผ ํด๋ณด๊ธฐ๊ฐ ๋๋ฌด๋๋ ์ด๋ ค์ ๋ค.
๊ทธ๋์ ์ค์ ๋ก ๊ธฐ๋ฅ์ด ํ๋์ฉ ๊ตฌํ๋ ๋๋ง๋ค, ์ฃผ๋ณ์ ์๋ ํ์๋ค์๊ฒ ๋จผ์ ๋ง์ด ํ๋ณด๋ํ๊ณ ํผ๋๋ฐฑ ์์ฒญ์ ๋ง์ด ๋๋ ธ๋๊ฑฐ ๊ฐ๋ค.
๊ฒฐ๊ตญ ์๋ฌด๋ฆฌ ์์ ์ฌ์ด๋ ํ๋ก์ ํธ๋ผ๋ โํผ์โ์๋ ํด๊ฒฐํ์ง ๋ชปํ๋ ์์๊ฐ ๋ถ๋ช ํ ๋ฐ์ํ๋ค๋ผ๋ ์ ์ด ๊ฐ์ฅ ์ด๋ ค์ด ์ ์ด ์๋์๋ ์ถ๋ค.
๐ค Understanding
์ด๋ฒ ํ๋ก์ ํธ๋ ์ ๋ง ์์ ์์ด๋์ด์ธ ๋ณต๊ถ ๋น์ฒจ ์ ๋ณด๋ฅผ โ๊ตฌ๋ ํํ๋ก ๋ฐ์๋ณด๊ฒํ๋ฉด ๋๊ฒ ๋๋ฐ?โ๋ก ์์ํ์๋ค.
์ค์ ๋ก ์ฒ์ ๊ธฐํ ๋จ๊ณ์์๋ ๋ก๋ ๋น์ฒจ ๊ฒฐ๊ณผ๋ง LOTTERY๐ Repository์ Watch๋ฅผ ๋๋ฌ์ค ์ ์ ๋ค์๊ฒ ์ ๊ธฐ ๊ตฌ๋ ์ด๋ฉ์ผ ์ ๋ณด๋ฅผ ๋ฐ์กํด์ฃผ๋ ํํ๋ก ๊ธฐํ๋์์๋ค.
๊ฐ๋ฐ ํ ์ฃผ๋ณ์ฌ๋๋ค์๊ฒ๋ง ์ถ์ํด๋ด๋ ์ ๋ง ์ฌ๋ฌ ํผ๋๋ฐฑ์ ๋ฐ์ ๊ฒ ๊ฐ๋ค.
- ์ ๋ ๊นํ๋ธ ๊ณ์ ์ด ์๋๋ฐ์? (๋น๊ฐ๋ฐ ์ง๊ตฐ)
- ๋ก๋ ๋ง๊ณ ์คํผ๋๋ ์๋ ค์ฃผ์ธ์.
- ์ฑ ์๊ฐ ์น ์ฌ์ดํธ ๋ชจ๋ฐ์ผ ํ๊ฒฝ์์ ๋๋ฌด ๋ถํธํด์.
์ฌ๋ฌ ๊ฑด์ ํ ํผ๋๋ฐฑ์ ํ ๋๋ก ๊พธ์คํ ๋ฐ์ ํ ์ ์์๋๊ฑฐ ๊ฐ๋ค.
์ข์ ์๋น์ค๋ฅผ ๋ง๋ค๊ธฐ ์ํด ๋จผ์ ๊ฐ๋ฐ์ ์์ํ๊ณ , ์ฌ์ฉ์๋ค๋ก๋ถํฐ ํผ๋๋ฐฑ์ ๋ฐ์ ์ ์ง์ ์ผ๋ก ๊ฐ์ ํด ๋๊ฐ๋ ๊ฐ๋ฐ ๋ฐฉ์(์ ์์ผ(Agile) ๊ฐ๋ฐ ๋ฐฉ๋ฒ๋ก )์ ํ์์ฑ์ ๋ค์ ํ๋ฒ ๋ชธ์ผ๋ก ๋๋ ์ ์์๋ค.
์์ง ์์ฑ๋ ํ๋ก์ ํธ๊ฐ ์๋๊ธฐ์ ์์ง ๊ฐ๋ฐํด ๋๊ฐ์ผํ ๋ถ๋ถ๋ค์ด ๋ง์ด ๋จ์์๊ณ , ์ ์์ผ๋ก ์ฌ๋ ์ฑ ๋๋ ํ ๋ฆฌ์๋ ์ฌ์ฌ ๋ฐ์ LOTTERY๐ ์ฑ์ ๊ผญ ๋ฐฐํฌํด๋ณด๊ณ ์ถ๋ค.