如何在不影响网站性能的情况下,以人为单位捕获页面浏览量?我看到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版本,您需要手动将相同的属性应用于所有操作。
[PageView]
public ActionResult CallOne()
{
}
[PageView]
public ActionResult CallTwo()
{
}
OnActionExecuted
来代替,并检查 filterContext.Result is ViewResult
,以获得更高的准确性。 - Xavier Poinas最好的方式可能是使用全局操作过滤器来拦截所有控制器上所有操作的请求,然后在数据库中为当前用户和页面递增计数器。为了避免对数据库产生太大的影响,您可以缓存这些值,并根据处理的流量情况每隔几分钟使它们无效。
[ServiceFilter(typeof(PageViewAttribute))]
services.AddMemoryCache();
services.AddScoped<[PageViewAttribute]>(); - 不带方括号!
以下是代码。
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);
}