경력·사례·글은 한국어 원문으로 제공됩니다.

← 모든 에피소드

회사 초기 · 회사 업무 · 관리형 추상화의 대가

푸시 직후 접속 폭주와 직접 만든 인증

알림 뒤 몰린 접속은 발송과 재시도를 나눠 대응했다. 이후 인증을 직접 만든 데에는 서비스마다 다른 회원 요구도 있었다.

그때
알림 직후 접속과 토큰 재발급이 몰렸고, 의도한 재시도가 부하를 더했다.
지금
다시 인증을 설계한다면 요청의 도착 방식과 회원 정책, 유지·복구 책임을 따로 살펴보고 싶다.

알림을 보고 들어온 사용자들

정해진 시각에 알림이 나가면 사용자들이 동시에 앱을 열었다. 그때 접근 토큰이 만료됐거나 다시 발급받아야 하는 요청도 한꺼번에 들어왔다. 접근 토큰은 앱이 서버에 요청할 때 인증받은 사용자임을 나타내기 위해 보내는 값이다. 인증은 관리형 서비스에 맡겨 두었고, 그 서비스에는 요청 한도가 있었다.

로그인이 풀린 것은 아니었다. 앱은 요청이 실패하면 다시 보내도록 만들어져 있었다. 의도한 동작이었지만, 몰린 요청 위에 재시도가 더해졌다. 서버 함수의 동시 실행과 데이터베이스 모두 부담을 받았고, 사용자 화면에서는 로딩이 계속 돌았다.

먼저 알림을 나눠 보냈다. 사용자 ID를 기준으로 구간을 나누고 순서대로 발송했다. 앱에서도 재시도 횟수를 제한하고, 다음 요청까지 기다리는 시간을 점점 늘렸다. 그 간격에는 무작위 요소를 섞었다. 한꺼번에 들어오는 첫 요청과, 실패 뒤 다시 들어오는 요청을 각각 나눠야 했다.

바꾼 뒤에는 접속이 극단적으로 몰리지 않고 서서히 늘어 감당할 수 있는 수준으로 지나갔다. 단순한 로딩 화면도 애니메이션이 있는 화면으로 바꿨다. 기다리는 동안 앱이 멈춘 것처럼 보이지 않게 하려는 조치였다. 화면 연출로 서버가 더 빨라진 것은 아니다.

같은 만큼 기다리면 다시 만날 수 있다

재시도는 잠깐의 실패를 넘기는 데 도움이 된다. 다만 실패한 요청마다 바로 새 요청을 보내면, 처리할 여유가 없는 서버에 일을 더 얹을 수도 있다. 다음 시도까지 기다리는 시간을 두는 것이 백오프(backoff)다. 실패가 이어질수록 간격을 늘리면 계속 같은 빈도로 요청하는 일을 줄일 수 있다. 재시도와 백오프 설명

기다리는 시간을 늘리는 것만으로는 부족할 때가 있다. 여러 앱이 동시에 실패하고 똑같은 시간을 기다린다고 생각해보자. 처음 요청은 흩어 놓았어도 재시도 시점에 다시 몰릴 수 있다. 기다리는 시간을 조금씩 다르게 고르게 하는 방법이 지터(jitter)다. 같은 실패를 겪은 앱들이 다음 요청까지 같은 박자로 움직이지 않게 하는 것이다. 백오프와 지터 설명

지터가 모든 요청을 고르게 배치해 주는 것도 아니다. 간격과 횟수를 정해도 들어오는 양이 처리 능력보다 크면 실패할 수 있고, 간격을 길게 잡으면 사용자는 더 오래 기다린다. 무엇을 다시 시도할지와 어디서 멈출지를 함께 정해야 한다.

