본문 바로가기
일상

소프트웨어 마에스트로에서 얻은 것 - 기술 부분

by 앗가 2022. 11. 30.
728x90
반응형

저희는 대체로 go와 AWS로 서버를 개발했습니다. AWS는 특히 dynamoDB, S3, ECS를 활용했습니다. 원래는 웹 백엔드/프론트엔드, 또 그중에서 프론트엔드를 좀 더 희망하고 있어서 react, styled component이런 기술을 연습했었는데 주제를 게임 쪽으로 잡으면서 서버 쪽에 관심이 많아져 자연스럽게 서버로 넘어가게 되었습니다. 세상에 내가 로직을 구현한다니 너무 최고야 이러고 달려갔습니다...ㅎㅎㅎ... 그리고 힘들었습니다.

서버 개발은 단순히 서버만 존재하지 않았습니다. 게임을 뒷단에서 보조할 서버와 AWS 클라우드 아키텍처와 클라우드에 서버를 배포하기 위한 CICD와 데이터를 저장할 DB, 게임 내 데이터 관리, 로깅 등 여러 해결해야할 문제가 있었습니다. 이런 문제를 AWS 서비스와 연결지어 해결하려 했고 클라우드 지원비도 제공받는 겸 나름 여러 AWS 서비스를 이용해 보게 됐습니다.

주로 다음과 같은 얘기를 하겠습니다. 여기는 주로 7월 이후의 내용을 담고 있습니다.

  1. 왜 go를 했나?
  2. AWS는 처음이라
  3. AWS 아키텍처는 뭐로 구성해?
  4. 어지러운 배포
  5. 생각외로 어려운 게임 데이터 파일
  6. 그래서 뭘 배웠지?
  7. 알았으면 좋았을 것들

1. 왜 go를 했나?

참 미친놈이였습니다. 분명 go를 선택한 순간에 우리의 도전이 과연 언어만으로 끝나지 않을 걸 알았다면 선택하지 않았을지도 모릅니다.

당시 저의 상태는 대략 이랬습니다.

  1. 서버는 express를 쓰고 단일 파일로만 서버를 짜 봤습니다.
  2. python으로 문제를 많이 풀었지만, 서버를 이용한 경험은 없습니다.
  3. java는 이미 다른 사람이 충분히 많이 쓰고 있는 언어이고 제가 이를 새로 익힌다고 해도 남들에 비해 경쟁력이 있을까를 생각했습니다.
  4. 서버를 개발하고 싶어서 팀에 왔는데 서버 관련으로 아는 지식이 없었습니다(미친놈인가?).

네... 사실 뭐로 서버 개발을 하더라도 처음 한다고 생각해야 맞겠습니다. 정말 웃기긴 합니다. 그런데 이렇게 처음 접하는 기술이니 뭘 해도 처음이다 생각하고 도전적인 길로 가보게 됩니다. java보다는 node로, python에서는 flask, django보다 fast api로, 그러다가 go는 어떨까라는 생각에 찾아본 결과, 준수한 성능과 비동기에 강하고, 멀티 스레드 기반이고, 타입이 존재하고, 도커, 쿠버네티스도 go기반이고(근데 이게 저희랑 무슨 상관이 있나 싶지만...), 생각보다 어렵지 않다는 입장으로 오 나쁘지 않겠는데?로 처음에 생각했습니다.

그렇게 생각만 하다(생각만 했으면 python쪽으로 갔겠지만...) 멘토님 중 go언어를 이용 경험이 있으신 멘토님이 있어 OK go로 가자 했습니다.

거의 제대로 된 서버를 구현하는 게 처음이고 기술도 처음이니 오히려 선택하기가 어렵지 않았던 것 같습니다. 그렇게 저희는 그나마 이전에 경험이 있던 python을 내려두고 go로 서버를 향해하게 됐습니다.

그렇게 7월은 후회로 보냈습니다 ㅋㅋㅋㅋㅋ..... 모든 기술 스택을 처음 써보는 go로 피팅을 해야 했고 이 언어에 프레임워크는 뭐가 유명한지도 모른 체 이후 기술선택을 하는 과정에 있어서 많은 시간을 쏟게 했습니다. 또 AWS 서비스와 go를 연결하는 작업도 다른 언어에 비해 시간이 덜 들었다고 하면 거짓말이겠습니다. dynamoDB 연동, S3 연동, lambda 사용 이런 부분에서 약간의 부하가 더 있었다 봅니다.

