Here are a few default rules for threading or using threads:
- A. Thread data as far as possible thread operation, do not use multithreading and careless to set up a lot of public variables to let it compete, this is bad. The purpose of thread opening has been explained in previous articles. By the way, there are plenty of concurrent collections available, such as the much-talked about ConcurrentHashMap. These collections are only used when competition is unavoidable, such as player collections (logins are used, scenes are used, interfaces are used)
- B. Do not add threads if necessary. It is necessary to use threads accurately, such as high blocking, high computation, failure tolerance and other factors to open threads, do not abuse, to accurately control the number of threads in the project and specific use. Otherwise a multithreaded problem, check the problem check you dead.
1. Network threads (using Netty here)
Netty itself has planned out the use of the network in terms of threads, so we went along with it, with several workers per Boss.
Since bosses are almost always listening for links, they are unlikely to be a bottleneck for concurrency, and one is fine by default. For games with scene interaction, our logic is thrown into the scene thread group for execution, so the Worker is only responsible for dealing with network transmission and parsing. It is good to give four here.
If it is an H5-related strong single-player game, the suggestion logic can be put in the Worker.
Thread-safe issues: Netty guarantees that a Channel is always executed in an EventLoop, so don’t worry about this. (See Netty Register event)
I’ll talk about the mechanics of Netty later.
2. Login thread
Why logins are set to a separate thread.
Login is actually a very simple logic, pull data from the database, cache or third party, verify the success, obtain the corresponding role, load the role into the scene. So, if you look at the login, there’s IO, and IO is a lot of time consuming, so it’s a separate thread.
So why single thread instead of Netty’s own Worker thread?
First, if the login is done concurrently, it will cause a lot of data competition, especially in the top number processing will be more troublesome.
The second is that, after testing, a single thread login is not a bottleneck for the entire application, especially if the player has done LRU caching.
Thirdly, Worker threads are related to the network, especially decoding and coding. We must let players link up first, send the login message, and quickly feedback the results, rather than being stuck in the network layer. We would rather let players’ login threads queue up rather than get stuck in the network thread.
3. Interactive threads
Important: You can think of the client as the handle, the content of the interaction thread as the real data of the player, and the scene thread as the puppet of the player’s handle. So the final process is that the gamepad connects to the server, the server assigns account permissions to the gamepad, and when you select a character, the server puts the character in the scene, and then gives the gamepad access to that character.
A scene character is a projection of interactive data.
Interactions are single-threaded for a reason.
A. Low frequency: The frequency of interactions is very, very low compared to the high frequency operations of the scene, so there is no performance problem.
B. Ensure safety: Since performance requirements are not high, we simply use a single-threaded approach to ensure consistent player data. Players can co-donate supplies to a gang, auction house, booth (not map trading), and so on, and feel free to write single-threaded logic.
4. Scenario thread group
The setting is the most important thing in the game, and for that we can allocate the best resources to it. But again, just the right number of threads, not too many.
Each thread in a thread group manages N maps, of course, depending on the importance of the scene, it is not wrong to assign separate threads to some scenes.
The thread thread ensures consistency of player data (including transactions) with the map.
Scenarios are high frequency logic, so you can’t have multithreading problems.
To switch scenes, you must log out of the original scene (thread) first, and then synchronize the scene to another scene.
When a scene thread group collaborates with an interaction thread, it is important to keep the scene thread running smoothly, and the interaction thread can be freely blocked.
Specific practice gives a reference. Suppose the player donates gang resources.
The first step, the interactive thread detects the gang information.
Step 2: Jump to the scene thread, block the interactive thread (Callable and Future blocking), and wait for the player scene player resources to be deducted.
Third, increase gang resources.
5. Schedule threads
Scheduling threads is very simple. A Scheduler or Timer sends a Runnable or Callable to the scene or interaction thread for execution whenever a time (millisecond level or Cron expression control) arrives. Scheduling threads can be multiple, but they must be sent to the corresponding thread for execution to ensure data consistency.
6. Interface threads
The interface thread is responsible for providing the OpenAPI, which is the open interface. Such as scene number audit, recharge callback and so on.