我們最近開發了基於SOA的網站,但這個網站最後不得不可怕的負載和性能問題時,它負載下去。我張貼有關這個問題在這裏一個問題:異步並等待:它們不好嗎?
ASP.NET website becomes unresponsive under load
該網站由被4個節點的集羣,這是另一個4-託管的網站上託管的API(WEB API)網站節點集羣並調用API。兩者都是使用ASP.NET MVC 5開發的,所有操作/方法都基於異步等待方法。
在一些監控工具(如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);
}
}
這種方法有什麼愚蠢的東西嗎?請注意,當我們將所有方法轉換爲非異步方法時,我們獲得了更好的性能。
下面是一個示例用法(我剪掉了與驗證,日誌記錄等有關的代碼的其他部分。此代碼是MVC操作方法的主體)。
在我們服務的包裝:
public async static Task<IList<DownloadType>> GetSupportedContentTypes()
{
string userAgent = Request.UserAgent;
var parameters = new { Util.AppKey, Util.StoreId, QueryParameters = new { UserAgent = userAgent } };
var taskResponse = await Util.GetApiResponse<ApiResponse<SearchResponse<ProductItem>>>(
parameters,
"api/Content/ContentTypeSummary",
default(CancellationToken));
return task.Data.Groups.Select(x => x.DownloadType()).ToList();
}
而且在行動:
public async Task<ActionResult> DownloadTypes()
{
IList<DownloadType> supportedTypes = await ContentService.GetSupportedContentTypes();
有關應用程序如何使用async/await的任何示例?當與IO綁定操作(如數據庫調用和文件操作)一起使用時,通常應該提高可伸縮性,而不是降低它。如果它產生了不必要的線程,那麼每個方法都可以標記爲異步,這可能是一個紅旗,可能是你的問題的原因。 –
也許,你的代碼使用'Task.Run'封裝同步API,而不是使用自然的異步API? http://stackoverflow.com/q/21690385/1768303。通常,在服務器上使用'Task.Run'是個不錯的主意。 – Noseratio
是MVC 5嗎?或者你的標籤說MVC 3? –