처음 개발을 하는 서버에서 사용자가 다른 언어에 비해 많지 않다는 특징은 꽤 아프게 다가왔습니다. 그러나 기획단계에서 go 사용을 기획 발표에 선언한 우리 팀! 그렇게 저희 쪽 서버는 go를 배웠습니다.


2. AWS는 처음이라

더 환장할 것은 AWS였습니다. 그래도 go는 나름 C, python의 비슷한 향기가 나서 할만했습니다. 그런데 AWS는 처음에는 막막함 그 자체였습니다. 서버를 온라인에 두고 띄워야 하는데 아무런 지식이 없었습니다. 그러나 저는 서버 포지션이었기에, 진짜 악으로 깡으로 배웠습니다. 소마에서 제공하는 AWS 강의를 다 글로 정리하며 팀원과 공유하고 강의를 완강했습니다.

그런데 강의를 들어서 따라 하면 구성을 할 수 있었지만 이게 도대체 뭔 의미인지, 왜 이렇게 구성하는지 도대체 이유를 몰랐습니다. 네트워크 지식의 부재가 너무 크게 느껴졌습니다. 그래서 7월부터 널널한 개발자님 유튜브 채널에서 네트워크 강의를 다 듣고 정리하자를 목표로 네트워크 강의를 다 수강했습니다. 정리를 시작한 날짜가 7월 11일이었네요.
https://atgane.tistory.com/134

 

널널한 개발자 네트워크 - OSI 7 layer, TCP/IP

널널한 개발자 TV - 네트워크 배우려는 사람들을 위해 https://youtu.be/k1gyh9BlOT8 위 강의 정리. 컴퓨터의 구조는 3개의 구조로 이루어져 있다부터 시작한다. 컴퓨터는 다음과 같은 구조를 갖는다. 컴

atgane.tistory.com

그렇게 AWS에 VPC를 만들고 인스턴스를 띄우고 git과 golang을 설치해서 로컬에서 빌드를 한 것을 인스턴스에 접속하여 git pull로 받아와서 바이너리를 빌드한 다음에 서버를 호스팅 하는 단순 무식한 방법으로 처음으로 클라이언트와 접속이라는 것을 해봅니다.


3. AWS 아키텍처는 뭐로 구성해?

AWS 아키텍처를 빠른 시간 내로 잡고 싶었습니다. 그런데 알고 있는 AWS 아키텍처가 없으니 AWS 코리아에서 참고하는 클라우드상에서 게임 서버를 호스팅 하는 기존 강의를 참고했습니다. 아래는 참고한 자료입니다.
https://www.slideshare.net/awskorea/gaming-on-aws-8-serverless-architecture

 

Gaming on AWS - 8. 서버 없이 게임 만들기 - Serverless Architecture

2015년 9월 2일에 열린 아마존 웹서비스의 게임 개발 컨퍼런스 Gaming on AWS에서 발표된 김일호 솔루션즈 아키텍트의 강연 '서버 없이 게임 만들기 - Serverless Architecture'의 발표자료입니다.

www.slideshare.net

게임 서버의 서버리스 구성에 대한 자료입니다. 게임 로직을 lambda로 처리하고 유저를 cognito외 여러 서비스, data를 dynamoDB, 미디어 파일을 S3, cloud front로 호스팅 하는 그런 구성에 대해 설명합니다.
https://youtu.be/Qa7DkK7IlNU

모바일 게임 서버를 운영하기 위해 고려해야 할 요소와 기술을 소개하는 강의입니다. 개발환경 동기화, 배포 자동화, AWS 네트워크 구성, 서비스 선택, 부하 테스트, 게임 데이터 활용 방법, 데이터 시각화와 저장, 장애 대응, 데이터 이중화에 관련된 클라우드 기반 게임 서버의 전반적인 내용을 소개합니다.
https://youtu.be/rqxLw0hafFY

게임 장르에 대한 AWS 아키텍처의 구성에 대해서 설명합니다. 게임을 서버 기술에 따라 크게 비동기형, mmorpg형, 세션형으로 나누고 그에 대응하는 아키텍처 구성을 소개합니다.

게임 서버의 클라우드 아키텍처 관련은 특히 아래 2개의 유튜브가 많이 도움이 됐습니다. 서버리스를 하기에는 그 모든 서비스를 당시 이용해볼 자신이 없었고 최대한 개발 환경과 비슷하게 세팅할 수 있는 아키텍처를 잡아서 기능 개발을 끝낸 뒤 이후에 제대로 구성을 해보고 싶었습니다. 또 go, 네트워크조차 새로 배우는 마당에 학습 부하를 더 얹기에 부담스러운 환경이었습니다. 또한 여러 lambda에 대한 관리 문제도 있었습니다. 그래서 서버리스는 포기하고 lambda는 랭킹 업데이트와 같은 아주 일부분의 기능만 사용했습니다.

