본문 바로가기
Work/개발 노트

[어스토니시아VS] 실 서비스에 들어간 현재 서버 구조

by ★용호★ 2014. 5. 6.

개발 언어 : C++, ASP.NET

사용 툴 : VisualStudio 2010

사용 DB : MS-SQL

 

서버 구조

 


DataCenter : 모든 게임 서버를 관리 / 대전 매칭

GameServer : 대전 처리

WebServer : 게임에 접속한 후의 대전을 제외한 모든 기능에 대한 처리

 

 

 모든 GameServer는 DataCenter와 DB에 연결되어 있다.

GameServer가 실행되면 DataCenter에 Connection을 맺고 자신의 상태를 알린다. 이 후 접속하는 클라이언트는

모두 DataCenter에 알려지게 되고 DataCenter는 모든 유저의 상태에 대해 GameServer로 부터 전달 받는다.

 

 여기까지는 기존 서버와 동일하고 달라진 점은 BattleServer가 존재하지 않다는 점이다. 

BattleServer 대신 대전의 처리를 GameServer에서 수행하게 되고 GameServer는 기존과 다르게 대전 외의 다른 작업은 수행하지 않는다. 대신 다른 기능을 위한 Web Server가 추가 되었다. WebServer를 추가한 이유는 TCP 서버에서의 부하를 최대한 줄이기 위함이었는데 장,단점이 존재하는 것 같다. 


 이 전에도 구조를 잡을 때 Web + TCP 구조를 생각해보긴 했었는데 이를 위해서는 Web으로 통신하는 중에도 TCP에 커넥션을 맺고 있어야 하는데 커넥션 맺은 상태에서 굳이 Web으로 통신해야할 이유가 있을까 싶어서 All TCP 구조로 잡았었다. 


 하지만 ALL TCP 구조에서는 Crash가 날 확률이 그만큼 높아지고, 병목현상이 생기게 되면 모든 유저에게 영향이 갈 수 있는데 Web도 마찬가지이긴 하지만 Request 요청에 따라 L4가 서버를 할당 해주므로, 커넥션을 맺고 나면 서버를 변경할 수 없는 TCP만큼 치명적이지는 않았다. 또한 서버를 확장하는 데에 Web보다는 불편하다는 단점이 존재해서 선택에 고민을 많이 했었다. 


 이번에 잡은 구조는 TCP에서는 대전만 처리하고 나머지 기능은 Web 서버에서 모두 처리하는 방식으로 DB 접근도 최대한 Web 서버에서 하도록 구현하였다. 

 

서버 Crash난 경우 처리

 

DataCenter와 GameServer 서버가 각각 Crash가 날 확률이 있기 때문에

각각의 경우를 모두 생각해봐야 한다.

 

우선 가장 중요한 DataCenter가 죽을 경우 연결된 GameServer들은 DataCenter가 죽었다는 상태로 만들고

모든 클라이언트에 알린다.  이 후 DataCenter가 다시 살아 날 때까지 재연결을 시도 한다.

DataCenter가 다시 살아나면 GameServer에서는 DataCenter와 재연결을 맺고 현재 서버에 접속해 있는 User들을 처음 접속했을때와 같은 시퀀스로 DataCenter에 접속 상태임을 알린다.

 

GameServer가 죽은 경우 해당 서버의 User는 어쩔 수 없이 연결이 끊어지게 된다. 다른 경우들과 마찬가지로 DataCenter에서 GameServer가 제거 되고 재 연결시에 다시 등록된다.


WebServer의 경우에는 데이터베이스 트랜잭션 처리만 잘 해주면 서버가 크래쉬나더라도 크게 문제될 소지는 없었다.


라이브 서비스에 들어간 지금...


 단기간 내에 작업을 하다보니 TCP 쪽에서 조금 아쉬운 부분들이 있었다. 우선 대전이 "모두의 마블" 처럼 서버간 통신으로 유저가 직접 서버를 옮겨가는 방식이 아니고 상대방 정보를 복사해와서 각각 수행 되는 방식이다. 그래서 두 유저가 같은 자원을 공유해서 사용하는 것이 아니라 복사된 정보를 따로 돌리고 있기 때문에 메모리 낭비가 생기게 되었다. 공유 자원을 사용할 경우보다 두배의 메모리가 필요하게 되므로 개발하면서 이부분이 무척 걱정이 되었었는데 대전에 필요한 정보가 크지 않기 때문에 생각보다는 큰 지장을 주지는 않았었다. 


 그동안은 개발하면서 서버에 대한 테스트를 소홀히 한 경향이 있었는데 이번에 더미를 통한 스트레스 테스트의 중요성에 대해 절실히 느꼈다. 나중에는 뭔가를 수정할 때마다 더미 테스트를 항상 수행하면서 구현과 테스트를 병행했다. 

 더미 테스트를 할 때는 유저가 어떠한 경로로 접근을 할지 예측할 수 없기 때문에 정상 동작 테스트 뿐만 아니라 유저가 끊어졌을 때의 경우와 중복 접속의 경우 등 여러 부분의 경우의 수를 생각해보고 테스트를 해봐야 한다. 


 또한 우리가 가장 애먹었던 부분은 바로 DB처리.. DB에 대해서 초보 수준이었기 때문에 테이블과 프로시저를 설계할 때 성능에 대한 부분을 고려하지 않고 구현을 한 부분들이 많았었다. 그 부분은 성능 테스트에서 전부 드러났다. 키와 인덱싱의 중요성, 그리고 쿼리 사용방법에 대해 제대로 숙지 하지 않고 사용했기 때문에 가장 많은 시간을 잡아먹었다. 이번 계기로 성능을 높이기 위해 이것저것 찾아보며 많은 공부를 할 수 있었고, 앞으로도 더 공부를 해야 할 것 같다. 

 


댓글