글로벌 서비스를 위한 멀티 리전 프록시 도입기

beNX의 서비스 중 위버스는 팬과 아티스트의 소통을 돕는 커뮤니케이션 플랫폼 입니다. 팬들은 아티스트들에게, 아티스트들은 팬들에게 서로 글을 쓰고 댓글을 달 수 있는 양방향의 커뮤니케이션이 가능한 플랫폼 입니다.

위버스의 아티스트 글 탭

시간과 공간의 제약이 없어진 만큼 위버스에서는 다양한 국가에서 많은 팬들이 글을 작성하고 아티스트의 글을 보는 등 많은 활동을 하고 있습니다. 이에 따라 전세계에 있는 사용자들에게 최고의 사용자 경험을 주기 위해서는 글로벌 네트워크 지연을 고민해야 하고 지연을 최소화 하는 것이 해결해야 할 가장 중요한 기술적 도전 과제 중 하나 입니다.

이번 글에서는 beNX에서 위버스의 글로벌 서비스 품질 강화를 위해 고민했던 내용들 그리고 그 과정에서 문제를 해결하기 위해 시도 했던 내용들을 이야기 해보려고 합니다.

멀티 리전 도입 전 API 서버의 응답 속도

첫 번째 시도는 API 서버군의 해외 리전 진출 이었습니다. 위버스는 크게 API 서버, Redis를 이용한 컨텐츠 캐시 서버, AWS Aurora로 이루어진 DB 서버로 나뉘어 집니다.

위버스 서버의 시스템 구성도

하지만 모든 서버들이 해외 리전으로 진출 하기에는 각 리전에 있는 컨텐츠 캐시, DB 서버들의 데이터 동기화 문제를 해결해야 했고, 아직은 데이터 동기화 문제를 해결할 수 있는 시간적 여유가 없었기 때문에 API 서버만 해외 리전으로 진출하기로 결정 했습니다.

API 서버만 해외 리전으로 진출했을 때

하지만 결과는 생각보다 좋지 않았습니다. 위 그림에서도 볼 수 있는 것처럼 CONNECT 시간은 확 줄었지만, WAIT 시간이 무척 길어진 것을 볼 수 있습니다. 이는 미국에 있는 API 서버가 한국에 있는 Redis, DB 등과 같은 백엔드 서버와의 통신이 생각보다 잦게일어나고 그 과정에서 발생하는 네트워크 지연이 영향을 끼쳤기 때문 입니다.

API 서버만 해외 리전에 있을 때의 문제

두 번째로 시도했던 방법은 AWS의 Global Accelerator를 활용하는 것이었습니다. (https://aws.amazon.com/ko/global-accelerator/) 하지만 이 방법 역시 결과는 조금 아쉬웠습니다.

Global Accelerator를 적용한 결과

AWS Global Accelerator는 CloudFront로 사용하는 Edge Server가 API의 프록시 서버 역할을 해주는 구조 입니다.

AWS Global Accelerator 구성도 (AWS 참조)

하지만 생각보다 CONNECT 시간이 줄지 않았습니다. 최대한 사용자의 가까이에서 반응할 수 있도록 CONNECT 시간을 줄이는 것이 가장 큰 목표 였지만 CONNECT 시간은 줄지 않았고 전체적인 응답 시간 역시 서울 리전으로만 운영할 때와 비교하여 크게 나아지지 않았습니다. 또한 위 그림에서도 보이는 것처럼 Edge Server의 위치가 잘못되지 않았을까 의심해 봤지만 13.248.139.251은 미국에 위치한 Edge Server로 클라이언트의 위치에 맞는 정상적인 Edge Server가 반응 했다는 것을 알 수 있었습니다.

세번째로 시도했던 방법은 해외 리전에 EC2 인스턴스를 직접 올리고 EC2 인스턴스에 nginx reverse proxy를 설치하는 방법 이었습니다. 이렇게 하면 API 서버만 해외 리전에 진출 했을 때와는 달리 해외 리전과 서울 리전과의 통신 과정도 대폭 줄일 수 있기 때문에 효과가 있지 않을까 생각 했습니다.

nginx reverse proxy를 적용했을 때의 결과

다행히 세번째 방법은 유의미한 결과를 보여 주었습니다. 기존에 비해 CONNECT 시간도 현저하게 줄어 들었으며 WAIT 시간도 유지 되었습니다.

결과적으로 700ms ~ 1s 정도 걸리던 API 호출 시간이 300ms ~ 500ms로 두 배 정도 빨라 졌습니다.

nginx reverse proxy를 적용했을 때의 결과

nginx reverse proxy 도입 후 글로벌 사용자들의 체감 성능이 좋아 졌지만 아직 문제가 남아 있었습니다. 바로 AWS ALB의 IP 주소 변경에 따른 nginx의 에러 발생 이었습니다.

AWS의 ALB는 경우에 따라 서버가 늘어나거나 줄어들기 때문에 ALB의 IP 주소 역시 유동적으로 변경 됩니다. nginx reverse proxy 설정을 위해 사용하는 upstream 모듈에는 upstream 서버의 IP 변경을 동적으로 감지하는 기능이 없습니다. 따라서 ALB의 IP가 변경되면 nginx는 아래와 같은 에러를 출력하면서 정상적으로 동작하지 않게 됩니다.

[error] 25957#0: *1760577 no live upstreams while connecting to upstream, client: 10.12.31.108, server: XXXXX

이 문제를 해결하기 위해서는 nginx upstream 모듈의 resolve 지시자를 사용하면 됩니다. resolve 지시자를 이용하면 upstream 서버의 동적 IP 변경을 감지할 수 있지만, 안타깝게도 해당 지시자를 사용하기 위해서는 nginx의 commercial subscription이 필요 합니다. (http://nginx.org/en/docs/http/ngx_http_upstream_module.html#server)

저희는 이 문제를 해결하기 위해 백그라운드에서 upstream 서버의 IP를 확인하고 변경되었을 경우 nginx를 reload 해주는 파이썬 스크립트를 도입해서 사용하고 있습니다. (https://github.com/benxcorp/nginx-upstream-reload)

해당 레포는 https://github.com/rohitjoshi/nginx-upstream-reload 레포를 포크한 후 로깅 기능을 추가한 레포 입니다.

지금까지 위버스의 글로벌 서비스 품질 향상을 위해 저희가 고민해 왔던 내용들을 이야기 해 봤습니다. 하지만 위버스의 글로벌 도전은 여기가 끝이 아니고 시작일 뿐 입니다. 더욱 안정적이고 더욱 빠른 글로벌 서비스 제공을 위해 아직도 고민하고 있으며 연구하고 있습니다.

beNX에서는 이런 고민을 함께 해주실 개발자분들을 애타게 찾고 있습니다. 관심 있으신 분들의 많은 지원 부탁 드립니다.

--

--

Weverse Company Technology Blog
Weverse Company Tech Blog

IT 기술로 Global Entertainment & Media 사용자 경험을 혁신합니다. (https://benx.co)