6. 분산 시스템 기능으로 서버 여러대 띄우기¶
이번 챕터에서는 앞의 Flavor 기능을 이용해 서버 기능 분리하기 챕터에서 설명한 분산 시스템 기능을 사용하도록 설정해서 로비 Flavor 와 게임 Flavor 를 동시에 실행하고, 분산 시스템 기능의 동작을 클라이언트 중복 로그인 상황을 통해서 설명하겠습니다.
6.1. 분산 기능 켜기¶
먼저, 분산 시스템 기능을 사용하도록 각 서버의 설정을 변경해 보겠습니다.
동시에 튜토리얼 환경에서는 하나의 서버 호스트에 여러 서버 인스턴스를 띄우기 때문에 서버들끼리 사용하는 포트가 중복되면 서버가 실행되지 않습니다.
따라서 게임 Flavor 는 사용하는 포트도 함께 변경하겠습니다.
hello_world-source/src/MANIFEST.game.json
을 열어서 다음 항목들을 수정 해 주세요.
"SessionService": {
...
"tcp_json_port": 9012,
...
"http_json_port": 9018,
...
},
"ApiService": {
"api_service_port": 9014
},
"RpcService": {
"rpc_enabled": true,
"rpc_port": 9015,
...
},
로비 Flavor 는 포트를 변경하지 않아도 되므로 분산 기능만 켜면 됩니다.
hello_world-source/src/MANIFEST.lobby.json
을 다음처럼 수정합니다.
...
"rpc_enabled": true,
...
끝으로 아이펀 엔진 의 분산 기능을 Redis 서버를 사용하기 때문에 Redis 서버가 설치 및 실행되고 있는지 확인 해 주시기 바랍니다.
$ sudo apt-get install redis-server
$ dpkg --list redis-server
ii redis-server 5:4.0.9-1ubuntu0.2 amd64 Persistent key-value database with network interface
$ sudo netstat -atnp | grep 6379
tcp 0 0 0.0.0.0:6379 0.0.0.0:* LISTEN 1906/redis-server 0
만일, 외부 호스트에 있는 Redis 서버를 사용하고자 하는 경우에는 각 Flavor 의 MANIFEST.json 파일을 열어서 아래 설정을 외부 호스트의 IP 주소로 변경 해 주시기 바랍니다.
"RpcService":
"rpc_redis_hosts": [
{
"host": "127.0.0.1:6379",
"database": 0,
"auth": ""
}
]
6.2. 테스트용 클라이언트 패킷 추가하기¶
저희가 로비 서버에 로그인 한 사용자가 게임 서버에서 이를 확인할 수 있음을 테스트해보기 위해서 signin
이라는 클라이언트 패킷과 check
라는 클라이언트 패킷을 추가해보겠습니다.
hello_world-src/src/event_handlers.cc
에 다음을 추가해주세요.
// 아래 함수는 ifun 이라는 유저를 로그인 처리합니다.
void OnSignin(const Ptr<Session> &session, const Json &message) {
bool r = AccountManager::CheckAndSetLoggedIn("ifun", session);
Json response;
response["result"] = r;
session->SendMessage("singin_reply", response);
}
// 아래 함수는 ifun 이라는 유저가 어느 서버에 로그인했는지 체크합니다.
// 만일 로그인 한 서버가 없으면 서버 아이디는 0000-00... 형태의 Null UUID 가 됩니다.
void OnCheck(const Ptr<Session> &session, const Json &message) {
Rpc::PeerId server_id = AccountManager::Locate("ifun");
Json response;
response["result"] = boost::lexical_cast<string>(server_id);
session->SendMessage("check_reply", response);
}
void RegisterEventHandlers() {
...
// 두 패킷 핸들러를 등록합니다.
HandlerRegistry::Register("signin", OnSignin);
HandlerRegistry::Register("check", OnCheck);
...
}
자 이제 준비가 다 되었습니다. 로비 서버는 8018 번 포트, 게임 서버는 9018 번 포트로 사용되게 되었습니다. 각각의 script 로 이들을 실행합니다.
# 한 터미널에서
$ ./hello_world.lobby-local
# 다른 터미널에서
$ ./hello_world.game-local
6.3. 테스트 해보기¶
자, 이제 8018 번 로비 서버에 signin 을 보내서 ifun 을 로그인하겠습니다.
$ wget -qO- --post-data="{}" http://localhost:8018/v1/messages/signin
{"result":true,"_sid":"497844e8-1885-40ed-b7d7-29f2931ddac2","_msgtype":"singin_reply"}
기대한대로 결과가 true 네요. 중복 로그인을 시도해볼까요?
$ wget -qO- --post-data="{}" http://localhost:8018/v1/messages/signin
{"result":false,"_sid":"f0a511c0-ad16-4b1b-917f-f86da7809814","_msgtype":"singin_reply"}
이미 로그인되었으므로 결과가 false 입니다. 9018 번 게임 서버에 signin 을 보내면 어떨까요?
$ wget -qO- --post-data="{}" http://localhost:9018/v1/messages/signin
{"result":false,"_sid":"52a48a4a-58ef-462c-a08b-92371d298382","_msgtype":"singin_reply"}
예상대로 이미 로그인한 것으로 인지됩니다. 그럼 각각 어느 서버에 로그인했다고 알고 있을까요? 로비 서버와 게임 서버에 각각 check 요청을 보내보겠습니다.
$ wget -qO- --post-data="{}" http://localhost:8018/v1/messages/check
{"result":"aa561332-8aad-4f1f-0000-000000000000","_sid":"622e4ae2-3793-41ac-97ab-708840416a6d","_msgtype":"check_reply"}
$ wget -qO- --post-data="{}" http://localhost:9018/v1/messages/check
{"result":"aa561332-8aad-4f1f-0000-000000000000","_sid":"8bff8116-5583-40f7-b363-c18929ac9400","_msgtype":"check_reply"}
응답의 result 값이 같은 것을 뽈 때, 둘 다 ifun 이 같은 서버에 있는 것으로 인식하고 있네요. 로비 서버와 게임 서버간에 정보가 잘 공유되고 있다는 뜻입니다.
이제 분산 시스템으로 서비스 확장까지 했습니다. 다음 챕터에서는 게임 서버 프로그램의 패키지 관리와 관리용 RESTful API 를 추가해보겠습니다.