Service Fabric状态服务中的System.TimeoutException。在ITransaction.CommitAsync方法

时间:2017-11-02 22:46:06

标签: azure-service-fabric

我有一个使用IReliableConcurrentQueue存储状态的有状态服务。我正在使用无状态ASP.NET核心服务来公开两个REST端点。

GET端点从指定的IReliableConcurrentQueue获取指定数量的项目。它还会在返回之前写入同一事务中的单独可靠并发队列。 POST端点接收项目列表并将它们添加到IReliableConcurrentQueue。

当我在调试模式下从本地运行Visual Studio服务时,当我反复点击一个端点(GET或POST)时,它可以正常工作而没有任何问题。

当我同时点击两个端点时,经过3或4次点击(有时是10次)后,服务停止响应,我看到超时例外。

REST端点(无状态服务)

[HttpGet]
[Route("{number}/{queueName}")]
public async Task<IEnumerable<QueueItem>> Get(int number, string queueName)
{        
    IEnumerable<QueueItem> items = await statefulServiceProxy.GetItems(number, queueName);
    return items;
}

[HttpPost]
[Route("item")]
public async Task Set([FromBody]IEnumerable<Item> items)
{
    await statefulServiceProxy.SetItem(items);
}

有状态服务

始终陷入ReadAndLockItems()或SetItem()中的CommitAsync函数。

public async Task<IEnumerable<QueueItem>> GetItems(int number, string queueName)
{
    var items = await this.ReadAndLockItems(number, queueName);
    return items;
}

private async Task<IEnumerable<QueueItem>> ReadAndLockItems(int number, string queueName)
{
    var itemQueue = await this.StateManager.GetOrAddAsync<IReliableConcurrentQueue<QueueItem>>(queueName);
    var lockQueue = await this.StateManager.GetOrAddAsync<IReliableConcurrentQueue<QueueItem>>("LockQueue");
    List<QueueItem> results = new List<QueueItem>();

    using (var tx = this.StateManager.CreateTransaction())
    {
        for (int i = 0; i < number; i++)
        {
            var element = await itemQueue.TryDequeueAsync(tx);
            if (element.HasValue)
            {
                results.Add(element.Value);
            }
        }

        results.ToList().ForEach(async r =>
        {
            await lockQueue.EnqueueAsync(tx, r);
        });

        await tx.CommitAsync();     // This is where it gets stuck.
    }

    return results;
}

public async Task SetItem(IEnumerable<Product> products)
{ 
    var productQueue = await this.StateManager.GetOrAddAsync<IReliableConcurrentQueue<Product>>("ProductQueue");
    using (var tx = this.StateManager.CreateTransaction())
    {
        foreach (Product p in products)
        {
            await productQueue.EnqueueAsync(tx, p);
        }

        await tx.CommitAsync(); // Sometimes it gets stuck here. It's not consistent. Either in this function or the above one.
    }
}

我检查了这个Post并尝试了那里提到的更改。它还不起作用。

例外详情:

System.TimeoutException: This can happen if message is dropped when service is busy or its long running operation and taking more time than configured Operation Timeout.
   at Microsoft.ServiceFabric.Services.Communication.Client.ServicePartitionClient`1.<InvokeWithRetryAsync>d__24`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---

我使用收藏品和相关交易的方式有什么问题吗?

0 个答案:

没有答案