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

[어스토니시아VS] 초기 서버 구조

by ★용호★ 2014. 5. 4.

개발 언어 : C++

사용 툴 : VisualStudio 2010

사용 DB : MS-SQL

 

서버 구조

 

 

DataCenter : 모든 게임 서버를 관리(유저의 상태와 각 서버들의 상태를 관리)

GameServer : 게임에 접속한 후의 모든 기능에 대한 처리

BattleServer : 매칭된 두 유저의 대전을 처리

 

 

모든 GameServer는 DataCenter와 BattleServer 그리고 DB에 연결되어 있다.

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

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

 

BattleServer가 실행되면 마찬가지로 DataCenter에 Connection을 맺고 DataCenter를 통해 각 GameServer에도 알려지게 된다.

전달받은 GameServer들은 BattleServer로 Connect를 요청한다.

 

전투가 BattleServer에서 진행이 되므로 GameServer 간의 연결은 불필요하다.

이 때 BattleServer는 DB로의 접근은 없고 GameServer에서 주는 대전 정보를 메모리에 올리고 대전만 수행한 후

결과를 GameServer에 알린다. 대전 결과는 GameServer에서 DB에 기록한다.

 

주의해야 했던 점은 서버간 통신에서 DB를 접근할 경우 클라이언트로부터 요청된 패킷에 의한 DB 접근과 동기가 맞지 않아

덮어써지는 경우가 발생할 수 있다는 것이었다. 그러므로 한 방향으로만 DB 접근을 하도록 구현하였다.

대전 결과를 BattleServer로 부터 받더라도 결과를 DB에 기록하지 않고 클라이언트의 전투 결과 요청 패킷을 받았을 때 DB에 대한 처리를 하도록 했다.

 

BattleServer를 따로 두고 GameServer에서 Toss하는 방식으로 구현하면서 불편했던 점은

Client의 요청을 전달받은 서버에서 바로 처리하는 것이 아니고 다른 서버로 포워딩을 해야하는 단계가 있어서

구현하면서 혼동이 오기도 했고 실수하는 부분도 많이 생겼었다. 또한 서버간 통신으로 인한 문제(위의 DB접근과 같은..)들도 간혹 있었고

문제가 발생했을 때 발견해내기도 까다로웠었다.

 

 

 

위와 같이 클라이언트로 받은 패킷을 다시 BattleServer로 전달하고 다시 되돌려받은 패킷으로

클라이언트에 알려야하는 구조.. 단계가 하나 더 생긴 것 뿐이었지만 생각보다 불편하다.

 

서버 Crash난 경우 처리

 

DataCenter, GameServer, BattleServer 모든 서버가 각각 Crash가 날 확률이 있기 때문에

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

 

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

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

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

 

BattleServer가 죽은 경우 해당 서버가 죽었음을 DataCenter에 알리고 DataCenter는 해당 서버로 대전이 매칭되지 않도록

BattleServer 리스트에서 제거 한다. 다시 BattleServer가 올라가면 처음 연결 시퀀스와 마찬가지로 DataCenter에 연결되고

각 GameServer에도 연결을 맺게 된다.

 

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

 

댓글