为参与者“{actorName}”获取基于回合的并发锁在 {time} 后超时

2023-12-28

我有一个服务,可以通过某个名称创建某种类型的演员:

var storer = this.serviceClient.Create<IStorer>(new ActorId(agencyToProcess.Name));

然后我调用 Actor 的方法。

await storer.StoreStatusesAsync().ConfigureAwait(false);

在这次通话中我收到错误:

System.AggregateException:发生一个或多个错误。 ---> Microsoft.ServiceFabric.Actors.ActorConcurrencyLockTimeoutException: 为参与者“actorName”定时获取基于回合的并发锁 00:01:13.6480000 后输出。在 Microsoft.ServiceFabric.Actors.Runtime.ActorConcurrencyLock.d__17.MoveNext()

我不明白这个错误意味着什么以及如何修复它。

这个问题并不是每次都会发生。 (100 次中有 20 次)。


[ServiceDescription("Storer", ServicePrefix = "MyApp")]
public interface IStorer : IActor
{
    Task StoreStatusesAsync();
}

该服务是在 Observer 中创建的。有完整的代码可以在观察者中创建参与者。

public async void OnNext(AgencyModel agencyToProcess)
{
    try
    {
        var storer = this.serviceClient.Create<IStorer>(new ActorId(agencyToProcess.Name));

        await storer.StoreStatusesAsync().ConfigureAwait(false);
    }
    catch (Exception exception)
    {
        this.Logger.Error(exception);
    }
}

发生这种情况是因为您的服务正在尝试调用当前锁定处理另一个调用的 Actor。

从代码的外观来看,您正在基于事件触发参与者,如果连续调用针对同一参与者的两个事件,其中一个事件将等待前一个事件完成,如果前一个事件花费太长时间才能完成,则会超时抛出“ActorConcurrencyLockTimeoutException”。

这种情况并不经常发生,因为每个调用可能需要几秒钟或更短的时间来处理,但是当您有许多调用排队时,最新的调用将等待所有先前的调用按各自的顺序进行处理,并且这迟早会超时。

为了减少这些异常,您可以增加超时阈值,默认值为 60 秒,但在我看来这不是一个好主意,因为它可能会排队太多请求,并且可能无法处理所有请求,同时占用资源和连接。当服务重新平衡时,这些请求也可能会丢失。

最好的解决方案是找到一种方法来限制这些请求。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为参与者“{actorName}”获取基于回合的并发锁在 {time} 后超时 的相关文章

随机推荐