Występują problemy z wydajnością na naszej stronie związane z wysokim wykorzystaniem procesora. Podczas korzystania z profilera zidentyfikowaliśmy konkretną metodę, która zajmuje około 35 sekund.Powiadomienie SagePay (gateway płatności) w aplikacji ASP.Net MVC zwraca długi czas.
Jest to metoda oddzwonienia, gdy używana jest bramka płatności o nazwie SagePay.
mam skopiowane dwie metody, które są częścią tej rozmowy poniżej:
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();
}
Sposób GetTransactionByVendorTxCode jest proste wezwanie Entity Framework, więc już orzekł, że na zewnątrz.
Czy ktoś ma w tym jakieś doświadczenie lub czy widzi coś rażąco nie tak z kodem, który mógłby spowodować taki problem?
EDYCJA: Patrząc na tabelę podziału dostarczone przez profilera, mówi, że 99,6% czasu spędza w System.Web.Mvc.MvcHandler.BeginProcessRequest().
EDYCJA: Używając narzędzia do profilowania New Relic, mówi, że 22% całego czasu przetwarzania jest wydawane w metodzie this.sagePayTransactionManager.GetTransactionByVendorTxCode (vendorTxCode). Jest to po prostu zawierające wywołanie EF6 do repozytorium. Wywołanie zawiera jednak parametr predykatu, a nie predefiniowany warunek. Czy to możliwe, że zapytanie nie jest wstępnie skompilowane?
"Proste wywołanie Entity Framework" - Jesteś pewien? jaki jest kod? –
Spójrz na to pytanie/odpowiedź i dodaj kod writeline debugowania do Application_BeginRequest: http://stackoverflow.com/a/17073158/82333 –
Zmień wywołanie GetTransactionByVendorTxCode na fałszywą konstrukcję danych i zobacz, czy czas reakcji zmienia się drastycznie . Jeśli tak, to masz wąskie gardło, jeśli nie czas na inne miejsce. – Bardo