Distributed TCP system with Akka

akka
java
akka-cluster

#1

I am looking at designing a game server which uses TCP around the use of Akka for distributing the components across multiple systems.

I plan to use Netty as the TCP frontend in which users connect to and then Akka as the backend communication system to distribute parts.

Imagine this:

A TCP frontend can be put online anywhere, it could be the same server or a different server. Once online the Akka system communicates that it is part of the system (somehow). What approach can I take to do this? In my experience in Microservices I would have a discovery service in which the node is aware of to say “Hey! I am available!”. Is a discovery service available with Akka?

The next challenge is, If a user 1 is at Node 1 but a packet needs to route to Node 2 to user 2. What is an efficient way of telling the “PlayerActor” (should be named PlayerManagerActor really) that I need to locate where user 2 is. I thought of maybe using distributed data where each has a copy of where players are stored or I just simple broadcast a message to all the nodes and ones where the user doesn’t exist are ignored.

Hopefully someone can point me in the right direction.

Many thanks


(Patrik Nordwall) #2

What exists is the discovery in Akka Management. It’s mainly used for discovering other nodes for joining a cluster at the moment, but it’s scope might be expanded to service discovery later.

If you model each user as an actor, and there should only be one such actor per user somewhere in the cluster then Cluster Sharding is probably a perfect fit.


#3

Thanks! That makes perfect sense. Yes a user actor should only exist once somewhere as if I run multiple end points which are load balanced then I can’t say have a user placed on another node otherwise the socket would become detached.

So I can just start up multiple instances of my app which means multiple nodes and just use Cluster Sharding to send data between players.


(Patrik Nordwall) #4

You want the user actor to be located on the node where the websocket is. Then Cluster Sharding will not work because you don’t have that control of where the actor is located. It’s decided by Cluster Sharding via your shard hashing and allocation strategy of shards (shard = many actors).

Instead you have to do something like you suggested with Distributed Data or broadcast. Distributed PubSub might be a good alternative, using the Send. Both Distributed Data and Distributed PubSub have limitations to how many actors you can register there, which might be a problem if this is a popular game :)


#5

Thanks for your help. I believe I can come up with a way. The nature of my game means I can simply split areas of the game up into multiple actors to handle each area.

One thing which is confusing now is game tick rates. The server needs to handle say 20 ticks per second so running every 50ms.

If I schedule a “Tick” message to my Actor every 50ms - this could risk of other messages not being processed until later as the nature of Actors only processing a single message at a time.

I take it would be better to have a “TickActor” which handles the ticks and the Supervisor being the game area?

Making a thread that loops inside the Actor would be against how actors handle concurrency right.