.NET 分布式会话原理

前言

近来系统从 net framework472 升级到 net8,因为是分布式部署,而且以前代码大量运用了会话,所以要弄分部署会话。

网上找资料发现没有太多深入一点的,所以整理一下记录。

ASP.NET Core 中的会话 | Microsoft Learn


原理说明

关键概念

cookie、持久化、数据保护、

关键概念介绍

  • cookie:用于存储加密后的 SessionKey
  • 持久化:用于 session 的内容存储到进程内存还是别的什么地方,
    可以用默认实现 调用 IDistributedCache 的实现来存储,
    也可以自定义 ISession、ISessionStore 来实现存储。
  • 数据保护:cookie 加解密处理器

源码分析、原理介绍

  • 总体流程

当用户访问网站发起请求到服务端的时候,请求首先会经过 SessionMiddleware 中间件,
该中间件会先尝试读取 cookie,并用 IDataProtector 的实现来解密得到 SessionKey,
期间如果 cookie 为空或者解密失败拿不到 SessionKey,会随机生成 SessionKey,
接下来通过 ISessionStore 的实现来 Create 一个 ISession 的实现,并把 SessionKey 传递给 ISession,
后续该请求内的所有 Session 相关的操作,都是通过这个 ISession 来操作的。

  • 数据存储

ISession 的默认存储方式,就是调用 IDistributedCache 的实现来存储的,具体实现看具体配置,默认就是进程内存。

  • ISession 接口
    这个接口最主要的 LoadAsync、CommitAsync、TryGet、Set、Remove、Clear
    其中,CommitAsync 方法是个请求离开时自动执行的。
    另外,这里只有 Load 和 Commit 是异步的,
    所以默认实现是 Load 的时候把 Session 信息全加载出来,
    然后中间同步的 Get、Set、Remove、Clear 操作都是在内存里运行记录,
    最后再通过 Commit 方法一次持久化。
    他们会把所有session数据塞到统一个Redis-Key里面。
    但是我们旧的代码给 Session 存了大的对象,每个请求都要存取Redis并且序列化,比较消耗资源,
    所以我们自己重新实现了 ISession 和 ISessionStore,每个Session的Key对应一个Redis Hash Field,
    并且要用才读单个field,要用才写单个field,节省资源。
    一般不要搞大对象session,就不需要重写也可以了。


注意事项

如果你已经看完原理了。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注