Мы испытываем проблемы с производительностью на нашем веб-сайте, связанные с высоким уровнем использования процессора. При использовании профилировщика мы определили конкретный метод, который возвращает ~ 35 секунд.
Это метод обратного вызова при использовании платежного шлюза SagePay.
Я скопировал два метода, которые являются частью этого вызова ниже:
public void SagePayNotificationReturn()
{
string vendorTxCode = Request.Form["vendortxcode"];
var sagePayTransaction = this.sagePayTransactionManager.GetTransactionByVendorTxCode(vendorTxCode);
if (sagePayTransaction == null)
{
// Cannot find the order, so log an error and return error response
int errorId = this.exceptionManager.LogException(System.Web.HttpContext.Current.Request, new Exception(string.Format("Could not find SagePay transaction for order {0}.", vendorTxCode)));
ReturnResponse(System.Web.HttpContext.Current, StatusEnum.ERROR, string.Format("{0}home/error/{1}", GlobalSettings.SiteURL, errorId), string.Format("Received notification for {0} but the transaction was not found.", vendorTxCode));
}
else
{
// Store the response and respond immediately to SagePay
sagePayTransaction.NotificationValues = sagePayTransactionManager.FormValuesToQueryString(Request.Form);
this.sagePayTransactionManager.Save(sagePayTransaction);
ReturnResponse(System.Web.HttpContext.Current, StatusEnum.OK, string.Format("{0}payment/processtransaction/{1}", GlobalSettings.SiteURL, vendorTxCode), string.Empty);
}
}
private void ReturnResponse(HttpContext context, StatusEnum status, string redirectUrl, string statusDetail)
{
context.Response.Clear();
context.Response.ContentEncoding = Encoding.UTF8;
using (StreamWriter streamWriter = new StreamWriter(context.Response.OutputStream))
{
streamWriter.WriteLine(string.Concat("Status=", status.ToString()));
streamWriter.WriteLine(string.Concat("RedirectURL=", redirectUrl));
streamWriter.WriteLine(string.Concat("StatusDetail=", HttpUtility.HtmlEncode(statusDetail)));
streamWriter.Flush();
streamWriter.Close();
}
context.ApplicationInstance.CompleteRequest();
}
Метод GetTransactionByVendorTxCode - это простой вызов Entity Framework, поэтому я решил это.
Есть ли у кого-нибудь какой-либо опыт в этом или они могут увидеть что-то очень плохое с кодом, который может вызвать такую проблему?
РЕДАКТИРОВАТЬ. Рассматривая таблицу разбивки, предоставленную профилировщиком, говорится, что 99,6% времени тратится на System.Web.Mvc.MvcHandler.BeginProcessRequest().
EDIT: Используя инструмент профилирования New Relic, он говорит, что 22% всего времени обработки расходуется в методе this.sagePayTransactionManager.GetTransactionByVendorTxCode(vendorTxCode). Это просто содержит вызов EF6 в репозиторий. Вызов содержит предикатный параметр, а не предопределенное условие. Может быть, запрос не компилируется?