【问题标题】:ASP.NET MVC shared counter best practicesASP.NET MVC 共享计数器最佳实践
【发布时间】:2012-12-10 21:39:18
【问题描述】:

我的 ASP.NET MVC 4 项目使用 EF5 代码优先,并且一些域对象包含根据传入请求更新的非持久化计数器属性。这些请求非常频繁,并且很可能出现多个请求会话正在修改这些计数器的情况。

我的问题是,是否有最佳实践(不一定与 ASP.NET 或 EF 相关)来处理这种情况?我认为(但我不确定)为了讨论,我们可以将域对象视为简单的 POCO(它们就是)。

编辑:根据要求,以下是实际情况:

该系统是一个订阅者和内容管理系统。对等服务器正在发出我的系统授权或拒绝的请求。授权请求会导致在对等服务器中打开会话。当对等服务器中的会话关闭时,它会发出一个请求,通知会话已关闭。

我的系统需要提供统计信息 - 例如,每个内容项(域实体之一)当前打开的会话数 - 并提供实时数据以及每分钟、每小时、每天、每周等. 数字。

由于性能问题,无法通过查询数据库来提取这些数字,所以我决定在内存中实现基本的计数器,每分钟将它们持久化到数据库中,并以每小时、每天等方式获取。那里的数字。

上述问题是因为每个对等服务器请求都会更新这些“计数器”。

我希望现在更清楚了。

【问题讨论】:

  • 如果您询问您想要实现的目标,人们将能够更好地帮助您。 EF 实体中的共享计数器可能不是最好的方法。如果您需要它来扩展,您可能无论如何都必须对计数器进行分片。
  • 您说计数器没有持久化,但您暗示它们在多个传入请求中得到维护。您能定义传入请求的含义吗?持久性有多种形式,要回答你的问题需要更多关于问题的细节。
  • 可能值得调查ConcurrentDictionary

标签: c# .net asp.net-mvc concurrency


【解决方案1】:

听起来您的方案仍然需要可靠的持久性策略。

您的计数器对象可以持久化到HttpRuntime.Cache。 丹·沃森 (Dan Watson) 在这里有一篇出色的文章: http://www.dotnetguy.co.uk/post/2010/03/29/c-httpruntime-simple-cache/

请务必使用CacheItemPriority.NotRemovable 以确保它在内存回收期间保持状态。缓存将在应用程序域的范围内维护。您可以在缓存中检索和更新计数器(它的线程安全!),并从可能的统计页面或其他选项查询其状态。但是,如果数据需要在运行时范围之外持久化,那么您已经使用的策略就足够了。

【讨论】:

  • 我不确定这些文章中描述的机制如何解决上述并发问题。
  • 我更新了我的答案,专注于利用缓存作为解决方案。
【解决方案2】:

实际上,我认为在您没有从测试和分析器工具中获得足够信息之前,您无需过多担心性能。

但是,如果您使用的是 EF,那么您需要处理 DataContext,这是 Martin Fowler 在他的书中描述的 Unit Of Work 模式实现。这种模式的主要思想是减少对数据库的请求量并尽可能多地操作内存中的数据,直到您不提交所有更改。因此,我的简短建议将只是以标准方式使用您的 EF 实体,而不是在每次数据更新时提交更改,而是有一些间隔,例如在 100 次更改之后,在会话、应用程序会话、缓存或别的地方。您唯一应该关心的是每次都使用正确的 DataContext 对象,并且不要忘记在不再需要它时将其丢弃。

【讨论】:

  • 我正在采用您一般描述的方法,但我不相信 EF 可以用于 Sessions。该表将保存数百万条记录,并且会有工作在后台处理,所以恐怕需要直接使用数据库以及某种形式的缓存(尚不确定)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-21
  • 1970-01-01
相关资源
最近更新 更多