Asp.net async / await Web API随机慢

时间:2018-02-01 06:01:39

标签: asp.net

我们有一个非常简单的async web api定义为 public async Task> GetOrderById(长id)。 通常情况下,它运行速度很快,可以在100毫秒内完成。但有时,生产需要5秒以上。 下图是我们跟踪的慢速调用之一(最后一列显示了服务器收到api调用时方法的以ms为单位的偏移时间)。 enter image description here

在AuthenticationAttribute类(ActionFilterAttribute的子类)中调用'RedisDataBase.StringGetAsync'方法,使用'onActionExecutingAsync'异步方式,'var user = await redisCache.TryGetAsync(sessionId)'。

因此我们怀疑在'await'关键字之后切换回Asp.net线程期间API已被临时阻止。用AuthenticationAttribute类和同步调用redis服务器的'OnActionExecuting'替换'OnActionExecutingAsync'方法后,可以消除成本。

此外,我们删除了API中的AspNetSynchronizationContext以避免不必要的上下文切换,如下所示

public async Task<ResultModel<OrderModel>> GetOrderById(long id)
    {
        var capturedContext = SynchronizationContext.Current;
        try
        {
            // Tricky, set current SynchronizationContext to null, to avoid capturing context during call await
            SynchronizationContext.SetSynchronizationContext(null);
            ...
            return new ResultModel<OrderModel>(order);
        }
        finally
        {
            // Restore the sync context
          SynchronizationContext.SetSynchronizationContext(capturedContext);
        }

然而,在callstack结束时,有时候还有几秒未知的成本。我的问题是这里发生了什么?是否有任何文章或方向我应该做进一步调查?  enter image description here

顺便说一句。目前在我们的项目中,我们仍在使用async&amp; amp;同步webapi和大多数api仍在使用同步。这是性能问题的根本原因吗?

并且,我们监控了PROD机器。它显示线程数约为120,并且有罕见的“请求排队”号码(峰值为8)。可能是由于Asp.net线程池号不足造成的吗?我们没有说明在我们的应用程序和web.config中设置线程数,而且我被告知iis 8.0的默认模式是auto,可以动态调整线程池号。

0 个答案:

没有答案