Недавно мы разработали сайт, основанный на SOA, но этот сайт столкнулся с ужасными проблемами загрузки и производительности, когда он перешел под нагрузку. Я разместил вопрос, связанный с этой проблемой здесь:
Веб-сайт ASP.NET становится неактуальным при загрузке
Сайт создан на веб-сайте API (WEB API), который размещен в кластере 4- node и веб-сайте, который размещен в другом кластере 4 node и вызывает вызовы API. Оба они разработаны с использованием ASP.NET MVC 5, и все действия/методы основаны на методе асинхронного ожидания.
После запуска сайта под некоторыми инструментами мониторинга, такими как NewRelic, при исследовании нескольких файлов дампов и профилирования рабочего процесса выяснилось, что при очень небольшой нагрузке (например, 16 одновременных пользователей) у нас было около 900 потоков, которые использовали 100 % от процессора и заполнил очередь потоков IIS!
Несмотря на то, что нам удалось развернуть сайт в производственной среде, представив кучи кеширования и поправки к производительности, многие разработчики в нашей команде считают, что нам нужно удалить все асинхронные методы и скрывать как API, так и веб-сайт для обычного веб-API и Методы действий, которые просто возвращают результат действия.
Мне лично не нравится подход, потому что мое чувство кишки состоит в том, что мы не использовали методы асинхронизации должным образом, иначе это означает, что Microsoft внедрила функцию, которая в основном довольно разрушительна и непригодна для использования!
Знаете ли вы какую-либо ссылку, которая очищает ее, где и как можно использовать/асинхронные методы? Как мы должны использовать их, чтобы избежать таких драм? например Основываясь на том, что я читал в MSDN, я считаю, что уровень API должен быть асинхронным, но веб-сайт может быть обычным сайтом без ASP.NET MVC.
Update:
Вот асинхронный метод, который делает все связи с 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();