5월 4일 저녁 6시 30분, PO한테 다급한 멘션이 왔다.
5월 4일 저녁 6시 30분, PO한테 다급한 멘션이 왔다. "공유 성공률이 바닥을 치는데, 문제 있는 거 아닌가요?" 토스 어른이날 이벤트 첫날이었다. 실제로 공유가 우수수 실패하고 있었다. 이 이벤트의 핵심이 공유인데. 내가 짠 에러 핸들링 로직이 문제였다....
5월 4일 저녁 6시 30분, PO한테 다급한 멘션이 왔다. “공유 성공률이 바닥을 치는데, 문제 있는 거 아닌가요?”
토스 어른이날 이벤트 첫날이었다.
실제로 공유가 우수수 실패하고 있었다. 이 이벤트의 핵심이 공유인데.
내가 짠 에러 핸들링 로직이 문제였다. 프론트엔드에서 서버를 체크하고, 부하가 걸려있으면 유저한테 “접속자가 많아 서비스를 이용할 수 없어요”를 띄운다. 그 밑에 ‘다시 시도하기’ 버튼을 달아놨다.
선물을 받으려고 공유를 눌렀는데 안 된다는 알림이 뜨면 사람들은 어떻게 할까.
당연히 즉각 다시 시도하기를 누른다.
에러 알림이 뜬다. 수천 명이 동시에 누른다. 서버가 더 막힌다. 더 많은 사람이 에러를 본다. 또 동시에 누른다. 서버가 회복할 틈이 없다.
나중에 알았지만 ‘재시도 폭풍(retry storm)‘이라는 소프트웨어 엔지니어링의 고전적인 문제였다.
PO가 “참여자는 X%밖에 안 늘었는데, 왜 에러율만 치솟아요?”라고 한 게 정확히 이 현상이었다. 나는 미처 생각을 못 했던 거다.
코드를 바꿨다. 유저 대신, 코드가 직접 재시도하게 했다. 대신 재시도 간격에 랜덤을 집어넣었다. 어떤 요청은 0.4초 뒤, 어떤 요청은 0.7초 뒤에. 이 랜덤을 지터(jitter)라고 부른다.
AWS는 아예 SDK에 jitter를 기본값으로 넣는다고 한다. 일반 재시도보다 에러율이 훨씬 낮아지기 때문에.
어른이날 이벤트 둘째날은 첫날보다 훨씬 많은 사람들이 참여했는데, 에러율이 크게 올라가지 않았다.
간단한 랜덤 노이즈 하나가 이렇게 다르다니… 온몸으로 배운 거라 오래 기억할 것 같다.