Недавно мы разработали сайт, основанный на SOA, но на этом сайте возникли проблемы с загрузкой и производительностью при загрузке. Я отвечал на вопрос, связанный этот вопрос здесь:async и ждут: они плохие?
ASP.NET website becomes unresponsive under load
Сайт сделан из API (WEB API) сайта, который размещен на кластере 4-узла и веб-сайт, который размещен на другой 4- узлового кластера и вызывает вызовы API. Оба они разработаны с использованием ASP.NET MVC 5, и все действия/методы основаны на методе async-wait.
После запуска сайта под некоторыми инструментами мониторинга, такими как NewRelic, при исследовании нескольких файлов дампа и профилирования рабочего процесса выяснилось, что при очень небольшой нагрузке (например, 16 одновременных пользователей) у нас было около 900 потоков, которые использовались 100% от процессора и заполнили очередь потоков IIS!
Несмотря на то, что нам удалось развернуть сайт в производственной среде, представив кучи кеширования и поправки к производительности, многие разработчики в нашей команде считают, что мы должны удалить все методы асинхронного сканирования и скрывать как API, так и веб-сайт в обычном веб-интерфейсе и Action, которые просто возвращают результат действия.
Я лично не доволен подходом, потому что мое чувство кишки заключается в том, что мы не использовали методы асинхронного программирования, иначе это означает, что Microsoft внедрила функцию, которая в основном довольно разрушительна и непригодна для использования!
Знаете ли вы какую-либо ссылку, которая очищает ее, где и как следует использовать/использовать методы async? Как мы должны использовать их, чтобы избежать таких драм? например Основываясь на том, что я читал в 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();
Любые примеры того, как приложение использует async/wait? При использовании с IO-связанными операциями, такими как вызовы базы данных и файловые операции, это обычно должно увеличивать масштабируемость, а не уменьшать ее. Если он порождает ненужные потоки, так что каждый метод может быть помечен как async, это, вероятно, красный флаг и, вероятно, причина ваших проблем. –
Возможно, ваш код обертывает синхронные API-интерфейсы с помощью 'Task.Run', вместо использования естественно асинхронных API? http://stackoverflow.com/q/21690385/1768303. Как правило, использование 'Task.Run' на сервере - плохая идея. – Noseratio
Это MVC 5? Или MVC 3, как говорит ваш тег? –