👉🏻 제 1회 인프콘 - 인프런 아키텍쳐 2022~2023 보러가기 (클릭)
👉🏻 제 2회 인프콘 - 인프런 아키텍쳐 2023~2024 보러가기 (클릭)
저번 인프런 아키텍처에서도 발표했지만, MSA 까지는 아니더라도 복제된 분산환경으로 전환을 했다.
그리고 그것을 바탕으로 점진적인 개선을 진행했다.
인프런은 레거시들을 점차적으로 줄여가는 것을 목표로 했었는데,
현실적으로 개편하지 못한 부분도 있었다.
즉, 기술 스택 전환 진행이 이루어진 조직과 이루어지지 않은 조직이 공존하게 되었는데,
이것에 가장 큰 영향을 끼친 이유는 바로바로
인프런의 글로벌 진출 !! 🌎
인프런의 프로덕트 조직 전체가 합심하여 국제화 를 진행하는 것이 목표가 되었다. (축하합니다 인프런!!)
즉, 학습외 서비스들은 국제화 이후 후순위로 미루게 되었다고 한다.
회사의 방향이 글로벌 진출인 만큼, 이것을 대응하기 위해서는 몇가지 작업이 필요했다고 한다.
개인적으로 인프런의 글로벌 진출을 너무 축하하는 마음이었고, 👏🏻
국제화 작업을 진행하면서 겪을 많은 문제들과 또 그것을 개선해 나간 내년 후기도 벌써 기대가 되었다.
인프런이 글로벌로 가기 전에 다져야 할 것은 바로 '트래픽 비용 개선' 이었다.
글로벌 서비스로 간다면 트래픽은 더욱 많아지게 된다.
수입이 없는 무상 트래픽이 글로벌하게 발생하게 된다면 회사에 큰 손실이 된다.
게다가 계속 치솟는 환율로 인해 서버비용은 더욱 아껴야만 했다.💰
👉🏻 '국제화 오픈 전에 비효율적인 트래픽 비용을 개선하자' 가 목표가 되었다.
AS IS
- 화면에 필요한 만큼의 이미지 크기만 전송 한다.
Cloud Front
을 통한 캐싱은 나쁘지 않은 방법이다.
하지만...
png
, jpeg
의 확장자 파일은 꽤나 큰 용량을 차지한다.
특히나 인프런과 같은 강의가 나열되어있는 페이지에 있는 썸네일들은 많은 트래픽을 발생 시킨다.
1페이지에 약 3mb 정도의 트래픽이 발생했다고 한다.
이 말은, 사람들이 인프런의 페이지를 돌아다니게 될 수록 무상 트래픽 비용이 계속 증가가 된다는 것을 의미한다.
들어는 보았나 AVIF
고품질 !! 고효율 !! 저용량 !!! AVIF 만세!!
jpeg
에 비해 최대 50% 의 용량이 개선이 된다고 한다.TO BE
query param
으로avif
형태로 이미지를 가져오고,lambda edge
를 통해 파일을 변환한다.
RESULT
- 이미지 포맷만 바꿨는데? -> 약 62 퍼센트의 트래픽 개선을 했다. 💡
- 정말 간단한 변화지만, 엄청난 퍼포먼스를 가져온 방법이었다.
인프런은 위와같은 카테고리를 가지고 있다.
저런 형태의 카테고리는 json
데이터로 뿌리게 되는데, 이것이 페이지를 조회할 때마다 api 를 통해 조회를 하게 된다면 어떨까?
사실, 그렇게 크지 않은 데이터여도 요청수가 많고 많이 찌르게 된다면 큰 데이터가 되버린다.
인프런이 카테고리에만 호출되는 Json 데이터의 크기는 하루에 150GB 정도였다고 한다. 👀
ㅎㄷㄷ....
인프런..트래픽..엄청나네...?
- DB 에 있는 카테고리를 일일이 찌르게 되면 DB 에 수많은 요청이 오게되고, 그것으로 DB에 부하가 생긴다.
방법 1) 외부 Cache 를 사용하자!
- 이것을 외부 Cache 로 개선해보자!
- ElastiCache 를 통해 DB 부하를 감소시키고, 좀 더 빠른 Cache 서버를 사용해서 개선해 봤다.
하지만.... 외부 Cache 의 높은 트래픽이 발생하게 되었다.
방법 2) 로컬 캐시를 사용하자!
- 그래서 로컬 캐시를 저정하도록 변경했다.
- 즉, 외부 캐시가 아니라 로컬 캐시로 계층을 변경하고, 로컬캐시를 통한 어플리케이션만으로 트래픽을 처리하게 했다.
- 이를 통해 DB 부하도 줄이고, 외부 Cache 서버를 클러스터링을 할 필요도 없었다.
어? 잠깐만..?
API 데이터도 어차피 Json 데이터를 내려보내는 거잖아? 💡
Json 데이터도 어차피 파일이야. 별다른 특별한게 아니야. image, js, css 처럼 정적으로 관리할 수 있지 않을까?
정적 데이터를 캐싱할 때 우리는 주로 뭘 사용하지?
정답 : CDN
이 장표를 보는데 무릎을 진짜 탁! 쳤다.
그래, 무조건 API 로 응답했었던 Json 데이터를 항상 API 를 통해서만 보낼 필요는 없지.
카테고리처럼 변경이 잦지 않고, 변경의 권한이 회사에게 있는 데이터는 정적인 데이터라고 생각해도 되겠구나!
- CDN 은 cache-control 에 따라 쿠키도 캐시할 수 있다.
- 즉, session 까지 긁어서 가기 때문에, 비지니스 드리븐한 API 를 CDN 캐시한다면 유의해야한다.
두가지 방법으로 매우 큰 비용을 조절함
브라우저에서의 모든 요청은 Next.js 가 API Proxy 로 동작하도록 변경했다.
Next.js 의 Rewrite
옵션을 통해 API 호출을 바이패스한다.
즉, API Proxy 서버로서 사용하도록 했다.
우선 API 를 external
과 internal
을 분리했다.
그리고, 외부에서 들어오는 API 인 external
만 세션체크를 하도록 정책을 마련했다.
내부 API 는 세션체크를 하지 않도록 했는데, 중요한 API 가 외부에서 호출되는 상황이 되어버렸다.
이것을 해결하기 위해 우선 두가지 방법을 고안했다.
해결 방안
1. 외부용, 내부용 프로젝트 코드를 분리 하도록 한다.
- 큰 단점 : 모든 백엔드 인프라가 2배로 늘어난다.
- 즉, 모든 환경을 쌍으로 개발해야하기 때문에 인프라 비용이 2배로 늘어나게 된다.
- 내, 외부 모두 세션 체크를 한다.
- 큰 단점 : 모든 API 를 모두 세션체크할 수 없다.
- 인츠라 부하, 코드 복잡도가 가중된다. 내부 호출을 포함한 모든 API 가 세션 쿠키를 가지는 것은 너무 부하가 크다.
API Path 를 1단계 더 추가한다.
즉, 클라이언터 단에서 호출하는 모든 API 에는 /client
를 붙이도록 설계를 변경했다.
즉, /client
가 븥어있으면 세션체크, 아니면 내부라고 인지하고 세션체크 하지 않도록 변경했다.
이로 인해서 Next.js Proxy 호출시에도 내부망 통신이 가능하게 되었다.
이것은, 관심사를 분리한 것으로도 생각할 수 있다.
백엔드단에서는 그냥 /client
가 붙어있으면 어느환경이든 상관없이 세션을 확인한다.
즉, 백엔드 단에서는 호출하는 곳이 어디인지 알 필요가 없다.
들어오는 API path 에 따라서 세션 확인 유무만 판단 하면 되기 때문이다.
반대로 클라이언트단에서는 /client
의 유무를 통해 백엔드로 호출이 가능하게 되었다.
이번 세션을 통해 느낀것은, "개발자의 최고 덕목은 역시 '주어진 문제를 어떻게든 해결하는 것' 이구나" 였다.
글로벌 서비스를 앞두고 인프런 서비스에서 현재 해결해야할 문제가 무엇인지 진단하고, 현재 환경에서 최선의 방법을 찾아낸 인프랩 개발팀에 박수를 보낸다.
개인적으로, API 응답 Json 을 CDN 을 통해 캐싱을 하는 아이디어를 생각하고 그것으로 많은 개선을 이루어 낸 것이 참 인상 깊었다.