在应用程序的负载测试期间(使用动态负载报告服务),整个应用程序停止工作,因为有状态分区的一个副本会发出警告。
Warning System.RAP IStatefulServiceReplica.ChangeRole(S)Duration Thu, 21 Jul 2016 3:36:03 GMT Infinity 131135817636324745 false false Start Time (UTC): 2016-07-21 13:35:43.632
这是在副本的负载平衡之后发生的,这发生在分区的第4个副本上,尽管我们只针对3.所以即使SF只是杀了它,应用程序应该没问题(因为主要和其他2个辅助设备都是)。然而整个事情都堵塞了。 (从记录中我可以看到至少还有10k事件需要处理,但整个事情都停止了)
在上面的图片中,您可以看到特定副本的详细信息。此副本与其他辅助副本之间的唯一区别在于以下值:
我也觉得奇怪的是副本状态说:准备就绪而不是重新配置。由于读/写状态表明它仍在重新配置 我正在运行最新的SDK(2.1.163,发布于2016年7月18日)。我认为错误修正在那里,但尽管它变得更难以重现它仍然发生。有谁知道可能导致这种情况的原因或如何解决这个问题?
在Vaclav的响应之后,我开始记录RunAsync中的所有内容,以确定实际导致问题的原因。因此,如果请求取消,代码的哪一部分不会退出。正如瓦茨拉夫指出,当要求取消时,该方法并没有停止。然而,似乎卡在其中的代码部分是本机Service Fabric。
using(ITransaction tx = StateManager.CreateTransaction())
{
await queue.TryDequeueAsync(tx, _queueTimeout, cancellationToken);
await tx.CommitAsync();
}
队列是ReliableQueue,超时设置为默认值4秒,cancelationtoken来自RunAsync。在每行之间添加日志记录后,我们得到了以下日志记录模式
//pre transaction
using(ITransaction tx = StateManager.CreateTransaction())
{
//pre dequeue
await queue.TryDequeueAsync(tx, _queueTimeout, cancellationToken);
//dequeued
await tx.CommitAsync();
//committed
}
//post transaction
在每一行我都记录了cancelationrequest的值,并且当取消请求被触发时,后台任务将记录。结果我们得到了这样的例子:
pre transaction: False
predequeue: False
dequeued: False
CancelationTokenFired: True
精确位置可能会有所不同,但CancelationTokenFired之前的最后一个日志始终为
如前所述,这是在最新的SDK(18-7-2016)上完成的,该SDK据称对类似问题进行了错误修复。问题也出现在较旧的SDK上,当时甚至更频繁。但即使在新版本上,每次运行仍然可以重现。
答案 0 :(得分:6)
此警告表示当您的服务的主副本在重新配置期间更改角色时,您的服务不会退出RunAsync(请查看上一屏幕截图中的运行状况警告)。确保在每个可能的代码路径中遵守该取消令牌。这也适用于通信侦听器 - 确保它们响应CloseAsync()。
鉴于你所说的,这里最有可能发生的事情:
重新配置完成后,您的副本集大小将减少到目标值3。
我们不会因为我们不知道你的应用程序会好起来而杀了你的慢复制品 - 也许它需要很长时间来安全处理有价值的数据 - 我们不会知道。 Service Fabric对安全性非常偏执,并且不会做任何可能导致您的服务丢失数据的事情。
不幸的是,Service Fabric Explorer没有显示重新配置状态,它显示了预期的最终结果。但是如果在PowerShell中运行Get-ServiceFabricPartition,它将显示分区的重新配置状态。
答案 1 :(得分:0)
我已经看过很多了,并且已经把头撞在砖墙上一段时间了。
然而,请查看最新版本 - 5.1.163和2.1.163 - 这似乎已经解决了我的问题。