강의를 학습하면서 알게 된 점은 생각보다 모니터링과 로깅이 중요하다는 것이었습니다. 단순히 서버를 배포하고 DB에 잘 저장하면 전부일 거라는 생각은 너무나도 좁은 생각이었습니다. 그렇기에 당분간은 서비스를 많이 늘리는 것보다 개발을 하자로 굳어졌습니다.

다음은 최종 아키텍처의 일부입니다. bucket object를 cloud front를 이용하여 호스팅 하는 부분과 route53적용하는 부분은 생략돼있습니다.


아래는 그 외로 도움을 많이 받은 강의입니다.
https://youtu.be/HI0fPiZpniY

사용자 규모에 대한 아키텍처 강의입니다.


4. 어지러운 배포

클라이언트에 서버를 제공하기 위해 API가 업데이트될 때마다 이런 작업을 반복했습니다.

먼저 리포지토리의 브랜치의 경우: 개발하는 기능을 feature로 개발 -> 로컬에서 dev 브랜치로 merge한 다음 테스트 -> release로 merge한 다음 EC2에서 추가 작업

EC2의 경우: EC2에 ssh 접속 -> 기존에 돌고 있던 서버 프로세스 종료 -> release 브랜치 따오기 -> go언어 빌드(이거도 권한이 또 달라서 추가 작업++...) -> 백그라운드로 서버 돌리기

API가 간단한 것만 작업이 끝나도 서버에 들어가서 이 짓을 반복 하니 쉽지 않았습니다. 저 과정에서 실수를 하기도 쉽고 귀찮기도 해서 상당히 많은 기능이 생기고 서버에 올라가야 클라이언트가 변경을 하는 불상사가 일어났습니다. 물론 이 덕분에 커밋 컨벤션과 브랜치 전략을 더 구성해볼 계기가 되었습니다.

그래서 이때 docker와 github action을 도입했습니다. EC2에 docker를 설치하고 github action runner를 설치해서 dev 브랜치가 push됐을 때 go언어 바이너리를 생성하고 서버에 자동으로 배포하도록 했습니다.

소마에서 gitlab을 제공하지만 자료 자체는 github에서 참조할 게 더 많아 보였고 가끔씩 있던 gitlab의 장애, 그리고 어차피 끝나면 github를 쓰는 게 이득이라 판단하여 그렇게 구성했습니다.

그러나 결국 EC2에 설정한 CICD 또한 private 환경에서 오토스케일링을 이용하기 위해 ECR / ECS로 변경이 일어납니다. 부하 대응에 대한 오토 스케일링 설정을 해보고 싶었고 단순 docker와 action으로는 어렵다 느꼈습니다. 그런데 k8s를 쓰기에는 배보다 배꼽이 더 커질 것을 염려해 ECS로 타협을 보고 기존에 EC2 기반이었으니 fargate보다 EC2를 선택하여 EC2 기반 ECS를 이용했습니다.


5. 생각외로 어려운 게임 데이터 파일

게임에 들어가는 데이터 파일은 크게 두 분류로 나눌 수 있다고 판단했습니다. 하나는 클라이언트만 필요한 파일, 다른 하나는 클라이언트와 서버 모두가 필요한 파일입니다.

예로 국가별 언어 파일이 앞의 예시가 되겠고, 밸런스 파일이 뒤의 예시가 될 것입니다. 이런 파일에 대한 의사결정도 생각보다 쉽지 않았고 많은 부분을 고민했습니다. 예를 들어 다음과 같습니다.

  • 파일 형식은 어떻게? csv? json? 아니면 뭐 새로운 거?
  • 아니면 스크립트를 써?
  • 그럼 파일의 구조는 어떻게? 하나의 파일에 다 적어? 언어는 언어파일에 전부? 밸런스는 밸런스에 전부?
  • 파일 내부에서 속성을 어떻게 분류해?
  • 파일 보안은? 로그인을 하고 파일을 가져가게 할까 아니면 그냥 가져가게 할까?
  • 밸런스 값은 숫자만? 아니면 수식으로 넣고 구문 분석?
  • 호스팅은 어떻게? S3? 아니면 인스턴스나 컨테이너에서 받아서 호스트?
  • 버전관리는? 게임 데이터 버전관리 어떻게 하실?
  • 데이터 파일은 CICD 어떻게?

