Mickael Thumerel
Mickael Thumerel

Reputation: 526

Akka.Net Clustering Simple Explanation

I try to do a simple cluster using akka.net.

The goal is to have a server receiving request and akka.net processing it through it cluster.

For testing and learning I create a simple WCF service that receive a math equation and I want to send this equation to be solved.

I have one project server and another client.

The configuration on the server side is :

<![CDATA[
      akka {
            actor {
              provider = "Akka.Cluster.ClusterActorRefProvider, Akka.Cluster"
              debug {
                receive = on
                autoreceive = on
                lifecycle = on
                event-stream = on
                unhandled = on
              }
              deployment {
                /math {
                  router = consistent-hashing-group #round-robin-pool # routing strategy
                  routees.paths = [ "/user/math" ]
                  virtual-nodes-factor = 8
                  #nr-of-instances = 10 # max number of total routees
                  cluster {
                     enabled = on
                                           max-nr-of-instances-per-node = 2
                                           allow-local-routees = off
                                           use-role = math
                  }
                }
              }
            }
            remote {
                helios.tcp {
                    transport-class = "Akka.Remote.Transport.Helios.HeliosTcpTransport, Akka.Remote"
                                    applied-adapters = []
                                    transport-protocol = tcp
                    port = 8081
                    hostname = "127.0.0.1"
                }
            }
          cluster {
              seed-nodes = ["akka.tcp://[email protected]:8081"] # address of seed node
             }

          }
  ]]>

On the Client side the configuration is like this :

 <![CDATA[
      akka {
            actor.provider = "Akka.Cluster.ClusterActorRefProvider, Akka.Cluster"
            remote {
                log-remote-lifecycle-events = DEBUG
                log-received-messages = on

                helios.tcp {
                    transport-class = "Akka.Remote.Transport.Helios.HeliosTcpTransport, Akka.Remote"
                                    applied-adapters = []
                                    transport-protocol = tcp
                    port = 0
                    hostname = 127.0.0.1
                }
            }
            cluster {
              seed-nodes = ["akka.tcp://[email protected]:8081"] # address of the seed node
              roles = ["math"] # roles this member is in
             }
            actor.deployment {
              /math {
                router = round-robin-pool # routing strategy
                routees.paths = ["/user/math"]
                nr-of-instances = 10 # max number of total routees
                cluster {
                   enabled = on
                   allow-local-routees = on
                   use-role = math
                   max-nr-of-instances-per-node = 10
                }
              }
            }
          }
  ]]>

The cluster connection seems to correctly be made. I see the status [UP] and the association with the role "math" that appeared on the server side.

Event follwing the example on the WebCramler, I don't achieved to make a message to be delivered. I always get a deadletters.

I try like this :

actor = sys.ActorOf(Props.Empty.WithRouter(FromConfig.Instance), "math");

or

var actor = sys.ActorSelection("/user/math");

Does someone know a good tutorial or could help me ? Thanks

Upvotes: 1

Views: 1335

Answers (1)

Danthar
Danthar

Reputation: 1075

Some remarks:

First: assuming your sending work from the server to the client. Then you are effectively remote deploying actors on your client. Which means only the server node needs the actor.deployment config section. The client only needs the default cluster config (and your role setting ofcourse).

Second: Try to make it simpler first. Use a round-robin-pool instead. Its much simpler. Try to get that working. And work your way up from there. This way its easier to eliminate configuration/network/other issues.

Your usage: actor = sys.ActorOf(Props.Empty.WithRouter(FromConfig.Instance), "math"); is correct.

A sample of how your round-robin-pool config could look:

deployment {
                /math {
                  router = round-robin-pool # routing strategy
                  nr-of-instances = 10 # max number of total routees
                  cluster {
                     enabled = on
                     max-nr-of-instances-per-node = 2
                     allow-local-routees = off
                     use-role = math
                  }
                }
              }

Try this out. And let me know if that helps.

Edit:

Ok after looking at your sample. Some things i changed

  • ActorManager->Process: Your creating a new router actor per request. Don't do that. Create the router actor once, and reuse the IActorRef.
  • Got rid of the minimal cluster size settings in the MathAgentWorker project
  • Since your not using remote actor deployment. I changed the round-robin-pool to a round-robin-group.

After that it worked.

Also remember that if your using the consistent-hashing-group router you need to specify the hashing key. There are various ways to do that, in your sample i think the easiest way would be to wrap the message your sending to your router in a ConsistentHashableEnvelope. Check the docs for more information.

Finally the akka deployment sections looked like this:

deployment {
                    /math {
                        router = round-robin-group # routing strategy
                        routees.paths = ["/user/math"]
                        cluster {
                           enabled = on
                           allow-local-routees = off
                           use-role = math
                        }
                     }
                  }

on the MathAgentWorker i only changed the cluster section which now looks like this:

cluster {
                  seed-nodes = ["akka.tcp://[email protected]:8081"] # address of the seed node
                  roles = ["math"] # roles this member is in
                 }

And the only thing that the ActorManager.Process does is:

 return await Program.Instance.RouterInstance.Ask<TResult>(msg, TimeSpan.FromSeconds(10));

Upvotes: 1

Related Questions