标题有点误导,让我进一步解释一下。
我有一个非线程安全的 dll,我别无选择,只能用作后端服务器的一部分。我不能直接在我的服务器中使用它,因为它的线程问题会导致它崩溃。因此,我创建了一个由 N 个节点组成的 akka.net 集群,每个节点托管一个 actor。我所有最初对那个坏 dll 的 API 调用现在都通过循环组通过消息路由到这些节点。由于每个节点只有一个单一的、单线程的参与者,我可以安全访问,但是当我有 N 个节点运行时,我得到了某种并行性。
在生产中,我auto-down = false
在心跳等方面配置了默认时间。这完美地工作。我可以根据需要启动新节点,将它们添加到组中,我可以删除它们,Cluster.Leave
这也很高兴。
我的问题是调试。在我们的开发环境中,我们保留了一个由 20 个节点组成的集群,每个节点都暴露一个如上所述的包装此 dll 的单个参与者。我们还有一组节点充当种子节点,不做任何其他事情。
当我们的应用程序运行时,它会加入集群。这允许它通过循环路由器将请求定向到我们在集群中保持的节点。在进行应用程序的开发、测试和调试时,如果我配置要使用的东西,auto-down = false
每当测试运行崩溃或我们在没有通过适当的集群离开逻辑的情况下停止应用程序时,我们最终都会遇到问题。例如当我们在调试器中使用停止按钮终止应用程序时。
如果没有自动关闭,这会给我们留下一个丢失的集群成员,导致领导者不允许添加到集群中。这意味着下次我运行该应用程序进行调试时,我无法加入集群并卡住了。
看来我必须设置自动关闭才能使调试工作。如果已设置,那么当我的应用程序崩溃时,节点会在 5 秒后从集群中删除。当我下次启动我的应用程序时,集群又回到了快乐的状态,我可以很好地加入。
这样做的问题是,如果我正在调试应用程序并暂停它任何时间,它几乎立即被视为无法访问,然后 5 秒后被抛出集群。基本上,我无法使用这些设置进行调试。
所以,我设置failure-detector.acceptable-heartbeat-pause = 600s
让我有更多时间在调试时暂停应用程序。我将在 10 分钟内关闭,但我不会经常在调试器中坐那么久,所以这是一个可以接受的权衡。这个问题当然是当我使应用程序崩溃或在调试器中停止它时,集群认为它在接下来的 10 分钟内仍然存在。没有人试图直接与这些节点对话,所以理论上这不是一个大问题,但我不断遇到我刚刚运行的测试本身被选为角色领导者的情况。所以角色领导者现在已经死了,但集群还不知道。这似乎阻止了我在 10 分钟结束之前加入集群的任何新内容。当我尝试很好地离开集群时,我的死节点卡在退出状态并且 10 分钟内没有被删除。而且我也不总是收到删除通知,
似乎没有任何方式可以说“永远不要让我成为领导者”。当我在没有为集群设置角色的情况下运行应用程序时,它似乎经常将自己选为集群领导者,这会导致与角色领导者死亡但未知但更大级别时相同的问题。
所以,我真的看不出有什么办法解决这个问题,但也许有人有一些技巧可以解决这个问题。我希望能够调试我的集群成员而不会将其从集群中抛出,但我也不希望集群认为领导节点在他们不在的时候就在附近,从而阻止我在下一次尝试时重新加入。
有任何想法吗?