출처 : http://network.hanb.co.kr/view.php?bi_id=936
온라인 게임에서 실질적인 게임을 진행시켜주는 것이 게임 서버이다. 우리는 게임서버의 구조는 게임의 진행과 시스템의 효율성에 많은 영향을 미치는 부분이다. 물리적으로 한정적인 시스템 자원을 효율적으로 사용하기 위해서 다양한 분산 처리는 필수적인 요소이다. 분산처리 구조를 익힘으로써 우리는 좀더 세련되고 뛰어난 성능을 발휘할수 있는 게임서버를 만들수 있다. 온라인 게임 서버 프로그래밍의 핵심인 게임 서버의 구조에 대해 알아 보도록 하자.
1. 일반적인 게임 서버 구조
2. 분산 게임 서버 구조
3. 서버간 통신
2. 분산 게임 서버의 구조
서버 프로그래밍을 하다 보면 분산 서버 또는 클러스터링에 많은 관심을 갖게된다. 그 이유는 온라인게임 서버 프로그래머라면 누구라도 기술적 한계를 뛰어넘어 수만에서 수십만명이 하나의 월드에서 자유롭게 게임을 즐기는 환경을 만들어 주는것을 바라기 때문이다.
현재 국내 온라인 게임을 살펴보면 월드에는 일정한, 내부에서 정하는 유저 제한치가 존재하게 되며 이러한 제한치가 넘어가게 되면 더이상의 유저를 수용하기 보다는 다른 서버군을 오픈하여 유저의 이동을 권하게 하는게 대부분이다.
일반적으로 서버군에 따라 각각 물리적으로 분리된 데이터베이스를 사용하게 된다. 때문에 서버군을 이동하게 되면 데이터베이스가 바뀌기 때문에 개발사에 따라 기존의 캐릭터를 그대로 옮겨 갈수도 있거나 아니면 새로 만들어야 하는 문제가 생기곤 한다. 개발사에서는 새로 오픈하게 되는 서버군에서 캐릭터들의 형평성을 위해 특별한 이유가 없는한 이전에 사용하던 캐릭터를 다른 서버군으로 옮기지 못하게 한다. 대부분의 온라인 게임이 이러한 구조를 택하고 있고, 하나의 캐릭터가 서로 다른 서버군을 옮겨 다니며 게임을 할 수 있게 만든다는 것은 분명 쉬운 일이 아니다.
질문 : 통합된 월드의 게임 서버를 만드는데 가장 문제가 되는 것은 무엇인가?
답: 첫번째는 통합된 월드내 수많은 유저의 정보를 실시간으로 저장할 수 있는 데이터베이스가 가장 문제가 된다. 서버군의 유저수를 통제하는것도 데이터베이스의 문제가 주요인이다. 그 이유는 데이터베이스가 실시간으로 동시에 처리할 수 있는 능력은 시스템에 따라 한계치가 있기 때문이다.
두번째는 데이터베이스의 부하를 분산하기 위해 replication 기능을 생각해 볼수도 있다. 하지만 replication 기능도 상황에 따라 한쪽 데이터베이스에서 오류가 발생할 경우 처리문제는 상당히 까다롭다. 실시간으로 오류 발생 즉시 다른 한쪽으로 데이터베이스 커넥션을 바꾸어야 하는데 이또한 임시적인 방책이지 해결책은 될수가 없다. 부하가 심해 오류가 발생되었다고 오류가 없는 데이터베이스로 커넥션을 옮긴다면 한쪽으로 부하가 집중되어 역시 오류가 발생할 문제가 다분해 지기 때문이다.
세번째는 실시간으로 부하를 분산해야 하는 문제가 있다. 갑자기 하나의 지역에 많은 유저가 몰리게 된다면 시스템의 한계에 의해 서버의 처리 속도가 현저하게 느려지거나 심할경우 OS가 다운이 될수 있기 때문이다. 부하를 실시간으로 분산시킬수 있는것은 상당히 까다로운 문제이다.
replication란? 데이터베이스의 복제 기능이다. 똑같은 정보를 가지고 있는 데이터베이스들끼리 연결되어 한쪽 데이터베이스에 정보가 입력된다면 입력된 데이터를 다른 데이터베이스에도 똑같이 입력되게 하는 데이터베이스 기능이다.
필자의 경우 같은 지역을 여러대의 맵서버가 관리하는 분산구조를 간단하게 테스트 해본적이 있다. 구조는 동기화 서버(1대)+게임 서버(여러대)의 구조이다.
![](http://image.hanbitbook.co.kr/blog/7609/1084351209@2_1_dispersion_struc.gif)
[그림1-13] 게임 서버의 분산 구조
동기화 전문 서버를 한대 두고 그에 여러대의 동일한 맵서버가 연결되어 부하를 분산시켜주는 구조이다. 동기화 서버와 맵서버간에는 UDP를 이용하여 데이터를 송수신 한다. 예를 들어 동기화 서버에 2대의 게임서버1,2를 붙이게 된다면 유저들은 게임 서버 앞단에 있는 로드밸런싱 서버에 의해 적은수의 유저가 있는 게임 서버를 알게하여 게임 서버 1,2에 분산되어 접속하고 게임을 하게 되지만 같은 섹터에 있는 캐릭터는 동기화 서버에 의해 동기화가 되는 구조이다.
물리적으로는 분리되어 있는 게임서버 1,2 이지만 동기화 서버에 의해 논리적으로는 같은 서버에 존재하게 되는 것이다. 동기화 서버는 오직 캐릭터들의 동기화 작업만 수행하기 때문에 디스크i/o가 없어 부하를 적게 차지하여 여러대의 동일한 공간의 게임 서버를 동기화 시킬수 있는 구조이기 때문에 많은 유저들을 수용할 수 있다.
3. 서버간의 통신
이전에 필자가 구현 했던 MMORPG의 서버군의 구성은 다음과 같다. [그림1-14]를 보면서 서버간의 통신에 대해 이야기 해보자.
![](http://image.hanbitbook.co.kr/blog/7609/1084351257@2_2_server_group.gif)
[그림1-14] 서버군
[그림1-14]의 서버군은 패치+로그인+로비+맵+관리 서버의 구조로 되어 있다. 서버간의 통신은 UDP 프로토콜을 이용하며 관리 서버를 중간에 두어 월드의 모든 접속자 리스트를 가지고 접속자 관리, 전체메세지 전송, 타 서버에 있는 케릭터에 귀속말 전달 등의 일을 담당한다. 유저가 인증에 성공을 하게되면 최초 인증 서버에서 관리 서버로 유저의 기본 데이터를 송신하여 유저의 연결 리스트에 추가를 하게 된다. 유저가 월드를 선택하고 캐릭터를 선택하여 게임 서버에 접속을 하게 되면 게임 서버에서 관리 서버로 관련 정보를 송신한다. 관리 서버에서는 데이터를 수신하여 연결리스트의 해당 유저 노드를 잘라내어 월드 트리의 해당 서버 브렌치에 노드를 추가하게 된다.
각 게임 서버들은 2개의 네트워크 인터페이스(랜카드)를 사용하여 각각 외부/내부 네트워크 전용으로 사용하였다. 특히 데이터베이스의 경우 외부 네트워크와 차단하여 혹시 있을수 있는 해킹에 대비하였다. 내부 네트워크와 외부 네트워크로 구분하기 위해 각각의 네트워크 인터페이스 카드(랜카드) 하나(랜카드1)에는 공인 IP를 또다른 하나(랜카드2)에는 사설 IP를 부여 하였다. 사설 IP는 B클래스 172.16.0.0 - 172.31.255.255 영역을 사용하였다. B클래스를 쓴 이유는 네트워크당 65000개의 호스트를 수용하기 때문에 서버가 많이 늘어나도 아이피가 부족할 일이 없기 때문이다. [표1-2]는 내부 네트워크에서 사용하는 클래스의 IP대역과 네트워크당 수용 가능한 호스트의 수이다.
![](http://image.hanbitbook.co.kr/blog/7609/1084351366@2_3_host.gif)
[표1-2] 클래스대역폭 및 수용 호스트수
각 서버들의 정보는 데이터베이스에 저장되어 있기 때문에 처음 서버가 구동될 때에는 전체 서버군에 있는 서버들의 정보를 적재(load) 시킨다. 적재된 서버의 정보는 서버 인덱스와 내부 아이피 정보인데, 각각의 서버들은 다른 서버와의 통신을 위해 서버 정보들을 사용한다. 통신이 필요한 서버에 메세지를 송신하고 수신받은 서버에서는 메세지에 따른 처리를 한 후에 다시 응답 메세지를 보내주면 하나의 통신이 완료되는 것이다.
서버간에 전송되는 메세지는 주로 캐릭터가 게임 서버를 이동할 때 사용되는 패킷과 귀속말 패킷이 주로 사용된다. 유저가 게임서버를 이동할 때에는 캐릭터가 위치하고 있는 포탈 인덱스에서 이동하려는 서버의 인덱스를 알아내어 클라이언트에게는 이동하려는 서버의 아이피, 접속 포트번호, 인증 키 등을 전송하고, 캐릭터가 현재 위치하고 있는 서버에서는 이동하려는 서버로 인증키 등을 전송한다. 클라이언트에서는 현재 서버로부터 받은 아이피와 포트로 새로운 서버로 접속을 하고 인증키를 통해 인증을 받게 된다. 서버간 통신은 랜카드2를 통해서만 송/수신(서버간의 패킷은 사설아이피로 수신된 패킷만 인정하고 공인아이피로 온 패킷은 무시) 하기 때문에 혹시 있을수 있는 사용자의 해킹을 방지한다. [표1-3]은 IP address 별 사용 용도와 특징을 정리한 내용이다.
![](http://image.hanbitbook.co.kr/blog/7609/1084351779@2_4_ip_address.gif)
[표1-3] IP address 사용
외부로부터의 보안을 위해 서버는 TCPWRAPPER를 사용하여 관리자 아이피외의 접근을 막았다. 게임 산업이 발전함에 따라 게임 서버의 보안 문제가 이슈가 된지는 오래이며 유명 게임 서버들의 경우 해커의 공격 목표가 되기도 한다. 해킹에 의해 소스나 데이터베이스가 유출되기도 하기때문에 개발사들은 보안에 만전을 기해야 한다. 시스템의 해킹은 자칫 큰 문제가 되어 게임의 흥망에도 큰 영향을 미칠수 있기 때문에 중요한 문제이다.
TCPWRAPPER란? Wietse Vanema에 의해 제작된 TCPwapper 는 호스트레벨에서 특정 프로토콜과 포트, 네트워크 IP 에 따른 접속허가를 내줄 것인지 거부할 것인지 결정하는 packet dropper이라고 볼 수 있다
'Development > 온라인 게임 서버' 카테고리의 다른 글
서버 엔진 기술 (0) | 2010.10.13 |
---|---|
게임 서버의 구조(1) (0) | 2010.10.13 |
![DNS server, DNS service](http://banner.dnsever.com/dnsever-banner_170x35.gif)