如果我想在不同的 PC 上运行两个 Lighthouse 种子节点,每个节点都应该知道另一个,我应该如何配置它们?尽管我发现提到使用多个 Lighthouse 实例并看到使用多个种子节点的非种子节点配置,但我无法在知道一个的单独 PC 上找到多个种子节点(特别是 Lighthouse)的示例其他。
我目前有这样的事情,但我不确定它是否正确。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="akka" type="Akka.Configuration.Hocon.AkkaConfigurationSection, Akka" />
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<akka>
<hocon>
<![CDATA[
lighthouse{
actorsystem: "MySystem" #POPULATE NAME OF YOUR ACTOR SYSTEM HERE
}
akka {
actor {
provider = "Akka.Cluster.ClusterActorRefProvider, Akka.Cluster"
}
remote {
log-remote-lifecycle-events = DEBUG
helios.tcp {
transport-class = "Akka.Remote.Transport.Helios.HeliosTcpTransport, Akka.Remote"
applied-adapters = []
transport-protocol = tcp
#will be populated with a dynamic host-name at runtime if left uncommented …
Run Code Online (Sandbox Code Playgroud) Akka.NET 提供了一个 F# API,它使得将 Akka actor 定义为 Akka 邮箱上的 F# 函数变得微不足道。只要参与者处理的所有消息都可以使用单个可区分联合来描述,参与者邮箱就是强类型的。问题是将所有消息定义放在单一类型(有区别的联合)中通常会使这种类型变得混乱:参与者经常响应不同类别的消息,例如远程客户端发送的消息和内部通信中使用的消息。例如,actor 可以产生内部作业并得到内部组件的通知。使用不同的(内部)类型定义这些内部消息是有道理的,但是actor的邮箱chages不能再是强类型,actor的函数如下所示:
let rec loop () =
actor {
let! message = mailbox.Receive ()
match box message with
| :? PublicMessage as msg -> handlePublicMessage msg
| :? PrivateMessage as msg -> handlePrivateMessage msg
| _ -> raise (InvalidOperationException(sprintf "Invalid message type %A" message))
return! loop ()
}
loop ()
Run Code Online (Sandbox Code Playgroud)
我在这里不喜欢的是,这种方法剥夺了 F# 的核心优势之一:类型推断。相反,我们必须将消息装箱以将它们转换为 Object 类型,然后将它们转换为我们期望的类型。
这种方法有两种替代方法:
我检查了 Akka.NET 训练营的代码,他们使用的是第一种方法 - 使用消息装箱和投射。这是可以做的最好的事情吗?
我有一个分布式演员系统,一些在 Windows 上,一些在 Linux 机器上。有时一个参与者可能需要连接其他参与者并进行一些通信。当然,也有其中一种在Windows系统上,另一种在Linux系统上的情况。
Actor 通过 ActorSelection 相互连接。问题是,当 Windows actor 尝试与 Linux 通信时,一切正常。但是当 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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
app.config 中的配置如下:
akka {
loggers = ["Akka.Logger.NLog.NLogLogger, Akka.Logger.NLog"] …
Run Code Online (Sandbox Code Playgroud) 我有点困惑如何在 .NET Core 应用程序中配置 AKKA.NET,其中 App.config 已被 project.json 替换。
AKKA.NET 还会寻找 App.Config 吗?或者我应该以某种方式将 HOCON 配置放入 project.json 中?
推荐的做法是什么?
编辑:更多的尝试和错误已验证可以将 App.config 文件添加到 .NET Core 项目并包含 hocon 部分,如下所示:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="akka" type="Akka.Configuration.Hocon.AkkaConfigurationSection, Akka" />
</configSections>
<akka>
<hocon>
<![CDATA[
akka {
actor {
serializers {
wire = "Akka.Serialization.WireSerializer, Akka.Serialization.Wire"
}
serialization-bindings {
"System.Object" = wire
}
}
}
]]>
</hocon>
</akka>
</configuration>
Run Code Online (Sandbox Code Playgroud)
我仍然想知道推荐的做法是什么。
我正在尝试将 AKKA 集成到使用 ASP.NET Core 在框架 net46 上构建的 IoT 应用程序中。我试图找到最好的方法,并希望对这个问题有任何评论,尽管它有点长。基于在 Java 和 AKKA.NET 中使用 AKKA 的经验的这两条评论都是相关的。
简而言之,我需要 AKKA.NET 从远程设备接收物联网消息并执行相当复杂的处理逻辑。
对于 IoT 通信,我们使用 Azure IoT 中心。物联网消息由多线程控制台应用程序使用,遵循 Microsoft 此处的指南:
https://azure.microsoft.com/da-dk/documentation/articles/iot-hub-csharp-csharp-process-d2c/
同时,我们正在使用依赖注入和所有最新的最佳实践运行标准的 ASP.NET Core(框架 net46)应用程序。
我需要 AKKA.NET 来接管 IOT 消费者应用程序内部进行的部分处理以及 ASP.NET 应用程序内部进行的部分处理。
我看到以下三个解决方案,我很好奇更有经验的 AKKA 开发人员会推荐哪种解决方案。我自己的直觉是解决方案 1 是首选,请参阅下面的我自己的论点:
方案一:新建一个基于AKKA.NET的Console应用,使用AKKA.Remoting与ASP.NET应用和IoT消费者应用进行通信。这意味着所有参与者逻辑都将封装在一个隔离的控制台应用程序中。当然,AKKA.NET 也将在 ASP.NET 应用程序和 IoT 消费者应用程序中引用和使用,但仅用于发送远程消息。
解决方案 2:在 ASP.NET 应用程序中直接使用 AKKA.NET,并使用 AKKA.Remoting 与 Iot 消费者应用程序进行通信。这意味着 ASP.NET 应用程序将使用 Actor 逻辑与现有的基于控制器、等待/异步等的传统 ASP.NET 逻辑并行扩展。
方案三:方案二的反面,即在IoT消费者应用内直接使用AKKA.NET,使用AKKA.Remoting与ASP.NET应用进行通信。
可能还有更多变化,例如在 ASP.NET 和 IoT 消费者应用程序中集成 AKKA.NET 逻辑,但我不喜欢在不同应用程序中运行 actor 的想法,至少在我所处的早期阶段不喜欢试图建立一个干净的新的基于演员的实现。
以下是我对解决方案 1 的论点:
有人告诉我,如果配置正确,AKKA.NET 能够以最佳方式利用所有核心,而无需上下文切换。为了能够分析和优化配置,我更喜欢为 …
我正在使用 AKKA.NET 在 .NET Core 控制台应用程序(框架 net46)中构建异步处理逻辑。
到目前为止,我已经使用内置的依赖注入来提供对我的 IDbConnection 对象(或 ApplicationDbContext for EF)的访问。这使得单元测试变得容易。
在处理从 Actor 内部访问数据库时,我非常怀疑什么是最佳实践。
一个简单的方法是编写这样的旧使用块:
using(var db = new ApplicationDbContext()) {
...query, modify and save objects using the db object
}
Run Code Online (Sandbox Code Playgroud)
并完全忽略 DI 容器。
我很想知道,在这种情况下,经验丰富的 AKKA 开发人员认为最佳实践是什么?
我有一个 IPClient 演员,它管理/拥有一个打开/关闭成本高昂的连接。
在演员处理完消息之前,我想查看演员邮箱的顶部,检查是否还有另一条消息待处理。- 如果演员还有更多工作,请保持连接打开。- 如果参与者清空了邮箱,则关闭连接。
这是我的想法的要点:
public void Handle(PollDevice message)
{
if (!_client.IsConnected)
_client.Connect();
var results = _client.GetData()
var actorHasMoreWork = Context.Dispatcher.Mailboxes.???
if (!actorHasMoreWork)
_client.Disconnect();
Sender.Tell(true);
}
Run Code Online (Sandbox Code Playgroud)
这可能吗?这是最好的方法吗?
我正在使用 Serilog,并且在关闭 Actor 系统时注意到,在删除像 Serilog 这样的自定义记录器之前,并非所有未完成的日志消息都已处理。因此,一堆消息不再发送到 Serilog 接收器,而是在默认记录器中结束。
作为一种解决方法,我在ReceiveAsync
处理程序中使用它:
await Task.Delay(TimeSpan.FromSeconds(5));
Context.System.Terminate();
Run Code Online (Sandbox Code Playgroud)
我可能可以AutoResetEvent
在非异步处理程序或 FSMOnTermination
处理程序中使用一个或类似的。
上面的解决方法只是一种解决方法。有没有办法刷新日志?请注意,在关闭 actor 系统之前我已经刷新了 Serilog,这部分工作正常。
我有使用诸如RabbitMQ
和其他消息传递技术的企业分布式系统的背景,尽管我对Actor Model
.
话虽如此,我想知道使用Actor Model
诸如AKKA
或AKKA.NET
类似的应用程序的框架是否是个好主意Whatsapp
?鉴于此类应用程序的要求(高可用性、低延迟等...)。
我的另一个问题是,Erlang 的内置 actor 模型是大公司将其用于其消息传递应用程序的原因还是我不知道的其他原因?
技术解释受到高度赞赏。提前致谢。
假设我有以下 Actor 层次结构:
user
|____A___|---E
| |---F
| |---G
|
|____B___I
|____C___J
|____D___K
Run Code Online (Sandbox Code Playgroud)
假设 Actor E 需要拥有 Actor I、J、K 的 IActorRef,如果系统扩展并需要更多 Actor,则在构造函数中传递 Actor Ref 会变得混乱,并且不建议用户在本地使用ActorSelection 。
随着系统的扩展,是否有一种适当且动态的方式来获取 ActorRef ?
我想了很多关于我是否应该问这个问题,因为它可以解释为基于意见的问题,但我真的很纠结这个问题,因为我已经搜索了很多,目前还不清楚这个问题的最佳实践是什么因为代码可能会变得非常混乱和不可读。
akka.net ×10
akka ×4
.net-core ×3
c# ×2
actor-model ×1
akka-cluster ×1
asp.net-core ×1
f# ×1
linux ×1
logging ×1
messaging ×1