์ ๋ขฐํ ์ ์๋ ์๊ฐ๋ ์ธ์ ํธ์ ์๋ฆผ ์์คํ ๊ตฌ์ถ
์ ์ธ๊ณ ์์ฒ ๋ช ์ ์ฌ์ฉ์์๊ฒ ์์ฌ ์๋ฆผ, ๊ธฐ๋ถ ํ์ธ, ์๋ถ ์ญ์ทจ ์๋ฆผ, ์๋ฉด ์ ํธ, ๋ง์ถค ์๋ฆผ ๋ฑ ๊ฐ์ธํ๋ ๋งค์ผ์ ์๋ฆผ์ ๋ณด๋ด์ผ ํ๋ ๊ฑด๊ฐ & ์ฐ๋น ์ฑ์ด ์์์ต๋๋ค. ํต์ฌ์ ๋ชจ๋ ์๋ฆผ์ด ์ ํํ ํ์ง ์๊ฐ์, ๋จ ํ ๋ฒ๋ง, ๊ทธ๋ฆฌ๊ณ ์๋ํ์ง ์๋ ๊ธฐ๊ธฐ์๋ ์ ๋ ๋๋ฌํ์ง ์์์ผ ํ๋ค๋ ๊ฒ์ด์์ต๋๋ค. ์ฐ๋ฆฌ๋ ์ด๋ฅผ ๊ฐ๋ฅํ๊ฒ ํ๋ ๋ถ์ฐ ํ์ดํ๋ผ์ธ์ ์ค๊ณํ๊ณ ๊ตฌ์ถํ์ต๋๋ค.
๋น๋ฉด ๊ณผ์
- ๋๊ท๋ชจ ์๊ฐ๋ ์ ํ์ฑ. "์ค์ 9์ ์์นจ ์์ฌ ์๋ฆผ"์ ์ฌ์ฉ์๋ง๋ค ๋ค๋ฅธ ์๋ฏธ๋ฅผ ๊ฐ์ง๋๋ค. ์๋ฒ ์๊ฐ์ผ๋ก ๋ณด๋ด๋ฉด ์๋๋์ ๋๊ตฐ๊ฐ์๊ฒ๋ ์๋ฒฝ 3์์ ์๋ฆผ์ด ๊ฐ ๊ฒ์ ๋๋ค. ๊ฐ ์๋ฆผ์ ์ฌ์ฉ์์ ํ์ง ์๊ฐ์ ๋ง์ถฐ์ผ ํ์ต๋๋ค.
- ์คํธ ๋ฐ ์ค๋ณต ์์. cron ์ค์ผ์ค๋ง์ ํ์ฐ์ ์ผ๋ก ๊ฒน์น๊ณ ๋ค์ ์คํ๋ฉ๋๋ค. ์๊ฒฉํ ๋ณด์ฅ์ด ์์ผ๋ฉด ํ ๋ช ์ ์ฌ์ฉ์๊ฐ ๋์ผํ "์ ์ฌ ์๊ฐ ๐ฅ" ์๋ฆผ์ ๋์ธ ๋ฒ ๋ฐ์ ์ ์์ผ๋ฉฐ, ์ด๋ ์ฑ ์ญ์ ๋ก ์ด์ด์ง ์ ์์ต๋๋ค.
- ๊ธฐ๊ธฐ ์ ๋ขฐ์ฑ ๋ถ์กฑ. ์ฌ์ฉ์๋ ์ฑ์ ์ญ์ ํ๊ณ , ๊ถํ์ ์ฒ ํํ๋ฉฐ, ํธ์ ํ ํฐ์ ์ง์์ ์ผ๋ก ๋ณ๊ฒฝํฉ๋๋ค. ์ค๋๋ ํ ํฐ์ ์๋ฆผ์ ๋งน๋ชฉ์ ์ผ๋ก ๋ณด๋ด๋ ๊ฒ์ ๋ฆฌ์์ค๋ฅผ ๋ญ๋นํ๊ณ ์ ๋ฌ ์งํ๋ฅผ ์์์ํต๋๋ค.
- ๋ฌด์ฐจ๋ณ ์ค์ผ์ค๋ฌ ์์ด ์ ํํ ํ์ด๋ฐ. 60์ด๋ง๋ค ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๊ณ์ ๋๋๋ฆฌ๋ cron ์์ด ์๋ฐฑ ๊ฐ์ ์๋ฆผ์ ์ ํํ ์๊ฐ์ ์ ๋ฌํ๋ ค๋ฉด ๋จ์ํ ํด๋ง๋ณด๋ค ๋ ์ค๋งํธํ ๋ฉ์ปค๋์ฆ์ด ํ์ํ์ต๋๋ค.
์ฐ๋ฆฌ์ ์๋ฃจ์
์ฐ๋ฆฌ๋ ๋ฌด์์ ๋ณด๋ผ์ง, ์ธ์ ๋ณด๋ผ์ง, ๊ทธ๋ฆฌ๊ณ ์ค์ ๋ก ๋ณด๋ด๋ ๊ณผ์ ์ ๋ช ํํ๊ฒ ๋ถ๋ฆฌํ๋ 3๋จ๊ณ ํ์ดํ๋ผ์ธ์ ๊ตฌ์ถํ์ฌ ๊ฐ ๋จ๊ณ๊ฐ ๋ ๋ฆฝ์ ์ผ๋ก ์คํจํ๊ณ ๋ณต๊ตฌํ ์ ์๋๋ก ํ์ต๋๋ค. ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ์ง์ค์ ์์ฒ์ด๋ฉฐ, ๋ฉ์์ง ํ๋ ์ ํํ ํ์ด๋ฐ์ ์ฒ๋ฆฌํ๊ณ , ๋จ์ผ ์์ปค ๊ณ์ธต์ ํธ์ ํ๋ก๋ฐ์ด๋์ ํต์ ํฉ๋๋ค.