허어.... 답이 없습니다. 너무 어렵네요...

네... 많은 고민을 했고 어렵고 어려웠습니다. 뭘 해도 맞는 정답이 없고 뭘해도 틀린 정답이 없는 영역이라 생각합니다. 저희는 위의 대답에 팀만의 대답을 내고 그 환경에 맞추어 갔습니다. 이 부분이 사실 현직의 경우에 어떻게 하셨을지 많이 궁금한 내용입니다.


6. 그래서 뭘 배웠지?

음... 되돌아보면 정말 많은 것을 배웠습니다. 6월까지 대부분을 기획에 쏟았고, 유니티도 잠깐이지만 경험해보았습니다. 본격적으로 서버의 내용을 학습한 것은 7월부터이고 그쯤에 구현해 나갔던 것 같습니다. 새로 배운 것들은 정말인지 너무 많습니다. 언어는 go를 얻었고, AWS에 새롭게 흥미를 갖게 된 점과, 이를 이해하기 위해 공부한 네트워크, docker와 컨테이너 기술, 쉽지 않은 에자일, 그 외로 게임 자체에 대한 이해도 높아졌다고 생각합니다.


7. 알았으면 좋았을 것들

7.1. 밸런스 밸런스 그리고 밸런스

네. 저는 게임의 핵심이라 생각합니다. 개발만 하다 밸런스를 너무나도 늦게 작업한 것이 너무 아쉽습니다. 밸런스는 뼈아픕니다. 게임은 이미 진행됐는데 밸런스 패치를 했을 때 반응이 당연히 좋을 리 없습니다. 그런데 저희는 너무 성급하게 배포를 했었고 이미 계정은 존재하는 상태에서 밸런스 패치를 많이 하게 됐습니다. 꽤나 실수가 있었던 부분이고, 많은 게임들이 개발이 됐지만 왜 이렇게 출시가 늦어지게 되는지 이해하게 되는 부분이었습니다. 밸런스가 깨질 때와 좋을 때의 유저가 게임을 지속해나가는 비율 자체가 달라집니다. 개발에 치우치다보니 이런 디테일한 부분에서 부족함이 있었습니다.

7.2. 지금 고른 스택이 미래를 결정할지도 모른다

좀 더 현실적으로 풀어보면 4월에 11월을 생각해서 무언가를 결정해야 한다가 되겠네요.

처음 기간 동안 고른 기술스택이 말 그대로 미래를 결정할 수 있을 거란 가능성을 아예 몰랐습니다. 소마를 끝나고 사회로 나가는 우리는 소마 프로젝트가 제일 빛나는 법입니다. 그런데 저는 네. 그렇습니다. 대부분이 선택하지 않는 go와 그리고 게임 분야를 골랐습니다. 그러나 후회하지 않습니다.오히려 새로운 분야를 경험해보는 계기가 되었고 기존에 웹에만 있던 관심을 다른 분야로 확장해볼 수 있었습니다. 게임 분야와 콘텐츠 분야에 관심이 생겼고, 전에는 알지도 못했던 게임 서버 관련 지식과 블록체인의 분야, 그리고 AWS를 사용해보며 배운 CICD, 인프라, 네트워크와 같은 개발을 보조하는 분야에 시야를 갖게 됐습니다. 오히려 그래서 도전적이고 자신감 있게 움직일 수 있을 것 같습니다. 이 사실을 알았다면 달라졌을 수 있겠지만, 돌이킬 수 없는 지금을 후회하진 않습니다. 오히려 만족스럽습니다. 이 부분에 대해서는 자신의 특성에 따라 스택을 맞춰서 진입하는 게 제일 좋을 것 같습니다. 다행히 저는 운이 좋게도 그랬습니다.


네. 이렇게 기술 부분도 마무리가 지어졌습니다. 일단 올해를 다시 되돌아가고 싶지 않습니다. 나름 최선을 다했고 오히려 이를 다시 따라 걷기가 두렵습니다.

앞으로의 방향은 어떻게 될지 사실 잘 모르겠습니다. 프로젝트를 게임을 했지만 게임 서버가 될지, 클라우드 인프라가 될지, go언어를 활용한 블록체인이 될지, 이제는 알아서 길을 걸어야 합니다. 다만 여러 기술을 새로 배우면서 더 큰 세상을 볼 수 있게 되었습니다. 이렇게 마무리가 됐지만 이제 다시 새로운 시작을 향해서 나아가게 될 것입니다. 다만 지금까지 유지한 이 도전적인 진행을 유지해보고 싶습니다.

728x90

댓글