我编写了一个自定义HttpModule,它实现了Application_PreRequestHandlerExecute和Application_PostRequestHandlerExecute事件,以便记录所有请求时间。我正在尝试使用此HttpModule来检测MVC Web应用程序,以将所有请求的性能记录到其中。 MVC Web应用程序使用Http Session,超时设置为默认的20分钟。我们有一套JMeter负载测试,在我的HttpModule之前运行正常。但是,当我检测应用程序时,在JMeter运行其测试20分钟后,它会开始在整个地方抛出错误,表明所有会话变量都已被删除。
为什么会这样?我在HttpModule中根本没有访问会话状态,所以我对可能造成这种情况的原因感到茫然。这是自定义HttpModule的完整代码。似乎仅仅存在这个HttpModule会导致配置为使用它的任何应用程序出现会话超时问题。
public class LoggerModule : IHttpModule
{
public void Dispose()
{
}
public void Init(HttpApplication context)
{
if (context == null)
{
return;
}
// Using PreRequestHandlerExecute/PostRequestHandlerExecute instead of BeginRequest/EndRequest
// from: http://stackoverflow.com/questions/12981298/how-to-analyze-the-performance-of-requests-in-asp-net-mvc-application
// NOTE: The Web.config for each application should be configured with preCondition="managedHandler". See
// http://stackoverflow.com/questions/18989449/how-does-precondition-managedhandler-work-for-modules.
// TL;DR is that this HttpModule will only run for managed resources like MVC endpoints, .aspx requests, etc. and won't run for static files.
context.PreRequestHandlerExecute += this.Application_PreRequestHandlerExecute;
context.PostRequestHandlerExecute += this.Application_PostRequestHandlerExecute;
}
private void Application_PreRequestHandlerExecute(object sender, EventArgs e)
{
// Store the current time in order to determine the time taken to process each request.
(sender as HttpApplication).Context.Items["PerformanceLoggerStart"] = DateTime.Now;
}
private void Application_PostRequestHandlerExecute(object sender, EventArgs e)
{
HttpContext context = (sender as HttpApplication).Context;
if (context == null)
{
return;
}
// Calculate the time taken to process the request
DateTime start = (DateTime)context.Items["PerformanceLoggerStart"];
double millisecondsTaken = (DateTime.Now - start).TotalMilliseconds;
// Asynchronously log performance. Note that this also insulates the profiled application from any exceptions that may be thrown by the task being done.
Task.Run(() => Logger.LogPerformance(new LogEntry
{
// Get the full URL as it appears in the browser MINUS any MVC route-specific parameter like a GUID
Endpoint = ApplicationInformation.TrimIdFromMVCRoute(context.Request.Url),
// GET, POST, etc.
Action = context.Request.HttpMethod,
// Name of the machine executing this code
MachineName = Environment.MachineName,
// Get the application name from the URL - depends on whether running locally or remotely
ApplicationName = ApplicationInformation.GetApplicationName(context.Request.Url, context.Request.ApplicationPath),
// Time taken to process the request
MillisecondsTaken = millisecondsTaken
}));
}
}