我目前正试图开始使用Akka,我面临一个奇怪的问题.我的演员有以下代码:
class AkkaWorkerFT extends Actor {
def receive = {
case Work(n, c) if n < 0 => throw new Exception("Negative number")
case Work(n, c) => self reply n.isProbablePrime(c);
}
}
Run Code Online (Sandbox Code Playgroud)
这就是我开始工作的方式:
val workers = Vector.fill(nrOfWorkers)(actorOf[AkkaWorkerFT].start());
val router = Routing.loadBalancerActor(SmallestMailboxFirstIterator(workers)).start()
Run Code Online (Sandbox Code Playgroud)
这就是我关闭所有东西的方式:
futures.foreach( _.await )
router ! Broadcast(PoisonPill)
router ! PoisonPill
Run Code Online (Sandbox Code Playgroud)
现在发生的事情是,如果我发送工具消息,其中n> 0(没有抛出异常),一切正常,应用程序正常关闭.但是,只要我发送一条导致异常的消息,应用程序就不会终止,因为仍有一个actor正在运行,但我无法弄清楚它来自哪里.
如果它有帮助,这是有问题的线程的堆栈:
Thread [akka:event-driven:dispatcher:event:handler-6] (Suspended)
Unsafe.park(boolean, long) line: not available [native method]
LockSupport.park(Object) line: 158
AbstractQueuedSynchronizer$ConditionObject.await() line: 1987
LinkedBlockingQueue<E>.take() line: 399
ThreadPoolExecutor.getTask() line: 947
ThreadPoolExecutor$Worker.run() line: 907
MonitorableThread(Thread).run() line: …Run Code Online (Sandbox Code Playgroud) 长版:
我是erlang的新手,并考虑将其用于可扩展的架构.我发现该平台的许多支持者都在宣传其可靠性和容错性.
但是,我很难准确理解在这个消息在瞬态内存中排队的系统中如何实现容错.我知道可以安排一个主管层级来重新生成已故的流程,但我一直无法找到很多关于重生工作对正在进行的工作的影响的讨论.在飞行中的消息和在垂死节点上丢失的部分完成的工作的工件会发生什么?
当消费者进程死亡时,所有生成器是否会自动重新传输未被确认的消息?如果没有,这怎么可以被认为是容错的?如果是这样的话,是什么阻止了被处理的消息 - 但不是很确认 - 被重新传输,因此不适当地重新处理?
(我认识到这些问题不是erlang独有的;在任何分布式处理系统中都会出现类似的问题.但是erlang爱好者似乎声称平台让这一切变得"简单"......?)
假设重新传输消息,我可以很容易地想象出一个复杂的消息链的下游影响在发生故障后可能变得非常混乱的情况.如果没有某种繁重的分布式事务系统,我不明白如何在不解决每个进程中的重复的情况下保持一致性和正确性.我的应用程序代码是否必须始终强制执行约束以防止事务被多次执行?
精简版:
分布式erlang进程是否受重复消息的影响?如果是这样,是重复保护(即,幂等)应用程序的责任,还是erlang/OTP以某种方式帮助我们?
我们正在Scala + Akka开发一个服务器系统,用于为Android,iPhone和Second Life的客户提供服务.此服务器的某些部分需要高度可用,在多台计算机上运行.如果其中一台服务器死亡(例如硬件故障),系统需要继续运行.我想我希望客户有一个他们将尝试连接的机器列表,类似于Cassandra的工作方式.
到目前为止,与阿卡我见过的多节点例子似乎对身边的可扩展性的理念为中心,而不是高可用性(至少在硬件方面).多节点示例似乎始终存在单点故障.比如有负载均衡,但如果我需要重新启动具有负载均衡的机器之一,我的系统会遭受一些停机时间.
是否有任何示例显示Akka的这种类型的硬件容错?或者,您是否有任何关于实现这一目标的好方法的想法?
到目前为止,我能够提出的最佳答案是研究Erlang OTP文档,冥想它们,并试图找出如何使用Akka中提供的构建块将我的系统放在一起.
但是,如果有关于如何在多台机器之间共享状态的资源,示例或想法,如果其中一台机器停机运行,我肯定会欣赏它们,因为我担心我可能会重新发明这里的轮子.也许有一个多节点STM容器可以自动保持多个节点之间的共享状态同步?或者这可能很容易使文档没有显示如何做到的例子,或者我在研究和实验中还不够彻底.任何想法或想法将不胜感激.
我已经开始使用Akka和Scala在面向总线的架构中开发一组交互组件.我需要测试系统的容错性,为此我想知道是否有任何方法可以在Scala测试框架内使用概率失效模型(即为每个Actor设置一些失败参数).有任何想法吗?那个已经实现了这个的框架?
我刚刚阅读了Hystrix指南,并试图了解默认断路器和恢复周期的运行方式,以及如何自定义其行为.
显然,如果电路跳闸,Hystrix会自动调用命令的getFallBack()方法; 我明白这一点.但是,首先使电路跳闸的标准是什么?理想情况下,在我们考虑服务离线/不健康并使断路器跳闸之前,我想尝试多次尝试支持服务(例如,最多3次尝试).我怎么能实现这个,在哪里?
但我想如果我覆盖默认的断路器,我还必须覆盖处理默认恢复期的任何机制.如果支持服务出现故障,可能是出于以下几种原因之一:
在大多数情况下,仅仅等待N秒然后再次尝试的恢复期是不够的.如果服务中有错误,或者有人在数据中心拔出了一些网线,我们将始终从此服务中获取失败.只有在少数情况下,客户服务才能在没有任何人为干预的情况下自动修复自身.
所以我想我的下一个问题部分是" 如何自定义默认恢复期策略? ",但我猜主要是:" 当服务中断并需要人工干预时,如何使用Hystrix通知devops? "
我想模拟文件系统损坏,以便测试我们的嵌入式系统如何对它做出反应,并最终使它们尽可能优雅地失败.我们使用不同类型的块设备模拟闪存存储器来经常修改并且不适合存储在NAND/NOR中的数据.
因为我非常清楚在文件树的不同部分修改数据的频率以及存储敏感数据的位置.我想在特定区域注入错误,而不仅仅是随机.
在紧急情况下,我们将其fsck -y用作最后的手段,以便尝试启动系统并报告处于非常糟糕的状态.我非常希望引发错误,这些错误会触发fsck尝试修复,以便研究对系统恢复能力的影响.
dd if=/dev/random因为它不能轻易用于注入受控错误,所以对我的目的来说不够精确.还有其他工具或方法可以更好地满足我的需求,还是我必须创造自己的?
我喜欢LWN文章"Crash-only software",我想了解更多关于崩溃安全和容错编程的知识.
令人惊讶的是,很难确保持久状态在故障情况下是一致的.在这里,我甚至不讨论分布式操作:在单个节点上也很难:如果系统崩溃,即使是正常的Berkeley DB(BDB数据存储或BDB并发数据存储)也可能有一个被破坏的数据库.不仅高级应用程序约束被破坏,如果系统崩溃,数据库可能无法正确打开.
什么是关于崩溃安全和容错设计,方法和编程的良好资源.
如果资源专注于C++和POSIX环境,我将不胜感激.
当然可以运行单个节点集群,但我想要一定程度的容错能力.
目前我可以租用两台服务器(8GB RAM,私有VLAN @ 1GigE)而不是3台服务器.
我的理解是,3个节点是Cassandra集群所需的最小节点,因为2个节点之间不可能存在大多数节点,并且解决版本控制冲突需要大多数节点.哦等等,我想到"矢量时钟"和Riak?确认!Cassandra使用时间戳来解决冲突.
对于2个节点,建议的读/写策略是什么?我通常应该写入所有(两个)节点并从ONE读取(N = 2; W = N/2 + 1; W = 2/2 + 1 = 2)?像往常一样,Cassandra会使用暗示切换,即使是2个节点,是吗?
这两台服务器位于同一数据中心FWIW中.
谢谢!