【问题标题】:How can I slowly migrate to using Redis as a Session State Provider from in process?如何从进程中慢慢迁移到使用 Redis 作为会话状态提供程序?
【发布时间】:2019-02-19 15:23:39
【问题描述】:

实现我自己的会话状态提供程序,根据 redis 会话提供程序和 inproc 会话提供程序之间的键有条件地切换是不是一个坏主意?

我正在一个非常大的遗留 asp.net 应用程序中工作,该应用程序当前使用 inproc 会话提供程序。我们正在迁移到 Redis 作为会话状态提供程序,以便它持续部署,但是应用程序充满了会话滥用(例如,太大的对象,不可序列化的对象,我出于某种原因在那里看到了一个线程?)。

我们计划慢慢纠正这些滥用行为,但在它们全部纠正之前,我们无法真正迁移到 redis。我希望我们可以慢慢开始将可序列化安全密钥迁移到 redis 中,而滥用行为仍会保留在内存中,直到我们解决它们。

有人对此有什么建议吗?或者也许是从进程中迁移到进程外的替代建议?

谢谢!

【问题讨论】:

    标签: asp.net asp.net-mvc session redis session-state-provider


    【解决方案1】:

    会话状态的来源:https://github.com/Microsoft/referencesource/blob/master/System.Web/State/ 文档:https://docs.microsoft.com/en-us/dotnet/api/system.web.sessionstate?view=netframework-4.7.2

    我首先要查看参考源,以便您可以搜索代码库。一个接口跳出来可能很有趣.. IPartialSessionState (当在一个类型中实现时,返回一个零个或多个会话键的列表,向会话状态提供者指示必须检索哪些会话状态项。)来源在这里 https://docs.microsoft.com/en-us/dotnet/api/system.web.sessionstate.ipartialsessionstate?view=netframework-4.7.2

    我偶然发现了https://www.wiktorzychla.com/2007/06/wrapped-inprocsessionstatestore.html 通过ASPNET : Switch between Session State Providers ?‏.
    这种技术理论上也可以与 Redis 提供程序一起使用。您必须维护适合存储在 Redis 中的键列表,或者尝试序列化/捕获/缓存哪些类型的结果可以序列化并自适应地回退到 InProc 行为。您应该能够使用 HttpContext.Current.Items 在请求处理管道中的事件之间传递信息。

    SessionStateModule(负责检索会话、锁定、保存、解锁等的模块)似乎在某些地方将 InProc 视为特殊的。在其代码中搜索 InProc。本质上,您正在尝试插入一个神奇的提供程序,它是自定义的,但仍然具有由唯一的 SessionStateModule 应用的所有 InProc 语义。您将无法/可能不想修改该模块,但您可以连接另一个与其相邻的模块,该模块与请求管道中的相关事件挂钩,并执行任何需要做的事情进程内或自定义特定。您可能会遇到需要使用反射的内部/私有方法。不确定许可如何在参考源上工作(我认为是 MS-PL),但另一种选择是将 SessionStateModule 中的代码复制并粘贴到您自己的代码中,根据需要进行调整,取消注册原始代码并注册您的替换代码。

    认为您将不得不处理大量反射代码才能使其正常工作。

    【讨论】:

      【解决方案2】:

      在 ASP.NET Web 窗体和 MVC 中,使用 Redis 表示会话状态只是在 Web.config 中的几行修改。然后将SerializableAttribute 添加到类中。 no side effects of applying it to a class

      根据我几年前迁移到 Azure 时的经验,Session State 不值得慢慢迁移。

      缓存是另一回事。它需要更改代码,因此我们最终实现了两个类 - MemoryCacheManagerRedisCacheManager,并在运行时在 IoC 容器中注册。然后将ICacheManager 注入依赖类。

      【讨论】:

      • 你说将它应用到一个类没有副作用,但不是有类不一定是可序列化的吗?例如如果我在一个包含对线程的引用的类上进行可序列化,这将在运行时中断,不是吗?
      • 澄清一下,我们打算修复这些用途以更恰当地遵循会话指南,但我很好奇我们清理这些区域的缓慢推出。
      • break at runtime 是的,如果一个类引用了不可序列化的类,它会抛出运行时异常。如果要实现自定义会话状态提供程序,可以查看RedisSessionStateProvider 源代码。
      猜你喜欢
      • 2015-03-10
      • 2015-08-27
      • 2015-11-28
      • 2014-08-06
      • 2013-07-21
      • 2012-08-23
      • 2015-11-18
      • 2016-04-19
      • 2014-12-24
      相关资源
      最近更新 更多