【问题标题】:StructureMap warns caution when injecting in Session - Why?StructureMap 在 Session 中注入时警告警告 - 为什么?
【发布时间】:2013-07-16 04:03:12
【问题描述】:

StructureMap documentation on life cycle 中,他们声明一个范围选项是 HttpSession,并且它:“缓存 HttpContext.Session 集合中的实例。谨慎使用。”

我不知道要小心什么,我的 google-fu 让我失望了。

我们的用例是我们想要缓存一些昂贵的 Web 服务调用。其中一些是无状态的,但其中一些与特定用户相关联。

如果我们在 Session 范围内注入,我们什么时候是坏人?我们需要注意什么?

【问题讨论】:

    标签: .net asp.net-mvc-4 ioc-container session-state structuremap


    【解决方案1】:

    我将通过一个极端的例子来描述这个问题,缓存一个工作单元对象(例如 LINQ to SQL 的 DataContext、Entity Framework 的 ObjectContextDbContext 或 NHibernate 的 ISession):

    内存占用

    工作单元对象通常包含大量对象。将会话对象放在 HttpSession 中意味着只要会话存在,并且缓存中的所有对象都将存在。即使用户在 20 分钟后回来,您的应用程序也会有这种内存压力。这可能(并且在相当大的负载下)会导致内存不足异常。

    数据变得陈旧

    由于工作单元对象缓存了它从数据库加载的所有实体,因此该数据很快就会变得陈旧。当数据被另一个用户更改时,默认情况下不会刷新缓存的数据,并且您可能会遇到奇怪的行为,即一个用户看到一些数据,但另一个用户看到其他数据。刷新页面将不起作用,因为您在会话的生命周期内缓存了数据。只有关闭浏览器才会起作用(有时)。

    序列化

    当您扩展您的网络服务器(这意味着您添加更多服务器)时,会话信息必须从一台服务器传输到另一台服务器。您将不得不使用进程外缓存(例如 MemCache 或 SQL Server)。工作单元对象很难或不可能序列化和反序列化,这意味着您无法根据需要或需要进行横向扩展。

    总结

    这个例子是极端的,因为你不应该在工作单元模式中使用按会话生活方式。但它仍然相当清楚地描述了这个问题。每个会话的生活方式增加了应用程序的内存占用,因为服务保持活动很长时间。如果您使用此类服务​​来缓存数据,它可能会变得陈旧(尽管缓存可能只是您提高性能所需要的)。尽管 DTO 通常很容易序列化,但这不适用于您注册的任何服务。这意味着您无法横向扩展,因为需要可序列化的会话对象才能横向扩展。

    因此,不要在服务上使用 Per Session 生活方式,而是尝试构建无状态的服务,以便它们可以注册为单例。可以从 HTTP 会话中请求他们需要的任何用户特定数据。

    【讨论】:

    • 很遗憾 ASP.NET 不会强制 Session 内的对象可序列化,即使存储在进程中......这会导致 Web 项目以无法扩展的方式开始它们的生命,而不是从一开始就避免这种行为。
    • @MiguelAngelo:我同意。这就是为什么我总是将开发环境配置为使用进程外缓存,即使生产不这样做。这将使事情在开发过程中失败。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-25
    相关资源
    最近更新 更多