我们在网站上遇到与高CPU使用率相关的性能问题.使用分析器时,我们已经确定了一个需要约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();
}
Run Code Online (Sandbox Code Playgroud)
GetTransactionByVendorTxCode方法是一个简单的实体框架调用,所以我已经排除了这一点.
有没有人有这方面的经验,或者他们是否可以看到可能导致此类问题的代码明显错误?
编辑:查看分析器提供的故障表,它表示99.6%的时间花在System.Web.Mvc.MvcHandler.BeginProcessRequest()上.
编辑:使用分析工具New Relic,它表示所有处理时间的22%用于this.sagePayTransactionManager.GetTransactionByVendorTxCode(vendorTxCode)方法.这只是包含对存储库的EF6调用.该调用确实包含谓词参数,而不是预定义条件.可能是查询没有预编译?
您可能需要考虑很多事情。
如果 GetTransactionByVendorTxCode 占总处理时间的 22%,那么您将需要简化该方法涉及的所有内容,但仍然继续解决整个处理管道中的其他瓶颈。
您说该方法抽象了对 EF6 的调用,并传入一个谓词表达式,该表达式在Where 子句中使用以构建最终查询。
如果查询很复杂,您是否考虑过委托给 StoredProcedure?由于您要返回一个实体,因此您可以将其挂在 DbSet 上。(对于 DTO,它将挂起 DbContext 的数据库属性)。
此外,您还需要查看谓词中使用的列的索引。当前的记录数是多少?您的查询会导致搜索或扫描吗?您将需要查看生成的查询计划;如果使用 SQL Server 运行查询数据库引擎优化顾问。
也许有关您当前设置的更多详细信息将有助于提供更好的指导。
| 归档时间: |
|
| 查看次数: |
704 次 |
| 最近记录: |