Scaling and Administration

posted in trill41 for project ABx
Published November 02, 2018
Advertisement

The Game server doesn't scale vertically (i.e. throw better hardware at a problem) well, because it's mostly single-threaded, so it can host only a limited amount of concurrent games. The second option is to make it scale horizontally (throwing more hardware at a problem) well, so make it possible to spawn/shutdown Game servers dynamically across different hardware.

Only the File and Game server are meant to be spawned dynamically. All other server are needed that these servers can work together.

For this I made an Admin interface (btw. meanwhile I'm no longer sure what's this all about, is it a game server or a framework for scaleable servers?), which can spawn Game and File server as needed.

absadmin.thumb.png.cb3f3400bc2cba9a77ab216675cdd96b.png

Oh yes, I wrote a Web server for it, based on SimpleWeb which is also used for the File server, and it uses a nice Bootstrap theme (Gentelella Admin). I just added support for Cookies, Sessions and it has simple templating, because I don't want to write Markup in C++. Hell, I totally forgot how fast a Web server can be, like response times under 1ms.

A central part in this process takes the Message server, which is for inter-server communication. It works like a Chat server, Clients connect to it and can broadcast messages to all other connected clients, or they can send a message to a certain client identified by its ID.

A server can only spawn another instance of itself, it can not spawn a different server, like a File server can not spawn a Game server. So there is a persistent (master) server that can be told to spawn child servers, and it'll do so.

absadmin_details.png.d38d5d0447758cfa0d09b45782607fbf.png


Exactly this is happening when clicking the green Spawn button. The Admin server sends a message to the Message server, which forwards the message to this particular server and this is spawning a new server of the same type with the same configuration.

spawn_flow.png.77e3f4f45c20d7af808d3de52076ee71.png

Well, with almost same configuration, of course it needs a unique ID (I use UUIDs), a unique Name and it must use a free Port. To get a free Port, this is what works for me:


uint16_t GetFreePort()
{
    asio::io_service service;
    asio::ip::tcp::acceptor acceptor(service);
    uint16_t port(0);
    asio::ip::tcp::endpoint endPoint(asio::ip::tcp::endpoint(asio::ip::tcp::v4(), port));
    acceptor.open(endPoint.protocol());
    acceptor.set_option(asio::ip::tcp::acceptor::reuse_address(true));
    acceptor.bind(endPoint);
    acceptor.listen();
    asio::ip::tcp::endpoint le = acceptor.local_endpoint();
    port = le.port();
    acceptor.close();
    return port;
}

Shutting down a server is different, it can stop only itself. So if one server wants to shutdown another server, it sends a message to the message server, which sends the target server a message to stop itself. Even a "Master" server can not shutdown a child process, it would need to send a shutdown message to the Message server.

Previous Entry Migrating and Porting
Next Entry Skills
1 likes 0 comments

Comments

Nobody has left a comment. You can be the first!
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Profile
Author
Advertisement

Latest Entries

Advertisement