์ํคํ ์ฒ
- Expo-notifications๋ iOS์ Android ๋ชจ๋์ ๋จ์ผ ํ ํฐ ํ์๊ณผ ์ ๋ฌ API๋ฅผ ์ฌ์ฉํ๋ ๋ค์ดํฐ๋ธ ์ฑ๋, ๊ณ ์ ํ ์๋ฆฌ ๋ฐ ๋ฅ ๋งํฌ๋ฅผ ๊ฐ์ถ React Native ํด๋ผ์ด์ธํธ์ ๋๋ค.
- FCM ๋ฐ APN ์์ ํตํฉ ํธ์ ์ถ์ํ๋ก expo-server-sdk๋ฅผ ์ฌ์ฉํ๋ NestJS ๋ฐฑ์๋.
- ์ง์ค์ ์์ฒ์ธ MongoDB โ NotificationMessage, NotificationToken, ๊ทธ๋ฆฌ๊ณ NotificationCounter ์ปฌ๋ ์ .
- ์ ํํ ์ค์ผ์ค๋ง๋ ์ ๋ฌ์ ์ํ ์นดํ ๊ณ ๋ฆฌ๋ณ(์์ฌ, ๊ธฐ๋ถ, ํ๋, ์์ , ์๋ฆผ) ActiveMQ (STOMP) ์ง์ฐ ํ.
- ์ฌ์ฉ์๋ณ ์๊ฐ๋๊ฐ ํด๊ฒฐ๋ ์๋ฆผ ๋ ์ฝ๋๋ฅผ ์์ฑํ๋ Creator crons.
- ๊ฐ ํ๋ฅผ ๊ตฌ๋ ํ๊ณ ์ ์ก ์ ์ ์ต์ข ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ์ํํ๋ Consumer workers.
- crons ๋ฐ consumers๋ฅผ ์คํํ๋ AWS ECS Fargate; ์ ์ฉ EC2 ์ธ์คํด์ค์์ ์คํ๋๋ ActiveMQ.
์ฃผ์ ๊ธฐ๋ฅ
- ์๊ฐ๋ ์ธ์ ์ค์ผ์ค๋ง. date-fns-tz๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ ์ฌ์ฉ์์ ํ์ง ๋ฐ์ก ์๊ฐ์ ๊ณ์ฐํ๊ณ , ์ ์ฅ์ฉ์ผ๋ก UTC๋ก ๋ค์ ๋ณํํ๋ฉฐ, ํ๋ฃจ์ ํ ๋ฒ์ ์๋ฆผ์ ๋ณด์ฅํ๊ธฐ ์ํด UTC ๋ ์ง ๋ฒ์๋ก ์ ํํฉ๋๋ค.
- ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ํ ๋ฉฑ๋ฑ์ฑ ๋ณด์ฅ. ๋ณด๋ฅ ์ค์ธ ๋ฉ์์ง์ ๋ํ ๋ถ๋ถ ๊ณ ์ ์ธ๋ฑ์ค๋ cron์ด ๋ ๋ฒ ์คํ๋ ๋๋ ์ค๋ณต ์์ฑ์ ๋ถ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค:
| // ๋ฉ์์ง๊ฐ PENDING ์ํ์ด๊ณ ์ญ์ ๋์ง ์์ ๊ฒฝ์ฐ์๋ง ๊ณ ์ ํฉ๋๋ค schema.index( { userId: 1, notificationTokenId: 1, category: 1, label: 1, scheduledAt: 1 }, { unique: true, partialFilterExpression: { status: 'pending', isDeleted: false } } ); |
3. ์ง์ฐ ํ๋ฅผ ํตํ ์ ํํ ์ ๋ฌ. ๋ถ ๋จ์ cron ๋์ ์ค์ผ์ค๋ฌ๋ ๋ฉ์์ง๋ฅผ ์ง๊ธ ๋๊ธฐ์ด์ ๋ฃ์ง๋ง, ActiveMQ์ scheduled-delay ํค๋๋ฅผ ์ฌ์ฉํ์ฌ ์ ํํ ์์ ์๊ฐ์ผ๋ก ์ ๋ฌ์ ์ฐ๊ธฐํฉ๋๋ค:
| client.send(`/queue/${queueName}`, { persistent: 'true', 'AMQ_SCHEDULED_DELAY': String(delayMs), // ์์ ๋ ์๊ฐ์ ์ ํํ ์ ๋ฌ๋ฉ๋๋ค }, JSON.stringify(message)); |
4. ๊ธฐ๊ธฐ๋น ๋จ์ผ ํ์ฑ ํ ํฐ. ๋ถ๋ถ ๊ณ ์ ์ธ๋ฑ์ค๋ ๊ธฐ๊ธฐ๋น ํ๋์ ํ์ฑ ํ ํฐ์ ์ ํํ ๋ณด์ฅํฉ๋๋ค. ์๋ก์ด ๋ก๊ทธ์ธ์ ์ด์ ํ ํฐ์ ๊น๋ํ๊ฒ ์ ๊ฑฐํ๋ฉฐ, ๋์ ๋ก๊ทธ์ธ์ ๋๋นํ์ฌ ์ง์ ๋ฐฑ์คํ ์ฌ์๋๋ฅผ ์ฌ์ฉํฉ๋๋ค.
5. ์์์ฆ ํ์ธ + ์๋ ์ ๋ฆฌ. ์ ์ก ํ Expo ์์์ฆ์ ํด๋งํฉ๋๋ค. DeviceNotRegistered ์๋ต์ ์ฆ์ ๋นํ์ฑ ํ ํฐ์ ๋นํ์ฑํํ์ฌ ๋ค์๋ ํด๋น ํ ํฐ์ ์ ์ก์ ๋ญ๋นํ์ง ์๋๋ก ํฉ๋๋ค.
| f (receipt.status === 'error' && receipt.details?.error === 'DeviceNotRegistered') { await this.deactivateToken(token); // ๋นํ์ฑ ๊ธฐ๊ธฐ๋ก์ ์ ์ก ์ค์ง } |
6. ์คํจ ํ๋. ๊ฐ ๊ธฐ๊ธฐ์๋ ์ฌ์๋ ์นด์ดํฐ๊ฐ ์์ต๋๋ค; 3ํ ์ฐ์ ์คํจ ํ ํ ํฐ์ ์๋์ผ๋ก ํ๊ธฐ๋ฉ๋๋ค โ ๋ฌดํ ๋ฃจํ๋ ์ข๋น ํ ํฐ์ด ์์ต๋๋ค.
7. ๋ฐ์ก ์ ์ฌ์ฉ์ ์๋ ์กด์ค. ์๋ฆผ ํ๊ฒฝ์ค์ ์ ์ค์ผ์ค๋ง ์์ ๋ฟ๋ง ์๋๋ผ ์ ๋ฌ ์์ ์๋ consumer์ ์ํด ๋ค์ ํ์ธ๋ฉ๋๋ค โ ๋ฐ๋ผ์ ์๋ฆผ 1์๊ฐ ์ ์ ์ตํธ์์ํ ์ฌ์ฉ์๋ ์ ๋ ์๋ฆผ์ ๋ฐ์ง ์์ต๋๋ค. ๋ฉ์์ง๋ ์ ์งํ ์ต์ข ์ํ๋ก ๊ฒฐ์ ๋ฉ๋๋ค: success, failed, ๋๋ is_missed.
๊ฒฐ๊ณผ
- ๋ชจ๋ ์ฌ์ฉ์๋ ์ ์ธ๊ณ ์ด๋์์๋ ์ ํํ ํ์ง ์๊ฐ์ ์๋ฆผ์ ๋ฐ์ต๋๋ค โ ๊ทผ๋ฌด ์ธ ์๊ฐ ์๋ฆผ์ ์์ต๋๋ค.
- ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ค ๋ฉฑ๋ฑ์ฑ์ ํตํด ์ค๋ณต ์๋ฆผ์ด ์์ ํ ์ ๊ฑฐ๋์์ต๋๋ค.
- ๋นํ์ฑ ๋ฐ ์ค๋๋ ๊ธฐ๊ธฐ ํ ํฐ์ด ์๋์ผ๋ก ๊ฐ์ง๋๊ณ ํ๊ธฐ๋์ด ๊น๋ํ ์ ๋ฌ์ ์ ์งํฉ๋๋ค.
- ๋ฌด์ฐจ๋ณ ์ค์ผ์ค๋ฌ ์์ด๋ ์ ํํ๊ณ ๋ถ ๋จ์๋ก ์ ๋ฐํ ์ ๋ฌ๋ก ์ ๋ขฐ์ฑ์ด ํฅ์๋๊ณ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ถํ๊ฐ ๊ฐ์ํ์ต๋๋ค.
๊ธฐ์ ์คํ
React Native ยท Expo Notifications ยท NestJS ยท TypeScript ยท MongoDB ยท ActiveMQ (STOMP) ยท expo-server-sdk ยท date-fns-tz ยท AWS ECS Fargate

