我们最近开发了一个基于SOA的站点,但是当它负载不足时,该站点最终出现了可怕的负载和性能问题.我在这里发布了一个与此相关的问题:
该网站由被一个4节点集群,其中托管另一个4节点集群上并且对API调用的web站点上托管的API(WEB API)位点组成.两者都是使用ASP.NET MVC 5开发的,所有操作/方法都基于async-await方法.
在一些监控工具(如NewRelic)下运行站点,调查几个转储文件并分析工作进程后,发现在非常轻的负载下(例如16个并发用户),我们最终拥有大约900个线程,这些线程利用了100%的CPU并填满了IIS线程队列!
尽管我们通过引入大量缓存和性能修正设法将网站部署到生产环境,但我们团队中的许多开发人员认为我们必须删除所有异步方法并将API和网站转换为普通的Web API和Action方法.只需返回一个Action结果.
我个人对方法不满意,因为我的直觉是我们没有正确使用异步方法,否则就意味着微软已经引入了一个基本上具有相当破坏性和无法使用的功能!
您是否知道有哪些参考文献可以清楚地知道应该/可以使用异步方法的位置和方式?我们应该如何使用它们来避免这种戏剧?例如,根据我在MSDN上阅读的内容,我认为API层应该是异步的,但网站可能是一个普通的无异步ASP.NET MVC站点.
更新:
以下是与API进行所有通信的异步方法.
public static async Task<T> GetApiResponse<T>(object parameters, string action, CancellationToken ctk)
{
using (var httpClient = new HttpClient())
{
httpClient.BaseAddress = new Uri(BaseApiAddress);
var formatter = new JsonMediaTypeFormatter();
return
await
httpClient.PostAsJsonAsync(action, parameters, ctk)
.ContinueWith(x => x.Result.Content.ReadAsAsync<T>(new[] { formatter }).Result, ctk);
}
}
Run Code Online (Sandbox Code Playgroud)
这种方法有什么愚蠢的吗?请注意,当我们将所有方法转换为非异步方法时,我们获得了更好的性能.
这是一个示例用法(我已经删除了与验证,日志记录等相关的代码的其他位.此代码是MVC操作方法的主体).
在我们的服务包装中:
public async static Task<IList<DownloadType>> GetSupportedContentTypes()
{
string userAgent = Request.UserAgent;
var parameters = new { Util.AppKey, Util.StoreId, QueryParameters = new { UserAgent …Run Code Online (Sandbox Code Playgroud)