在不降低网站性能的情况下,按人捕获页面浏览量的最佳方法是什么?我看到stackoverflow到处都显示页面视图。每次我点击页面时,他们都会插入数据库吗?
在 asp.net-mvc 中,是否有任何推荐的方法来跟踪每个用户的页面浏览量(我的网站有一个登录屏幕),这样我就可以查看人们要去哪些页面以及多久访问一次
在不降低网站性能的情况下,按人捕获页面浏览量的最佳方法是什么?我看到stackoverflow到处都显示页面视图。每次我点击页面时,他们都会插入数据库吗?
在 asp.net-mvc 中,是否有任何推荐的方法来跟踪每个用户的页面浏览量(我的网站有一个登录屏幕),这样我就可以查看人们要去哪些页面以及多久访问一次
首先.. 如果您真正关心的是客户如何使用我的网站,那么您很可能希望查看Google Analytics(分析)或类似服务。
但是,如果您想要一个快速而肮脏的页面查看记录,并且您正在使用 ASP.Net MVC 3,那么正如 Chris Fulstow 所提到的,您将需要混合使用全局操作过滤器和缓存。这是一个例子。
PageViewAttribute.cs
public class PageViewAttribute : ActionFilterAttribute
{
private static readonly TimeSpan pageViewDumpToDatabaseTimeSpan = new TimeSpan(0, 0, 10);
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var calledMethod = string.Format("{0} -> {1}",
filterContext.ActionDescriptor.ControllerDescriptor.ControllerName,
filterContext.ActionDescriptor.ActionName);
var cacheKey = string.Format("PV-{0}", calledMethod);
var cachedResult = HttpRuntime.Cache[cacheKey];
if(cachedResult == null)
{
HttpRuntime.Cache.Insert(cacheKey, new PageViewValue(), null, DateTime.Now.Add(pageViewDumpToDatabaseTimeSpan) , Cache.NoSlidingExpiration, CacheItemPriority.Default,
onRemove);
}
else
{
var currentValue = (PageViewValue) cachedResult;
currentValue.Value++;
}
}
private static void onRemove(string key, object value, CacheItemRemovedReason reason)
{
if (!key.StartsWith("PV-"))
{
return;
}
// write out the value to the database
}
// Used to get around weird cache behavior with value types
public class PageViewValue
{
public PageViewValue()
{
Value = 1;
}
public int Value { get; set; }
}
}
在你的 Global.asax.cs
public class MvcApplication : HttpApplication
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new PageViewAttribute());
}
}
对于 pre-ASP.Net MVC 3 ONLY,您将不得不手动将相同的属性应用于您的所有操作。
[PageView]
public ActionResult CallOne()
{
}
[PageView]
public ActionResult CallTwo()
{
}
最好的方法可能是一个全局操作过滤器,它拦截对所有控制器上所有操作的请求,然后在数据库中为当前用户和页面增加一个计数器。为了避免过于频繁地访问数据库,您可以缓存这些值并每隔几分钟使它们无效,具体取决于您正在处理的流量。
我们使用开源 Piwik:http://piwik.org/,它是在它自己的服务器上设置的。_Layout 页面中的一行 Javascript 在页面加载后调用 Piwik(将 JS 放在末尾),完全不影响页面加载性能。
除了计数之外,您还将获得有关用户来自何处、浏览器、屏幕分辨率、已安装插件的大量信息。此外,您可以跟踪转化并使用相同的工具来跟踪营销活动等。
<肥皂盒>
我想不出在 MVC 或一般的 Web 应用程序中实现这一点会更好的情况。这些东西根本不属于你的网络应用程序,是一个应该分离出来的元问题。这种方法使我们能够以统一的方式跟踪我们所有应用程序(其中 32 个:mvc 2/3、webforms、php...)的分析。
如果您真的不想为此使用其他工具,我建议您访问您的 IIS 日志并从那里获取您的统计信息。同样,要从中获得任何真正的决策能力,您需要在其上放置一个好的分析器。我推荐 Splunk:http ://www.splunk.com/
</肥皂盒>
我想为感兴趣的人发布 Shane 答案的更新版本。需要考虑的一些事项:
在使用如下语法装饰方法时,您必须将 action 属性设置为服务:
[ServiceFilter(typeof(PageViewAttribute))]
据我所知,HttpRuntime.Cache.Insert 不是 .NET Core 中的东西,所以我使用了 IMemoryCache 的简单实现(您可能需要将此行添加到您的 startup.cs 中才能使用该接口) :
services.AddMemoryCache();
因为我们将 IMemoryCache 注入到一个不是控制器的类中,所以我们需要在 startup.cs 中将我们的属性注册为服务,如下所示:
services.AddScoped<[PageViewAttribute]>(); - 没有括号!
创建 cacheKey 时返回的任何对象都将分配给 OnRemove 方法的“value”参数。
下面是代码。
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var controllerActionDescriptor = filterContext.ActionDescriptor as ControllerActionDescriptor;
var arguments = filterContext.ActionArguments;
ActionId = arguments["id"].ToString();
var calledMethod = string.Format("{0} -> {1}",
controllerActionDescriptor.ControllerName,
controllerActionDescriptor.ActionName);
var cacheKey = string.Format("PV-{0}", calledMethod);
var cachedResult = _memoryCache.Get(cacheKey);
if (cachedResult == null)
{
//Get cacheKey if found, if not create cache key with following settings
_memoryCache.GetOrCreate(cacheKey, cacheKey =>
{
cacheKey.AbsoluteExpirationRelativeToNow
= pageViewDumpToDatabaseTimeSpan;
cacheKey.SetValue(1);
cacheKey.RegisterPostEvictionCallback(onRemove);
return cacheKey.Value;
});
}
else
{
_memoryCache.Get(cacheKey);
}
}
//Called when Memory entry is removed
private void onRemove(object key, object value, EvictionReason reason, object state)
{
if (!key.ToString().StartsWith("PV-"))
{
return;
}
// write out the value to the database
SaveToDataBase(key.ToString(), (int)value);
}
作为参考,这是针对 .NET Core 5 MVC 应用程序完成的。
问候。