잘못된 코드로 인하여 AWS 폭탄 맞은 이야기

2023. 3. 17. 16:44iOS/이슈

깊은 고민 없이 사용한 잘못된 코드(라이브러리)로 비용이 많이 청구된 이야기를 공유해보려고 한다.

결론 부터 말하자면, 비디오의 캐시 다운로드로 인하여 아직 개발 중이어서 사용자가 적은데도 불구하고 AWS 비용이 30만원이 청구되었다.

개발 히스토리

비디오 피드 리스트가 있는 화면을 만들게 되었다. 처음엔 트위터의 비디오 피드 같이 심플한 디자인이어서 AVKit만으로 충분했다.
하지만 점점 유튜브 비디오 UI처럼 요구 사항이 늘어나게 되어, AVPlayer Layer를 사용한 커스텀이 필요하게 되었다. ControlUI도 필요하고, 비디오 캐시 처리를 하면 데이터를 아낄 수 있을 것 같아 Custom 확장성과 비디오 캐시를 지원하는 GSPlayer 라이브러리를 사용했다. 이 당시에는 AVAsset의 이해도가 낮아, thumbnail과 duration을 띄우려고 리스트의 비디오를 play()했다가 pause()하였다.

문제는 여기에 있었다. GSPlayer는 resourceLoaderDelegate를 구현하여 비디오 캐싱을 하였는데 한 번 resource request를 받으면 재생 버퍼와는 별도로 비디오 끝까지 다운하게 구현되어 있었다. 따라서 비디오를 끝까지 보지 않아도 play() 만으로 비디오 파일 전체를 요청하게 된 것이었다. 테스트할 때 필요에 따라 삭제하고 다시 설치하는 경우가 빈번해 스토리지 캐시가 날라가고 다시 다운받는 횟수 * 테스트 폰 개수만큼 증가하여 요금이 청구되게 되었다.

개선 사항

thumbnail 이미지를 유저가 따로 올릴 수 있는 요구 사항이 생겨서 업로드 시 썸네일 이미지를 분리하게 되었다. 또한 duration도 AVAsset을 이용하여 async load()하였다. 

현재는 GSPlayer를 포크하여 custom delegate 부분을 정지시켜 놓았다. 사용자의 필요에 따라 local download하게 바꿀 예정이다.

비디오 리스트 화면

Custom Resource Loader관련

Naver Deview에 좋은 발표가 있어서 첨부한다. 우리는 HLS를 사용한 스트리밍을 하지는 않지만 Resource Loader를 구현하는데 도움이 될 거 같다.

NAVER Deview PDF 링크