Go game server framework from scratch (1) – Architecture Design

Time:2021-1-7

Wuyi Yinxia, whose real name is Jianchang, has been playing for 10 years and now lives in seclusion by the sea.

  This tutorial takes go language partition game server framework as an example.

Go language is a kind of programming language developed by Google, which is static, strongly typed, compiled, parallel and has garbage collection function. It is similar to C language in syntax, and supports the object-oriented concepts such as interface, including another struct to realize inheritance. Compared with C / C + +, it is more robust and easier to develop concurrent programs. I used to write c + + server. After contacting go, I prefer to use go for game server development.

  The so-called partition game, refers to the game will be divided into many areas, different areas between players can not interact or only a small amount of interaction. Players need to select the partition to enter the game, and enter the designated partition to play the game. A player can have roles in different partitions at the same time. At present, most of the medium and heavy online games in the market adopt this mode. Partition games are suitable for games that do not need big dau interaction, such as cards, MMORPG, SLG, etc. From the technical level, the partition is a means of cluster expansion; in terms of operation, it is conducive to the fine operation of the partition, and rolling service operation has been a relatively mature means of game operation. Compared with partitioned games, there are also social games that are not partitioned. The core of this kind of games is matching confrontation, such as COC. If the partition of a partitioned game is mapped to the node service of the game, and the broadcast service is mapped to the matching service, the architecture of a non partitioned game will be well understood.

This tutorial mainly talks about the construction of partition game server framework.The overall design is as follows:

  Partition game, players first log in to the game, and then enter the designated partition. So first of all, there should be a login server to provide global login service. The core data of the login server is the player’s account, and the core business is to check the login of the player, including using the own account system and the third-party account. Account data needs to be stored for a long time, so there is a MySQL database in the server to save the player’s account information. There are one or more login service processes for game login verification. The login service is a short connection service, which uses HTTP protocol to provide a unified access address through nginx to balance the load of multiple login service processes. Generally, the login interface will also return partition information, brief information of players’ roles in each partition, the latest version number of the client, configuration version, resource version, announcement, etc. these information can be dynamically updated through the GM service (described later). The login service will obtain and return to the client in response to the request. Therefore, a redis service will be provided on the login server to cache these data.

After successful login, the player will enter the selected game partition. A partition is a set of service processes. Most of the game partitions use long connection communication. If we take into account the popular H5 games and wechat games at the same time, we consider using websocket for communication (used to use socket). Considering the need of broadcasting in the game, both broadcasting data and partitioned game data want to return to the client from the same connection, it is necessary to provide a unified partitioned gateway service. The gateway service process provides the client with a unified partitioned address and port, and forwards the data internally. The logical business of partition can be centralized in a game server process. In the past, the online data of some games were saved in the process memory. Due to the frequent changes of game data, the frequent reading and writing performance of MySQL is not high, so it will be saved to MySQL after a certain period of time. But within the zoneThe gamesuit is a single point. Once it collapses, the memory data of the gamesuit will be lost. It will be saved to the last time. Later, in order to reduce this risk, some games saved online data to shared memory and then to MySQL regularly. Shared memory depends on the system and language, so it is found that go has no direct support. Later, memcached and redis came into being. Some games chose to use this kind of caching system for caching. The game server collapsed, and the data was still in the cache. It could quickly start the game server recovery service. I choose redis as the cache to cache active player data. After a certain period of time, save the change data to MySQL. Redis data mainly uses the key value method to save data, and each business processing needs to read, parse, and then use. Not very friendly to business development. The game server process memory will still save the online player data. When the player enters the partition, it will read the game server memory from redis. If redis fails to hit, it will issue a message to the data server for data preheating. After successful preheating, it will read from redis. Later requests can be judged and processed directly through the memory data, and the changed data can be saved to redis in transaction mode, which will be responded to the client after success. In this way, the memory data is consistent with the redis data, and the player data can be split into smaller units to reduce the communication with redis. After the player goes offline, clear the memory data of the game clothes. So there is a redis and a MySQL in the partition. In order to establish the mechanism of saving data regularly, and not be affected by the collapse of the game server, a data service with simple function is equipped. Through the publish subscribe mechanism and message queue of redis, it is responsible for the regular landing and solidification of data, player registration and data preheating.

As the name suggests, radio service is mainly responsible for broadcasting, such as running lantern broadcasting, world chat and world boss. Broadcast service will broadcast data to players through gateway service of each partition, so broadcast service will connect gateway of each partition. The broadcast task is cached by message queue, so that the broadcast operation of each partition can respond to the client after it is written to the queue. The message queue is implemented by redis. Broadcast service is a global service. In order to avoid a single point of risk, it can be a master-slave service. Through the subscription publishing mechanism of redis, it can subscribe to redis when it is started. If it does not receive the publishing message for a certain period of time, it thinks that the master service does not exist. It switches to the master service, cancels the message subscription, connects to each partition gateway, and regularly publishes the message to redis.

In addition to business-related services, we need to provide management for the whole service system. For example, service opening, service stopping, configuration / resource version updating, email, announcement, props distribution, kicking, etc. It provides a global GM service. After each partition service is started, the game server process connects to the GM service and keeps the heartbeat to inform the GM service to start / stop. GM service updates these changes to the redis of login service, so that players can log in to the game and know the status of each service. The GM service can also send a message to redis to notify the login service to perform operations such as sealing. Since each game server is connected to the GM server, the GM command can be sent to each partition. The GM service can write messages to the message queue of the broadcast service and send full broadcast. The function of GM service is operated by operators, so HTTP service is needed to facilitate access on the web. GM service has the function of releasing props, so the third-party payment callback can request delivery through the HTTP interface of GM service.

In order to provide decision-making for the operation, we also need to provide statistical background to collect and count the game data log. Due to the login service, the game service of each partition and the GM service will report the data, the data source is wide and the amount of data is large, so the message queue is needed. Therefore, login service, game service and GM service all report through the message queue of redis. Statistics follows redis to read messages and save data logs to MySQL. Therefore, a redis and MySQL are needed. The function of statistical service is used by operators, and HTTP service should be provided to facilitate access on the webpage. The HTTP interface of the statistical service also supports the client to report data.

In order to merge the pages of operators, GM service and statistics service provide a unified HTTP address through nginx.

In this way, we get the whole service framework as shown in the previous design.

So far, we will introduce the implementation of each service in detail. Before that, the next article introduces the design and implementation of some common basic mechanisms.