问题
I am currently working on an online card game, similar to blackjack, which will consist of a series of tables where each table has a "dealer" and multiple human players. The dealer (a computer bot) is responsible for dealing and shuffling cards. The tables will be stored in a PostgreSQL database table and it will be possible for a human admin to add/remove/edit tables.
The game will consist of a web front end and a REST/websocket API backend. I will probably use Kubernetes and Nginx as a load balancer for the backend servers.
Onto my question. Let's say I have a single server, I could simply have it read the table list from the database and start a dealer process/thread per table. However, if I have 2 or more servers things start to get more messy.
How do I ensure that the tables are assigned in a balanced way across all servers (e.g. if there is 10 tables and 3 servers, the distribution should be roughly 3-3-4)?
How do I ensure that if a server fails, its tables get reassigned to a live server?
How do I make sure that, when a new server comes online, some existing tables get re-assigned to it so to reduce the workload of the other servers?
回答1:
I assume each state change is forwarded to players via websockets and stored into the database for persistence (just for failure recovery and some stats). So if for some reason server1 stops working and nginx starts connecting clients of table1 to server2 then it(server2) will have no problems with picking up the state of the game which was serviced by server1 before failure.
You can use hash of URI or parameter to forward all requests related to the same table to specific server.
When nginx sees that server went offline it will stop using it as a pool member and migrate all requests to another server in a consitent way.
Of course when new server comes online existing table will NOT be reassigned to the new server during the game (because you need to keep websocket connection in working state).
But when game ends you can tell clients (via existing websocket connection) to reopen new websocket connection with slightly modified URL thus forcing nginx to re-balance connections between servers.
upstream backend {
hash $request_uri consistent;
# hash $arg_table consistent;
server bj-1.card-games.com max_fails=2 fail_timeout=2s;
server bj-2.card-games.com max_fails=2 fail_timeout=2s;
server bj-3.card-games.com max_fails=2 fail_timeout=2s;
}
server {
location / {
proxy_pass http://$backend;
}
}
来源:https://stackoverflow.com/questions/57438912/how-to-distribute-card-game-table-dealers-across-servers-in-a-balanced-way