Foundry
알림 시스템 설계
심화
핵심

제공자가 경계다

마지막 단계가 우리 통제 밖이다

알림 시스템의 특이한 점은 마지막 단계가 우리 것이 아니라는 것입니다. 푸시는 운영체제 제공자를, 문자는 통신사 쪽을, 메일은 메일 발송 서비스를 거칩니다.

통제가 끝나는 지점

알림 시스템의 마지막 단계는 우리가 통제하지 못하는 제3자 제공자다 우리가 통제하는 구간 서비스 알림 플랫폼 여기서부터는 통제 밖 제공자 사용자 제공자가 느려지거나 우리 요청을 제한할 수 있다 채널마다 제공자가 다르고 규칙도 다르다 그래서 채널마다 다른 것을 한 겹으로 감싼다 우리 코드는 알림을 보내고, 그 겹이 제공자 차이를 흡수한다 제공자를 바꿀 때 우리 코드가 바뀌지 않아야 한다

우리가 할 수 있는 것은 제공자에게 넘기는 것까지입니다. 그 뒤는 볼 수 없고 바꿀 수 없습니다.

우리 통제 안통제 밖
무엇을 언제 보낼지실제로 도착하는지
재시도 정책제공자의 속도 제한
채널 선택제공자 장애

이 경계를 인정하는 것이 설계의 출발점입니다. 도착을 보장하려 하지 말고, 넘기는 것까지를 확실하게 만들고 그 뒤는 관찰합니다.

채널마다 다른 것을 한 겹으로 감싼다

제공자마다 요청 형식과 인증 방식과 오류 코드가 다릅니다. 그것이 우리 코드 전체에 퍼지면 제공자를 바꿀 때 모든 곳을 고쳐야 합니다.

우리 코드는 "이 사람에게 이 알림을 보낸다" 만 말한다
겹 하나가 제공자 차이를 흡수한다

제공자를 바꿀 때 우리 코드가 바뀌지 않아야 합니다. 문자 제공자는 실제로 바뀝니다. 가격과 도달률 때문에 옮기는 일이 흔합니다.

제공자가 우리를 제한한다

제공자에게도 속도 제한이 있습니다. 피크 초당 1만 을 그대로 밀면 거절당합니다.

대응내용
제공자별 발송 속도에 상한을 둔다거절을 미리 피한다
거절을 받으면 속도를 줄인다상대의 신호에 반응한다
큐에 쌓아 두고 나눠 보낸다폭주를 흡수한다

처리율 제한 설계에서 우리가 만든 장치를 이번에는 우리가 지키는 쪽입니다. 상대가 알려 주는 재시도 시각을 따르고, 지키지 않으면 차단됩니다.

한 채널의 장애가 다른 채널을 막지 않게

문자 제공자가 느려지면 그 발송이 쌓입니다. 같은 일꾼과 같은 큐를 쓰면 푸시 알림도 함께 멈춥니다.

그래서 채널마다 큐와 일꾼을 나눕니다. 크롤러에서 호스트별로 큐를 나눈 것과 같은 구조이고, 이유도 같습니다. 한 곳의 느림이 다른 곳으로 번지지 않게 하는 것입니다.

제공자의 응답을 어떻게 읽나

제공자가 200을 주면 "받았다" 입니다. "도착했다" 가 아닙니다. 이 구분을 흐리면 도달률 지표가 실제와 크게 달라집니다.

응답
수락제공자가 우리 요청을 받았다
거절형식 오류나 속도 제한. 우리가 고칠 수 있다
나중에 오는 보고실제 도착 여부. 채널마다 신뢰도가 다르다

세 가지를 구분해 기록해야 무엇이 잘못됐는지 알 수 있습니다. 도달 추적은 뒤에서 따로 다룹니다.

면접에서 이렇게 나옵니다

Q.알림 시스템에서 제공자 경계가 왜 중요한가요

마지막 단계가 우리 것이 아니기 때문입니다.

우리 통제 안통제 밖
무엇을 언제 보낼지실제로 도착하는지
재시도 정책제공자의 속도 제한
채널 선택제공자 장애

이 경계를 인정하는 것이 설계의 출발점입니다. 도착을 보장하려 하지 말고, 넘기는 것까지를 확실하게 만들고 그 뒤는 관찰합니다.

흔한 실수: 도달을 우리 책임으로 설계하는 것. 도달률을 목표로 잡으면 우리가 통제하지 못하는 값에 책임을 지는 셈입니다. 우리 목표는 "제공자에게 정확히 한 번 넘긴다" 이고, 도달률은 관찰하고 개선하는 값입니다.

Q.채널별 제공자 차이를 어떻게 다루시겠습니까

한 겹으로 감싸 그 차이를 흡수합니다.

제공자마다 요청 형식과 인증 방식과 오류 코드가 다릅니다. 그것이 코드 전체에 퍼지면 제공자를 바꿀 때 모든 곳을 고쳐야 합니다.

우리 코드는 이 사람에게 이 알림을 보낸다만 말한다
겹 하나가 제공자 차이를 흡수한다

제공자는 실제로 바뀝니다. 문자는 가격과 도달률 때문에 옮기는 일이 흔합니다.

흔한 실수: 추상화를 최소 공통 기능으로만 만드는 것. 채널마다 고유한 것이 있습니다. 푸시의 배지 수, 메일의 첨부가 그렇습니다. 공통 부분만 남기면 그 기능을 못 쓰게 되므로, 채널 고유 항목을 담을 자리를 함께 둡니다.

Q.제공자가 우리 요청을 제한하면 어떻게 하나요

제공자별 발송 속도에 상한을 두고, 거절을 받으면 줄입니다.

피크 초당 1만 을 그대로 밀면 거절당합니다.

대응내용
발송 속도 상한거절을 미리 피한다
거절 시 속도 감소상대의 신호에 반응한다
큐에 쌓아 나눠 보내기폭주를 흡수한다

처리율 제한 설계에서 우리가 만든 장치를 이번에는 우리가 지키는 쪽입니다. 상대가 알려 주는 재시도 시각을 따르고, 지키지 않으면 차단됩니다.

흔한 실수: 거절을 일반 오류로 보고 곧바로 재시도하는 것. 속도 제한 거절에 재시도를 붙이면 더 강하게 제한됩니다. 거절의 종류를 읽고 대응을 달리해야 합니다.

Q.한 채널의 장애가 다른 채널에 번지지 않게 하려면

채널마다 큐와 일꾼을 나눕니다.

문자 제공자가 느려지면 그 발송이 쌓입니다. 같은 일꾼과 같은 큐를 쓰면 푸시 알림도 함께 멈춥니다.

크롤러에서 호스트별로 큐를 나눈 것과 같은 구조이고 이유도 같습니다. 한 곳의 느림이 다른 곳으로 번지지 않게 하는 것입니다.

채널마다 큐와 일꾼을 따로 둔다
한 채널이 막혀도 나머지는 흐른다

흔한 실수: 일꾼 수만 늘려 대응하려는 것. 같은 큐를 보는 일꾼을 늘리면 느린 채널의 일이 늘어난 일꾼까지 잡아먹습니다. 나누는 것과 늘리는 것은 다른 처방입니다.

먼저 스스로 답해보고 아래 답변과 견줘보세요. 막히는 부분은 문제로 확인할 수 있어요.

읽었으면 문제로 확인해보세요

알림 시스템 설계 문제를 풀면 틀린 문제가 자동으로 노트에 쌓입니다. 가입 없이 5문제를 먼저 풀어볼 수도 있어요.