我使用Akka.Cluster创建了两个单独的控制台应用程序,一个是服务器,另一个是客户端。
我想使用多个客户端应用程序分布式执行消息。
当我同时运行两个应用程序时,出现以下错误:
在EndpointWriter中为[akka.tcp://ClusterSystem@127.0.0.1:52635]缓存的邮件。您可能应该实施流控制,以避免淹没远程连接。
这是我的服务器。hocon
akka {
actor.provider = cluster
actor.deployment {
/tasker {
router = consistent-hashing-group
routees.paths = ["/user/api"]
virtual-nodes-factor = 8
cluster {
enabled = on
max-nr-of-instances-per-node = 2
allow-local-routees = off
use-role = tracker
}
}
}
remote {
dot-netty.tcp {
port = 8081
hostname = localhost
}
}
cluster {
seed-nodes = ["akka.tcp://akkatest@192.168.1.117:8081", "akka.tcp://akkatest@192.168.1.17:8081"] # address of seed node
roles = ["akkatest"] # roles this member is in
role.["akkatest"].min-nr-of-members = 3 # crawler role minimum node count
}
}
这是我的客户。hocon
akka {
actor {
provider = cluster
deployment {
/tasker {
router = round-robin-pool
nr-of-instances = 2
// routees.paths = ["/user/tasker"]
// virtual-nodes-factor = 8
}
}
}
remote {
dot-netty.tcp {
hostname = "127.0.0.1"
port = 0
maximum-frame-size = 256000b
}
}
cluster {
#will inject this node as a self-seed node at run-time
seed-nodes = ["akka.tcp://ClusterSystem@localhost:12345"]
roles = ["tasker"]
}
}
服务器代码
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Akka Server Started.");
var actor = StartServer();
//StartNormalProcess();
Console.ReadLine();
InjectActor(actor);
Console.ReadLine();
}
public static IActorRef StartServer()
{
Config config = Utility.ParseConfig("server.hocon");
ActorSystem actorSystem = ActorSystem.Create("ClusterSystem", config);
//var router = actorSystem.ActorOf(Props.Empty.WithRouter(FromConfig.Instance), "tasker");
IActorRef myActor = actorSystem.ActorOf(Props.Empty.WithRouter(FromConfig.Instance), "tasker");
//var props = Props.Create<MyActor>(); //.WithRouter(new RoundRobinPool(5));
//IActorRef myActor = actorSystem.ActorOf(props, "myactor");
return myActor;
}
public static void InjectActor(IActorRef actor)
{
Console.WriteLine("Injecting actor");
int n = 200000;
Random random = new Random();
for (int i = 1; i <= n; i++)
{
var tradeData = new TradeData
{
UserId = i,
Qty = random.Next(1000, 5000),
Rate = random.Next(100, 1000)
};
actor.Tell(tradeData);
}
}
public static void StartNormalProcess()
{
new Process().ProcessData();
}
}
客户代码
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Akka Client Started.");
StartClient();
Console.ReadLine();
}
public static void StartClient()
{
//Config config = Utility.ParseConfig("client.hocon");
//ActorSystem actorSystem = ActorSystem.Create("ClusterSystem", config);
//var router = actorSystem.ActorOf(Props.Empty.WithRouter(FromConfig.Instance), "tasker");
//var props = Props.Create<MyActor>(); //.WithRouter(new RoundRobinPool(5));
//IActorRef myActor = actorSystem.ActorOf(props, "myactor");
Config config = Utility.ParseConfig("client.hocon");
ActorSystem actorSystem = ActorSystem.Create("ClusterSystem", config);
IActorRef myActor = actorSystem.ActorOf(Props.Empty.WithRouter(FromConfig.Instance), "tasker");
}
}
MyActor.cs
public class MyActor : UntypedActor
{
protected Cluster cluster = Cluster.Get(Context.System);
protected override void OnReceive(object message)
{
var up = message as ClusterEvent.MemberUp;
if (up != null)
{
var mem = up;
//Become(mem);
Console.WriteLine("Member is Up: {0}", mem.Member);
}
else if (message is ClusterEvent.UnreachableMember)
{
var unreachable = (ClusterEvent.UnreachableMember)message;
Console.WriteLine("Member detected as unreachable: {0}", unreachable.Member);
}
else if (message is ClusterEvent.MemberRemoved)
{
var removed = (ClusterEvent.MemberRemoved)message;
Console.WriteLine("Member is Removed: {0}", removed.Member);
}
else if (message is ClusterEvent.IMemberEvent)
{
//IGNORE
}
else if (message is ClusterEvent.CurrentClusterState)
{
}
else if (message is TradeData)
{
TradeData tradeData = message as TradeData;
double price = new Process().getTradePrice(tradeData.Qty, tradeData.Rate);
string logMessage = "Trade Price for UserId: {0} is Qty({1}) * Rate({2}) = {3} -- Process executed by Worker: {4}";
logMessage = String.Format(logMessage, tradeData.UserId, tradeData.Qty, tradeData.Rate, price, Context.Self.Path.Name);
Console.WriteLine(logMessage);
}
else
{
Unhandled(message);
}
}
protected override void PreRestart(Exception reason, object message)
{
cluster.Subscribe(Self, ClusterEvent.InitialStateAsEvents, new[] { typeof(ClusterEvent.IMemberEvent), typeof(ClusterEvent.UnreachableMember) });
}
protected override void PostRestart(Exception reason)
{
base.PostRestart(reason);
}
protected override void PreStart()
{
cluster.Subscribe(Self, ClusterEvent.InitialStateAsEvents, new[] { typeof(ClusterEvent.IMemberEvent), typeof(ClusterEvent.UnreachableMember) });
Console.WriteLine("Cluster Subscribed");
}
protected override void PostStop()
{
cluster.Unsubscribe(Self);
Console.WriteLine("Cluster Unsubscribed");
}
protected override void Unhandled(object message)
{
base.Unhandled(message);
}
}
请帮助我了解如何在多个客户端应用程序中分布式执行消息。