NDC(Nexon Developer Conference) 2019, <FIFA 온라인 4> 서버 포스트모템 후기
— Conference — 4 min read
발표자료는 올라올테지만, 가장 인상깊게 들었던 발표를 들으며 적었던 노트를 날것으로 (ㅋㅋ) 공유합니다.
<FIFA 온라인 4> 서버 포스트모템
김에스더님 From EA Korea
런칭 이전에 서버 준비과정부터 런칭 이후 운영 이슈까지 공유하고자 함
Microservices on Kubernetes(오케스트레이션 툴)
서버 아키텍쳐
피파온라인4는 FIFA시리즈 바탕 온라인 게임
아시아 4개국, PC와 모바일로 서비스 중
전작 피파3은 Monolithic Architecture
- 하나의 애플리케이션에 모든 구현이 담겨있었음 (Db- Game Server - User Interface)
- 세가지 단점
- 장애 → 전체 서비스 장애
- 작은 변경을 위해 전체 서버 빌드 및 배포 필요
- 비효율적인 서버 Scale out 비용 (휴일 등 트래픽 대응에 전체 서버를 스케일 아웃해야했음.)
MicroService Architecture
- 여러개를 합쳐서 운영하는 방식
- 개발 속도가 빠르다
- 배포가 쉽다
- 서버 장애의 영향도가 일부 서비스에 국한된다
- 스케일링이 쉽고 효율적이다
- 백엔드는 RabbitMQ, MongoDB, Redis 등을 사용함. (서비스 단의 메시지 통신을 위해 메시지 큐)
- 서비스 모니터링을 위한 Grafana 등으로 구성
- 대표적인 서비스 - GateWay, Auth, Session, API, Data, Log, Chat, Noti, Matchmaker
- 로그인 : Gateway가 받아서 처리할 수 있는 Authenticate 서비스에 보냄
- 전달하는 매개체는 RabbitMQ
- 훨씬 복잡한 구성이 있기때문에, hop이 길어지는 경우도 많음
배포
- 배포해야 하는 대상이 너무 많음
- 게이트웨이
- 인증
- 알림
- 로그
- 데이터
- 매치메이킹 등 .. 40가지 서버 부자가 되었다.
- 이렇게 많은 종류의 서비스를 라이브 서버에 어떻게 배포하지?
- config 하나하나 작성해서 40번 올리면 되지 🙂
- 이걸 관리할 수 있는 오케스트레이션 툴
- 구동, 배포, 관리하기 위해서 Kubernetes를 사용
- 구글이 개발, 선택하게 된 이유 중
- 라이브 서비스를 하기에 적합한 툴이라는 생각이 들음
- 장애나 형상관리를 할 때 유용한 Feature 들
- Rolling Update
- Version Control
- Auto Scaling
- Resource Allocation 이 가능하다.
Kubernetes Cluster
- Master - Node 의 단순한 구조
- Master의 요소랑 일반 노드의 요소랑 다름
- Master는 관리자 역할이 있으니까, 다양 - DNS 서버, API 서버, Scheduler, Controller Manager
- 클러스터 마스터에 명령을 내릴 때 실제 명령을 내리게 해주는 매개가 API 서버 (이를 통해 cluster 내에서, 그리고 관리자와 소통)
- Node 내에는 Kubelet이라는 노드 agent가 뜸.
- node 마다 role을 줄 수 있는데, role에 따라 어떤 서비스를 띄울 지 결정할 수 있음
- e.g.) Backend node는 MQ들이 뜨고, Game node에는 API 서버, cronjobs, data server 가 뜨는 방식
서비스 배포 단계
- 서비스 빌드 & 업로드
- Kubernetes Manifest 작성 ← 어려움, Kubernetes 적용 config
- 작성하는 포맷이 복잡하여 작성 작업이 시간이 크게 소요됨
- 스키마가 다 다름
- indentation 이 중요 ( yml 파일임 ㅠㅠ)
- 오타 등 실수가 감지하기 어려움
- 히스토리 관리와 공유가 어려움
Helm이라는 패키지 매니저를 통해서 Manifest를 관리 및 배포 프로세스 구축 + Jenkins와 Herfos(?)
- Helm
- 버전 컨트롤 뿐아니라 manifest respository 구성 가능 → 어떻게 manifest 작성할지 막막할때 helm 오피셜 repo에서 fetch 해올수 있음
- 방식이 좀 달라서, 지속적으로 변경이 일어나는 상수 부분을 대체할 수 있음.
- 40개의 서비스 manifest에 버전이나 서버 갯수를 바꿔야한다면..?!
배포 프로세스
레포에 manifest 커밋 → 젠킨스 job CI → Jenkins가 helm repo에 manifest push → 서버에서 fetch 해감
- 서버에 Manifest 적용하여 서비스 업데이트
장점
- 배포 히스토리 관리
- Helm 기능으로 설정 오류 감소 , 오류 보정됨
- 팀내 sync up
- 작업시간 감소
Stability
어떻게 서비스를 안정적으로 ?
서비스 오픈날도 장애없이 4개 국 동시 운영
장애 대비와 대응을 어떻게 했나? 🤨
Microservice Architecture
부하가 전체 서비스가 아닌 일부에만 영향을 준다!
match maker라든지 일부 서비스만 다운되면 로그인해서, 거래 시장 이용, 채팅 등은 문제가 없는 부분!
단점일 때도 있었음..
- 어떤 서비스에 얼마만큼의 영향을 주는지 파악하기 힘들다
- 물리서버 발주하는 시점에서(ㅋㅋㅋ) 서비스가 얼마나 리소스를 사용하는지 모름! 😢
- 매치 1판 할때 어떤 서비스에 얼마만큼 부하가 발생하는지 명확하게 알 수 있을까..?
- Monolithic 이면 부하만 보면 단순히 계산이 되는데!
- Micro 인 경우 - Gateway 부하가 얼마고, log에, match maker에 부하가 얼마나 들어가는지 계산이 어려움. 커뮤니케이터인 RabbitMQ인 경우 MQ의 부하도 생각해야하고, DB도 생각하고 ...
- 대규모 로드테스트를 하게 됨
대규모 로드테스트
CBT나 OBT말고 대규모(동접 30만 기준)
criteria를 정함 : 서버가 초당 3만 건 요청을 처리할 수 있어야 부하를 견딜 수 있다! 라고 생각함
- 유저 시나리오를 작성
- AWS 로드 테스트 서버 구축
- 라이브 서버와 똑같이 Kubernetes 구성, HA 구성, LoadBalancer도 붙임
- 로드 테스트 실행
기준(criteria)을 통과할 때까지 반복 실행
뭐가 좋아요?
- 부하가 높을 때만 발생하는 문제를 확인할 수 있음
- e.g.) 부하가 높을 때 → 서비스의 메모리 100% 차는 현상
- 처음에 말한 목적처럼 리소스 측정해서 할당 할 수 있음
미처 대비하지 못한 문제
- 패치 데이터 오류
- 발견하기 어려운 서버 코드 버그
- CPU 나 메모리등의 서버 리소스 사용량 급증
이런 문제가 발생했을 때 Kubernetes를 사용해서 해결
Solution #1
Server Hotfix : Rolling Update
- 유저 몰래 업데이트 😗
- 점검 없이 rolling update 가능
- 단. 라이브 서비스 중에 재시작되어도 트랜잭션 처리 등 서버 임팩트가 없도록 보장되어야 함
- 에러를 쓰루하는 등의 처리가 명확하지 않으면 CS 처리로 해야함.. 조심해..😭
Solution #2
손쉬운 명령어로 빠른 Scale out
Solution #3
auto scaling으로 자동 리소스 관리
- 미연에 장애를 관리할 수 있는 기능
- "부하가 늘면 자동으로 늘어나네"
- 단, Scale in 이 될수도 있기때문에 이 경우를 고려해야한다
Monitoring
모니터링 시스템을 구축안해도 Kubernetes Dashboard를 만들어준다 ! 🙂
하지만.. 사실상 모니터링보다는 관리자 작업 페이지에 가까움
- 서비스 구성 요소
- 리소스 사용량 확인
- 콘솔 로그 확인
- 서비스 생성 및 삭제
위와 같은 기능 제공!
- 리얼 타임으로 이걸 보기엔 괜찮지만 시간을 조절해서 볼수도 없다!
필요한 데이터는 뭐지 🤔
- 물리/VM 서버 상태
- 리소스 사용량
- Kubernetes 서비스 상태
- CCU 증감 추이 (게임 서비스의 데이터)
- 서버 응답 지연 및 에러 발견
위의 세개는 다음과 같이 해결할 수있는데
- Google Cloud Engine을 사용! (무료)
- DataDog같은 솔루션을 사용 (유료)
아래 두개는 다음과 같이 해결할 수있는데
- CCU API를 통해 감시
- Sentry로 에러 감시
솔루션이 나눠져 있는데 통합해서 볼 수 없을까?
- 대시보드가 여러 개면
- 뭔가 문제가 있을 때 한번에 보고 파악하기가 어렵다 .
Custom Monitoring Tool이 필요하다!
- Kubernetes + Game Server를 다 보자
- Kubernetes API Sever (모니터링 통해서 가져올수있는걸 준다)
- cAdvisor는 container 의 상태를 가져와서 Kublet에게 주고. API Server가 가져가고 싶은것만 Kublet에서 fetch해서 가져감
API Server → 프로메테우스에 저장하고 → Grafana(대시보드)
대시보드가 없을때는 Manifest를 들어가서 확인해야했음 ㅠ.ㅠ
NEEDS
- gateway 서버 100개면 평균적인 inbound outbound 값을 보여주고싶은데 그런 툴이 없어서 아직 custom 사용중.
- 처리 건수가 줄어들면 병목 상황을 감지 가능
- Slow API 가 초당 몇개 발생하고 있는지!
SUMMARY
MicroService 단점
- nanoservice 가 될 수 있음 → 갯수가 너무 늘어남
- 서비스 개수만큼 관리비용이 크다
- 트랜잭션과 같은 로직 구현이 까다롭다
- 서비스가 여러개인데 같은 document 에 접근하려고 할 때 로직 구현 어렵
- lock 걸때 지연속도가 늘어나서 어려움
- 서비스 간 통신 시간만큼의 서비스 처리 속도 증가 (hop 마다 속도가 늘어남)
Kubernetes 단점
- 기본 구성이 매우 복잡하다
- 초기 프로세스를 구축하기 위해 많은 노력
- 소규모에 적합하지 않다
장점
- 다양한 기능 제공
- 오토스케일링, 롤링 업데이트, Failover 기능으로 라이브 운영에 적합
개인적으로는 게임 서버 뿐 아니라 어떤 서버든 적용되는 내용을 꼼꼼하게 설명해주셔서 좋았다. 아는게 조금 늘어났다고 좀더 이해되는게 너무 신기하고 (그래서 후기도 쓸 수 있었고 ㅋㅋ), 좀더 개발 세션 들어야겠다.
위의 내용이 발표와 다르거나 틀린 점이 있는 경우 둥글게 댓글 부탁드립니다.