당시 요청 한도는 상향을 요청해 늘렸다. 한도가 있어서 아무것도 할 수 없었던 상황은 아니었다. 한도를 늘리는 일은 허용되는 양을 바꾸고, 발송과 재시도를 나누는 일은 요청이 도착하는 시점을 바꾼다. 그때는 두 가지를 모두 다뤄야 했다.

인증을 직접 만든 이유는 더 있었다

인증을 직접 만드는 방향으로 간 데에는 다른 사정도 있었다. 서비스 초기에 사용자가 빠르게 늘었고, 서비스들을 연결하거나 소셜 로그인을 지원하면서 회원을 다루는 요구도 달라졌다. 같은 계정 체계 안에서 역할에 따라 다른 회원으로 쓰거나, 사업자용과 고객용을 나누거나, 한 계정을 여러 사람이 동시에 쓰게 해야 하는 경우가 있었다.

이후 서비스부터는 OIDC를 기반으로 인증을 직접 만들었다. 관리형 서비스에서 쓰던 기능 대부분을 구현했고, 역할별 회원 구분과 사업자·고객 계정 같은 요구를 우리 방식에 맞게 다룰 수 있게 됐다. 시간이 지나면서 여러 서비스의 인증을 한곳으로 모으는 통합 인증으로도 이어졌다. 알림이 몰리던 날 자체 인증까지 한 번에 바꾼 것은 아니다.

OIDC(OpenID Connect)는 인증 서버가 확인한 사용자 정보를 다른 앱이나 서비스가 정해진 방식으로 전달받고 확인하도록 하는 표준이다. OIDC 공식 명세

그 표준을 따른다고 회원 정책까지 저절로 정해지지는 않는다. 예를 들어 같은 사람인지 확인하는 일과, 그 사람이 사업자 서비스에서 어떤 회원으로 활동할지를 정하는 일은 다르다. 인증을 주고받는 약속은 공통으로 두더라도 서비스별 역할과 계정의 관계는 따로 설계해야 한다. 당시 관리형 인증에 맞추기 어려웠던 요구도 이 부분과 닿아 있었다.

다시 만든다면 어디까지 맡길까

직접 만들면 요구에 맞춰 바꿀 여지는 생긴다. 대신 발급한 인증 정보를 어떻게 검증하고, 문제가 생겼을 때 어떻게 갱신하거나 끊을지도 계속 책임져야 한다. OIDC에 기반했다는 설명만으로 구현이 모두 안전하다고 말할 수는 없다. 다시 선택한다면 필요한 회원 정책뿐 아니라 그 기능을 유지하고 복구할 일까지 함께 따져보고 싶다.

인증 서버를 서비스 서버와 별도로 두는 구조도 먼저 살펴볼 것이다. 큐나 실시간 연결을 활용하는 방법도 떠올렸지만, 어디에 쓸지는 더 구체적으로 나눠 봐야 한다. 요청을 나중에 처리해도 되는 일인지, 사용자가 지금 인증 결과를 받아야 하는 일인지에 따라 답이 달라질 것이다.

요청이 덜 몰리게 바꾼 뒤에도 역할과 계정 관계에 대한 요구는 남았다. 직접 인증을 만든 이유를 돌아보면, 더 많은 요청을 받는 것만큼 서로 다른 서비스의 회원을 어떻게 연결할지도 중요했다. 요청이 들어오는 속도를 조절하는 일과 그 계정을 어떤 회원으로 받아들일지 정하는 일은 따로 살펴야 했다.

다시 만난 문제

이 글의 연결

앱의 재시도가 서버를 두드린 일앱의 재시도가 서버를 두…같은 토큰으로 다른 서비스에 들어가면 403이 나와야 한다같은 토큰으로 다른 서비…

댓글

댓글은 GitHub 토론을 사용하며, 열면 GitHub 로그인이 필요합니다. 고객·사람이 드러나는 정보는 남기지 말아 주세요.

작성 2026-10-05 · 수정 2026-10-06

기억에 의존한 회고이며 당시 문서로 확인하지 못했다.