长期分析 ASP.net 应用程序?

Posted

技术标签:

【中文标题】长期分析 ASP.net 应用程序?【英文标题】:Profiling ASP.net applications over the long term? 【发布时间】:2013-08-09 18:31:32 【问题描述】:

检测网站记录执行统计数据的公认方法是什么?

X 需要多长时间

例如,我想知道执行某些操作需要多长时间,例如使用 Active Directory 服务器验证用户的凭据:

authenticated = CheckCredentials(Login1.UserName, Login1.Password);

很多人会建议使用各种类型的 Tracing 来输出、记录或记录有趣的性能指标:

var sw = new System.Diagnostics.Stopwatch();
sw.Start();
authenticated = CheckCredentials(Login1.UserName, Login1.Password);
sw.Stop();

//write a number to a log
WriteToLog("TimeToCheckCredentials", sw.ElapsedTicks);

不是 X;全部 X

问题在于,我对根据 Active Directory 验证用户凭据需要多长时间不感兴趣。我对在 ActiveDirectory 中验证数千个用户凭据需要多长时间感兴趣:

var sw = new System.Diagnostics.Stopwatch();
sw.Start();
authenticated = CheckCredentials(Login1.UserName, Login1.Password);
sw.Stop();

timeToCheckCredentialsSum = timeToCheckCredentialsSum + sw.ElapsedTicks;
timeToCheckCredentialsCount = timeToCheckCredentialsCount + 1;
if ((sw.ElapsedTicks < timeToCheckCredentialMin) || (timeToCheckCredentialMin == 0))
   timeToCheckCredentialMin = sw.ElapsedTicks;
if ((sw.ElapsedTicks > timeToCheckCredentialMax) || (timeToCheckCredentialMax == 0))
   timeToCheckCredentialMax = sw.ElapsedTicks;
oldMean = timeToCheckCredentialsAverage;
newMean = timeToCheckCredentailsSum / timeToCheckCredentialsCount;
timeToCheckCredentialsAverage = newMean;

if (timeToCheckCredentailsCount > 2)

   timeToCheckCredentailsVariance = (
         ((timeToCheckCredentialsCount -2)*timeToCheckCredentailsVariance  + (sw.ElapsedTicks-oldMean)*(sw.ElapsedTicks-newMean))
         / (timeToCheckCredentialsCount -1))

else
    timeToCheckCredentailsVariance = 0;

有很多样板代码可以很容易地抽象成:

var sw = new System.Diagnostics.Stopwatch();
sw.Start();
authenticated = CheckCredentials(Login1.UserName, Login1.Password);
sw.Stop();

//record the sample
Profiler.AddSample("TimeToCheckCredentials", sw.ElapsedTicks);

这仍然是很多样板代码,可以抽象成:

Profiler.Start("TimeToCheckCredentials");
authenticated = CheckCredentials(Login1.UserName, Login1.Password);
Profiler.Stop("TimeToCheckCredentials");

现在我在内存中有一些统计数据。我可以让网站运行几个月,并且在任何时候我都可以连接到服务器并查看分析统计信息。这正是 SQL Server 在各种报告中呈现其自身运行历史的能力:

但是 ASP 会在没有警告的情况下杀死应用程序

问题在于这是一个 ASP.net 网站/应用程序。在一年的过程中,网络服务器会随机决定通过回收应用程序池来关闭应用程序:

可能已经闲置了 3 周 可能已达到最大回收时间限制(例如 24 小时) 可能文件的日期已更改,网络服务器必须重新编译应用程序

当网络服务器决定关闭时,我的所有统计信息都会丢失。

是否有任何 ASP.net 性能/仪器框架可以解决这个问题?

尝试持久化到 SQL Server

我考虑将我的统计信息存储在 SQL Server 中。就像 ASP.net 会话状态可以在每个请求完成后存储在 SQL Server 中一样,我每次都可以将我的值存储在 SQL Server 中:

void AddSample(String sampleName, long elapsedTicks)

    using (IDbConnection conn = CreateDatabaseConnection())
    
        ExecuteAddSampleStoredProcedure(conn, sampleName, elapsedTicks);
    

除了现在我在我的应用程序中引入了巨大的延迟。该分析代码每秒被调用数千次。当仅在内存中执行数学运算时,它需要几微秒。现在它需要几十毫秒。 (1,000 的系数;明显的延迟)。那是行不通的。

仅在应用程序关闭时保存

我已经考虑通过实现IRegisteredObject 将我的静态助手类注册到 ASP.net 托管环境:

public class ShutdownNotification : IRegisteredObject

    public void Stop(Boolean immediate)
    
        Profiler.SaveStatisticsToDatabase();
     

但我很好奇解决这个问题的正确方法是什么。比我聪明的人之前一定在 ASP.net 中添加了分析。

【问题讨论】:

很有趣。我喜欢你在这里尝试做的事情。您是否可以考虑将分析诊断移植到“单独的应用程序”中,然后使用消息传递框架(例如 RabbitMQ)来确保您的配置文件日志不会丢失。我猜也可以像这样为多个应用程序提供服务。 :) 【参考方案1】:

为此,我们使用 Microsoft 的应用程序性能监控。它捕获页面加载时间、数据库调用时间、API 调用时间等。当页面加载意外缓慢时,它还会提醒我们并提供堆栈跟踪以及影响加载时间的各种调用的时间。这有点简陋,但它可以解决问题,让我们能够验证我们没有任何不符合预期的变化。

提前警告:UI 仅适用于 IE。

http://technet.microsoft.com/en-us/library/hh457578.aspx

【讨论】:

以上是关于长期分析 ASP.net 应用程序?的主要内容,如果未能解决你的问题,请参考以下文章

远程分析 ASP.net 应用程序?

Azure 中的 ASP.NET WebApp 使用大量 CPU

ASP.NET 性能分析 404/500 错误

如何对正在运行的 ASP.NET 应用程序进行非侵入式分析?

Asp.net Core 中的内存使用限制

在 ASP.NET Core 中使用托管服务实现后台任务