Akka.Linux和Windows之间的.NET远程

本文关键字:NET 远程 之间 Windows Linux Akka | 更新日期: 2023-09-27 18:02:13

我有一个参与者的分布式系统,一些在Windows上,一些在Linux机器上。有时,一个参与者可能需要连接其他参与者并进行一些通信。当然,在某些情况下,其中一个在Windows系统上,而另一个在Linux系统上。

actor通过ActorSelection相互连接。问题是,当Windows actor试图与Linux actor通信时,一切都工作正常。但是当Linux actor启动通信时,ActorSelection。ResolveOne失败。

我在这里做了一个小示例:

static void Main(string[] args)
{
    ActorSystem system = ActorSystem.Create("TestSystem");
        system.ActorOf(Props.Create(() => new ConnectActor()), "test");
        while (true)
        {
            var address = Console.ReadLine();
            if (string.IsNullOrEmpty(address))
            {
                system.Terminate();
                return;
            }
            var remoteAddress = $"akka.tcp://{system.Name}@{address}/user/test";
            try
            {
                var actor = system.ActorSelection(remoteAddress).ResolveOne(TimeSpan.FromMilliseconds(5000)).Result;
                Console.WriteLine("Resolved: " + actor.Path);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Failed: " + ex.Message);
            }
        }
}

app.config中的配置如下:

akka {
          loggers = ["Akka.Logger.NLog.NLogLogger, Akka.Logger.NLog"]
          suppress-json-serializer-warning = on
          loglevel = "DEBUG"
          log-config-on-start = on
          actor {
            provider = "Akka.Remote.RemoteActorRefProvider, Akka.Remote"
            debug {
              receive = on
              autoreceive = on
              lifecycle = on
              event-stream = on
              unhandled = on
            }
          }
          remote {    
            log-remote-lifecycle-events = DEBUG
            log-received-messages = on
            helios.tcp {
                transport-class = "Akka.Remote.Transport.Helios.HeliosTcpTransport, Akka.Remote"
                transport-protocol = tcp
                applied-adapters = []
                port = 9000
                hostname = "0.0.0.0"
                public-hostname = "192.168.0.251" // This is different for different hosts, of course
            }
         }
      }

public-hostname是公开可用的ip地址。

下面是一些例子:

  • 当运行Windows/Windows时,两个实例看到对方(我给他们远程地址-他们输出"Resolved")
  • 当运行Windows/Linux时,将Linux actor的地址给Windows actor,它输出"Resolved"。所以windows连接linux没有问题。在此之后,将windows actor的地址给linux actor也给出了"Resolved"-我想,连接已经建立并且没有真正的握手传递
  • 但是当运行windows/Linux并将windows actor的地址提供给Linux actor时,它给出"Failed"。没有关于任何错误或丢弃包的消息。在日志的末尾有如下内容:

Akka.Remote.Transport。AkkaProtocolManager|现在正在监督akka://TestSystem/system/transport/AkkaProtocolManager .tcp.0/akkaProtocol-tcp%3A%2F%2FTestSystem%40%5B%3A%3Affff% 3a192.168.0.252% 5D%3A36983-1||||13:20:08.3766 | DEBUGAkka.Remote.Transport。ProtocolStateActor开始(Akka.Remote.Transport.ProtocolStateActor) | | | | |13:20:08.3922 | |调试Akka.Remote.Transport.ProtocolStateActor |停止了| | | |

类似日志的问题描述如下:Akka.net启动和停止没有活动原因是系统协议不兼容。这是同一个问题吗?我从阿卡来的。NET文档和发行说明,它有完整的linux支持…

那么,我在配置中遗漏了什么吗?有人能使这个样本工作与Linux -> Windows连接?

Akka.Linux和Windows之间的.NET远程

这里的问题似乎是Mono由于某种原因在其绑定地址中使用映射到IPV4的IPV6地址。

akka://TestSystem/系统/传输/akkaprotocolmanager.tcp.0/akkaProtocol-tcp % % 2 f % 2 3 3 ftestsystem % 40% 5 b % % 3 affff % 3 a192.168.0.252 % 5 d % 3 a36983-1

如果你解码这个URL它被翻译成

akkaProtocol-tcp://TestSystem@[::飞行符:192.168.0.252]:36983 -

所以我认为这里发生的事情是Helios应该解析的出站地址在Linux端被搞砸了,所以它试图连接到一个与Windows侦听的不一样的错误格式的地址。我怀疑参与者选择URI解析代码中特定于平台的某些内容是不正确的。

我在这里提交了一个bug: https://github.com/akkadotnet/akka.net/issues/2254