Skip to content

Commit 013216a

Browse files
committed
📝 docs: 가면사배 대규모 시스템 설계 기초 9-11장 추가
타이틀 - 9장: 웹 크롤러 설계(수정) - 10장: 알림 시스템 설계 - 11장: 뉴스 피드 시스템 설계
1 parent 9487652 commit 013216a

File tree

3 files changed

+450
-1
lines changed

3 files changed

+450
-1
lines changed

_posts/book/가상 면접 사례로 배우는 대규모 시스템 설계 기초/2025-09-30-9. 웹 크롤러 설계.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
title: "[Book - 가상 면접 사례로 배우는 대규모 시스템 설계 기초] 9. 웹 크롤러 설게"
33
date: 2025-09-29 23:30:00 +0900
44
categories: [Book - 가상 면접 사례로 배우는 대규모 시스템 설계 기초]
5-
tags: [book, System Design Interview, crawler, ]
5+
tags: [book, System Design Interview, crawler]
66
---
77

88
웹 크롤러는 검색 엔진에서 널리 쓰는 기술로, 웹에 새로 올라오거나 갱신된 콘텐츠를 찾아내는 것이 주된 목적이다.
Lines changed: 284 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,284 @@
1+
---
2+
title: "[Book - 가상 면접 사례로 배우는 대규모 시스템 설계 기초] 10. 알림 시스템 설계"
3+
date: 2025-10-13 23:30:00 +0900
4+
categories: [Book - 가상 면접 사례로 배우는 대규모 시스템 설계 기초]
5+
tags: [book, System Design Interview, message queue]
6+
---
7+
8+
알림 시스템은 단순 히 모바일 푸시 알림에 한정되지 않는다.
9+
알림 시스템은 모바일 푸시 알림, SMS 메시지, 이메일의 세 가지로 분류할 수 있다.
10+
11+
# 1단계. 문제 이해 및 설계 범위 확정
12+
13+
적절한 질문을 통해 요구 사항이 무엇인지 지원자 스스로 알아내야 한다.
14+
```
15+
질문1: 이 시스템은 어떤 종류의 알림을 지원해야 하나요?
16+
> 푸시 알림, SMS 메시지, 이메일
17+
18+
질문2: 실시간(real-time) 시스템이어야 하나요?
19+
> 연성 실시간(soft real-time) 시스템이라고 가정
20+
> 가능한 빨리, 부하 시 약간의 지연은 무방
21+
22+
질문3: 어떤 종류의 단말을 지원해야 하나요?
23+
> iOS, android, 랩톱/데스크톱
24+
25+
질문4: 사용자에게 보낼 알림은 누가 만들 수 있나요?
26+
> 클라이언트 애플리케이션 프로그램, 서버 측에서 스케줄링
27+
28+
질문5: 사용자가 알림을 받지 않도록(opt-out) 설정할 수도 있어야 하나요?
29+
> 네
30+
31+
질문6: 하루에 몇 건의 알림을 보낼 수 있어야 하나요?
32+
> 천만 건의 모바일 푸시 알림, 백만 건의 SMS 메시지, 5백만 건의 이메일
33+
```
34+
35+
# 2단계. 개략적 설계안 제시 및 동의 구하기
36+
37+
## 알림 유형별 지원 방안
38+
39+
### 1. iOS 푸시 알림
40+
iOS에서 푸시 알림을 보내기 위해서는 세 가지 컴포넌트가 필요하다.
41+
42+
```mermaid
43+
flowchart LR
44+
provider((알림 제공자))
45+
apns[[APNS]]
46+
ios["iOS 단말"]
47+
48+
provider --> apns --> ios
49+
```
50+
> APNS: 애플이 제공하는 원격 서비스
51+
52+
### 2. 안드로이드 푸시 알림
53+
```mermaid
54+
flowchart LR
55+
provider((알림 제공자))
56+
fcm[[FCM]]
57+
android["안드로이드 단말"]
58+
59+
provider --> fcm --> android
60+
```
61+
> FCM(Firebase Cloud Messaging)
62+
63+
### 3. SMS 메시지
64+
```mermaid
65+
flowchart LR
66+
provider((알림 제공자))
67+
service[[SMS 서비스]]
68+
sms["SMS 수신 단말"]
69+
70+
provider --> service --> sms
71+
```
72+
> 보통 상용 서비스로 Twilio, Nexmo 같은 제3사업자의 서비스를 많이 이용
73+
74+
### 4. 이메일
75+
```mermaid
76+
flowchart LR
77+
provider((알림 제공자))
78+
service[[이메일 서비스]]
79+
email["이메일 수신 단말"]
80+
81+
provider --> service --> email
82+
```
83+
> 보통 상용 서비스로 Sendgrid, Mailchimp를 사용
84+
85+
## 연락처 정보 수집 절차
86+
알림을 보내려면 모바일 단말 토큰, 전화번호, 이메일 주소 등의 정보가 필요하다.
87+
```mermaid
88+
flowchart LR
89+
user[사용자 단말]
90+
lb[로드밸런서]
91+
api[API 서버들]
92+
db[(DB)]
93+
94+
user -- 앱 설치 또는 계정 등록 --> lb
95+
lb --> api
96+
api -- 연락처 정보 저장 --> db
97+
```
98+
99+
## 알림 전송 및 수신 절차
100+
개략적 설계안부터 점진적으로 최적화해 보자.
101+
102+
### 개략적 설계안 (초안)
103+
* 1부터 N까지의 서비스
104+
* 마이크로서비스 or 크론잡 or 분산 시스템 컴포넌트
105+
* 예시
106+
* 사용자에게 납기일을 알리고자 하는 billing service
107+
* 배송 알림을 보내려는 쇼핑몰 서비스
108+
* 알림 시스템
109+
* 알림 전송/수신 처리의 핵심
110+
* 1개 서버만 사용하는 시스템 (가정)
111+
* 서비스 1~N에 알림 전송을 위한 API 제공 필요
112+
* 제3자 서비스에 전달한 알림 payload 필요
113+
* 제3자 서비스
114+
* 사용자에게 알림을 실제로 전달하는 역할
115+
* 확장성 유의
116+
* iOS, android, SMS
117+
* 사용자는 자기 단말에서 알림을 수신
118+
119+
```mermaid
120+
flowchart LR
121+
%% 서비스들
122+
subgraph Services[서비스들]
123+
s1[서비스 1]
124+
s2[서비스 2]
125+
s3["..."]
126+
sN[서비스 N]
127+
end
128+
129+
%% 알림 시스템
130+
notify[알림 시스템]
131+
132+
%% 제3자 제공 서비스
133+
subgraph ThirdParty[제3자 제공 서비스]
134+
apns[[APNS]]
135+
fcm[[FCM]]
136+
sms[[SMS 서비스]]
137+
email[[이메일 서비스]]
138+
end
139+
140+
%% 단말들
141+
ios[iOS 단말]
142+
android[Android 단말]
143+
sms_client[SMS 단말]
144+
email_client[이메일 수신 단말]
145+
146+
%% 서비스 -> 알림 시스템
147+
s1 --> notify
148+
s2 --> notify
149+
s3 --> notify
150+
sN --> notify
151+
152+
%% 알림 시스템 -> 제3자 서비스
153+
notify --> apns
154+
notify --> fcm
155+
notify --> sms
156+
notify --> email
157+
158+
%% 제3자 서비스 -> 각 단말
159+
apns --> ios
160+
fcm --> android
161+
sms --> sms_client
162+
email --> email_client
163+
```
164+
165+
이 설계에는 아래와 같은 문제가 있다.
166+
* SPOF(Single Point of Failure)
167+
* 알림 서비스에 서버가 하나밖에 없어서 장애가 생기면 전체 서비스의 장애로 이어진다.
168+
* 규모 확장성
169+
* 한 대 서비스로 푸시 알림에 관계된 모든 것을 처리하므로,
170+
* DB나 cache 등 중요 컴포넌트의 규모를 개별적으로 늘릴 방법이 없다.
171+
* 성능 병목
172+
* 사용자 트래픽이 많이 몰리는 시간에는 시스템이 과부하 상태에 빠질 수 있다.
173+
174+
### 개략적 설계안 (개선된 버전)
175+
아래와 같은 방향으로 개선해 보자.
176+
* DB와 cache를 알림 시스템의 주 서버에서 분리
177+
* 알림 서버를 증설하고 자동으로 수평적 규모 확장 보장
178+
* 메시지 큐를 이용해 시스템 컴포넌트 사이의 강한 결합 제거
179+
> 알림 서버는 아래와 같은 기능을 제공한다.
180+
>
181+
> * 알림 전송 API
182+
> * 알림 검증
183+
> * 데이터베이스 또는 캐시 질의
184+
> * 알림 전송
185+
186+
![알림 시스템 개선](https://drive.google.com/thumbnail?id=1jY5N0pw9UhFL4PvoA3INPYCXf_YKLK3r&sz=w700)
187+
188+
1. API를 호출하여 알림 서버로 알림을 보낸다.
189+
2. 알림 섬버는 사용자 정보, 단말 토큰, 알림 설정 같은 메타데이터를 캐시나 데이터베이스에서 가져온다.
190+
3. 알림 서버는 전송할 알림에 맞는 이벤트를 만들어서 해당 이벤트를 위한 큐에 넣는다.
191+
4. 작업 서버는 메시지 큐에서 알림 이벤트를 꺼낸다.
192+
5. 작업 서버는 알림을 제3자 서비스로 보낸다.
193+
6. 제3자 서비스는 사용자 단말로 알림을 전송한다.
194+
195+
# 3단계. 상세 설계
196+
애래 내용을 좀 더 자세히 알아보자.
197+
* 안정성(reliability)
198+
* 추가로 필요한 컴포넌트 및 고려사항
199+
* 알림 템플릿
200+
* 알림 설정
201+
* 전송률 제한
202+
* 재시도 메커니즘
203+
* 보안
204+
* 큐에 보관된 알림에 대한 모니터링과 이벤트 추적
205+
* 개선된 설계안
206+
207+
## 안정성
208+
**분산 환경**에서 운영될 알림 시스템을 설계할 때는 안정성을 확보하기 위한 사항 몇 가지를 반드시 고려해야 한다.
209+
210+
### 데이터 손실 방지
211+
데이터 손실 방지 요구사항을 만족하려면 알림 데이터를 DB에 보관하고 재시도 매커니즘을 구현해야 한다.
212+
```mermaid
213+
flowchart LR
214+
%% 노드 정의
215+
iosQ["iOS 푸시 알림 큐"]
216+
worker["작업 서버"]
217+
apns["APNS"]
218+
logDB[("알림 로그 데이터베이스")]
219+
220+
%% 흐름
221+
iosQ --> worker --> apns
222+
worker --> logDB
223+
224+
%% 스타일
225+
classDef dashed stroke-dasharray: 5 5, stroke:#999;
226+
class worker dashed;
227+
class logDB dashed;
228+
```
229+
230+
### 알림 중복 전송 방지
231+
같은 알림이 여러 번 반복되는 것을 완전히 막는 것은 가능하지 않지만, 그 빈도를 줄이기 위해 중복을 탐지하는 메커니즘을 도입한다.
232+
* 보내야 할 알림이 도착하면 그 이벤트 ID를 검사하여 이전에 본 적이 있는 이벤트인지 상핀다.
233+
* 중복된 이벤트라면 버리고, 아니면 알림을 발송한다.
234+
235+
## 추가로 필요한 컴포넌트 및 고려사항
236+
### 알림 템플릿
237+
```
238+
지금 [item_name]을 주문 또는 예약하세요!
239+
```
240+
241+
### 알림 설정
242+
사용자가 알림 설정을 상세히 조정할 수 있도록 알림 설정 테이블 사용
243+
244+
### 전송률 제한
245+
한 사용자가 받을 수 있는 알림의 빈도를 제한
246+
247+
### 재시도 방법
248+
제3자 서비스가 알림 전송에 실패하면, 해당 알림을 재시도 전용 큐에 넣는다.
249+
250+
같은 문제가 계속해서 발생하면 개발자에게 통지한다.
251+
252+
### 푸시 알림과 보안
253+
App의 경우, 알림 전송 API는 appKey와 appSecret을 사용하여 보안을 유지한다.
254+
255+
### 큐 모니터링
256+
큐에 쌓인 알림의 metric 수가 너무 크면 작업 서버들이 이벤트를 빠르게 처리하고 있지 못하다는 뜻이므로, 작업 서버를 증설하는 게 바람직할 것이다.
257+
258+
### 이벤트 추적
259+
알림 확인율, 클릭율, 실제 앱 사용으로 이어지는 비율 같은 메트릭은 사용자를 이해하는데 중요하다.
260+
261+
보통 알림 시스템을 만들면 데이터 분석 서비스와도 통합해야만 한다.
262+
263+
![이벤트 추적](https://drive.google.com/thumbnail?id=1stLWoOB6Umx8qpL042Jkf2EVDElY1nbH&sz=w600)
264+
265+
## 수정된 설계안
266+
![이벤트 추적](https://drive.google.com/thumbnail?id=1-e8GUrOFwCZPmalZwd3PoDW-9OiQ45s_&sz=w700)
267+
268+
# 4단계. 마무리
269+
알림은 중요 정보를 계속 알려준다는 점에서 필요불가결한 기능이다.
270+
271+
시스템 컴포넌트 사이의 결합도를 낮추기 위해 메시지 큐를 적극적으로 사용하였다.
272+
273+
각 컴포넌트의 구현 방법과 최적화 기법에 대해서 아래 주제에 집중하였다.
274+
* 안정성(reliability)
275+
* 메시지 전송 실패율을 낮추기 위해 안정적인 재시도 메커니즘 도입
276+
* 보안(security)
277+
* 인증된 클라이언트만이 알림을 보낼 수 있도록 appKey, appSecret 등의 메커니즘 이용
278+
* 이벤트 추적 및 모니터링
279+
* 알림이 만들어진 후 성공적으로 전송되기까지의 과정을 추적하고 시스템 상태를 모니터링하기 위해
280+
* 알림 전송의 각 단계마다 이벤트를 추적하고 모니터링할 수 있는 시스템을 통합
281+
* 사용자 설정
282+
* 사용자가 알림 수신 설정을 조정할 수 있도록 설계
283+
* 전송률 제한
284+
* 사용장에게 알림을 보내는 빈도를 제한

0 commit comments

Comments
 (0)