我的编程空间,编程开发者的网络收藏夹
学习永远不晚

如何利用MongoDB打造.Net的分布式Session子系统

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

如何利用MongoDB打造.Net的分布式Session子系统

本篇文章为大家展示了如何利用MongoDB打造.Net的分布式Session子系统,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

Taobao有她自己的分布式session框架,.net阵营也不能落后了,在下做了个基于MongoDB的支持最多26台MongoDB的分布式Session框架。

先看看配置文件:

<?xml version="1.0" encoding="utf-8" ?> <MongoDBSession>   <DbName>SessionDB</DbName>   <IdentityMap Identity="A">mongodb://localhost</IdentityMap>   <IdentityMap Identity="B">mongodb://localhost</IdentityMap>   <IdentityMap Identity="C">mongodb://localhost</IdentityMap>   <IdentityMap Identity="D">mongodb://localhost</IdentityMap>   <IdentityMap Identity="E">mongodb://localhost</IdentityMap>   <IdentityMap Identity="F">mongodb://localhost</IdentityMap>   <IdentityMap Identity="G">mongodb://localhost</IdentityMap>   <IdentityMap Identity="H">mongodb://localhost</IdentityMap>   <IdentityMap Identity="I">mongodb://localhost</IdentityMap>   <IdentityMap Identity="J">mongodb://localhost</IdentityMap>   <IdentityMap Identity="K">mongodb://localhost</IdentityMap>   <IdentityMap Identity="L">mongodb://localhost</IdentityMap>   <IdentityMap Identity="M">mongodb://localhost</IdentityMap>   <IdentityMap Identity="N">mongodb://localhost</IdentityMap>   <IdentityMap Identity="O">mongodb://localhost</IdentityMap>   <IdentityMap Identity="P">mongodb://localhost</IdentityMap>   <IdentityMap Identity="Q">mongodb://localhost</IdentityMap>   <IdentityMap Identity="R">mongodb://localhost</IdentityMap>   <IdentityMap Identity="S">mongodb://localhost</IdentityMap>   <IdentityMap Identity="T">mongodb://localhost</IdentityMap>   <IdentityMap Identity="U">mongodb://localhost</IdentityMap>   <IdentityMap Identity="V">mongodb://localhost</IdentityMap>   <IdentityMap Identity="W">mongodb://localhost</IdentityMap>   <IdentityMap Identity="X">mongodb://localhost</IdentityMap>   <IdentityMap Identity="Y">mongodb://localhost</IdentityMap>   <IdentityMap Identity="Z">mongodb://localhost</IdentityMap> </MongoDBSession>

从Identity A一直到Z,默认分成了26个Map,具体的C#应用代码:

protected void btnTest_Click(object sender, EventArgs e)          {              Session["A"] = DateTime.Now;              Session["B"] = 1111111111111;              Session["C"] = "fffffffffffffff";          }           protected void btnGetSession_Click(object sender, EventArgs e)          {              Response.Write(Session["A"].ToString());              Response.Write("<br />");              Response.Write(Session["B"].ToString());              Response.Write("<br />");              Response.Write(Session["C"].ToString());          }          protected void btnAbandon_Click(object sender, EventArgs e)          {              Session.Abandon();          }

呵呵,就是普通的Session用法。

这个要配置web.config:

<system.web>     <sessionState mode="Custom" customProvider="A2DSessionProvider" sessionIDManagerType="A2DFramework.SessionService.MongoDBSessionIDManager">       <providers>         <add name="A2DSessionProvider" type="A2DFramework.SessionService.MongoDBSessionStateStore"/>       </providers>     </sessionState>   </system.web>

这里会牵扯出2个类:

  1. A2DFramework.SessionService.MongoDBSessionIDManager

  2. A2DFramework.SessionService.MongoDBSessionStateStore

MongoDBSessionIDManager

  • 自定义生成的cookie值(也就是SessionID),在这个sample中,会生成如“E.asadfalkasdfjal”这样的SessionID,其中前缀E代表这个Session的信息会映射到哪台MongoDB上。

  • 关键代码

public class MongoDBSessionIDManager : SessionIDManager      {          private Random rnd = new Random();          private object oLock = new object();           public override string CreateSessionID(System.Web.HttpContext context)          {              int index = 0;              lock(this.oLock)              {                  index = rnd.Next(SessionConfiguration.SessionServerIdentities.Length);              }              string sessionId = string.Format("{0}.{1}", SessionConfiguration.SessionServerIdentities[index], base.CreateSessionID(context));              return sessionId;          }           public override string Encode(string id)          {              return DESEncryptor.Encode(id, SessionConfiguration.DESKey);          }          public override string Decode(string id)          {              return DESEncryptor.Decode(id, SessionConfiguration.DESKey);          }           public override bool Validate(string id)          {              string prefix;              string realId;               if (!Helper.ParseSessionID(id, out prefix, out realId))                  return false;               return base.Validate(realId);          }      }

MongoDBSessionStateStore

  • 自定义Session过程中最核心的一个类,代码如下(较多):

public sealed class MongoDBSessionStateStore : SessionStateStoreProviderBase      {          private SessionStateSection pConfig;          private string pApplicationName;           public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)          {              base.Initialize(name, config);               pApplicationName =System.Web.Hosting.HostingEnvironment.ApplicationVirtualPath;              System.Configuration.Configuration cfg = WebConfigurationManager.OpenWebConfiguration(pApplicationName);              pConfig =(SessionStateSection)cfg.GetSection("system.web/sessionState");          }           public override SessionStateStoreData CreateNewStoreData(System.Web.HttpContext context, int timeout)          {              return new SessionStateStoreData(new SessionStateItemCollection(), SessionStateUtility.GetSessionStaticObjects(context), timeout);          }           public override void CreateUninitializedItem(System.Web.HttpContext context, string id, int timeout)          {              //insert to db              MongoDBSessionEntity session = new MongoDBSessionEntity();              session.ApplicationName = this.pApplicationName;              session.SessionId = id;              session.Created = DateTime.Now;              session.Expires = DateTime.Now.AddMinutes(pConfig.Timeout.Minutes);              session.LockDate = DateTime.Now;              session.LockId = 0;              session.Timeout = timeout;              session.Locked = false;              session.Flags = (int)SessionStateActions.InitializeItem;               MongoCollection<MongoDBSessionEntity> collection = Helper.GetMongoDBCollection(id);              collection.Save(session);          }           public override void Dispose()          {          }           public override void EndRequest(System.Web.HttpContext context)          {          }           public override SessionStateStoreData GetItem(System.Web.HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions)          {              return GetSessionStoreItem(false, context, id, out locked, out lockAge, out lockId, out actions);          }           public override SessionStateStoreData GetItemExclusive(System.Web.HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions)          {              return GetSessionStoreItem(true, context, id, out locked, out lockAge, out lockId, out actions);          }           public override void InitializeRequest(System.Web.HttpContext context)          {          }           public override void ReleaseItemExclusive(System.Web.HttpContext context, string id, object lockId)          {              //update locked=0, expired=, where lockId=?              MongoCollection<MongoDBSessionEntity> collection = Helper.GetMongoDBCollection(id);               var query = Query.And(  Query.EQ("LockId", int.Parse(lockId.ToString())),                                      Query.EQ("_id", id),                                       Query.EQ("ApplicationName", pApplicationName));              var update = Update.Set("Locked", false)                                  .Set("Expires", DateTime.Now.AddMinutes(pConfig.Timeout.Minutes));               collection.Update(query, update);          }           public override void RemoveItem(System.Web.HttpContext context, string id, object lockId, SessionStateStoreData item)          {              //delete where sessionId=? and lockId=? and applicationname=?              MongoCollection<MongoDBSessionEntity> collection = Helper.GetMongoDBCollection(id);               var query = Query.And(Query.EQ("LockId", int.Parse(lockId.ToString())),                                      Query.EQ("_id", id),                                      Query.EQ("ApplicationName", pApplicationName));              collection.Remove(query);          }           public override void ResetItemTimeout(System.Web.HttpContext context, string id)          {              //update expire date              MongoCollection<MongoDBSessionEntity> collection = Helper.GetMongoDBCollection(id);               var query = Query.And(Query.EQ("_id", id),                                      Query.EQ("ApplicationName", pApplicationName));              var update = Update.Set("Expires", DateTime.Now.AddMinutes(pConfig.Timeout.Minutes));              collection.Update(query, update);          }           public override void SetAndReleaseItemExclusive(System.Web.HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem)          {              MongoCollection<MongoDBSessionEntity> collection = Helper.GetMongoDBCollection(id);              if (newItem)              {                  //delete expired items                  var query = Query.And(Query.EQ("_id", id),                                      Query.EQ("ApplicationName", pApplicationName),                                      Query.LT("Expires", DateTime.Now));                   collection.Remove(query);                   //insert new item                  MongoDBSessionEntity session = new MongoDBSessionEntity();                  session.ApplicationName = this.pApplicationName;                  session.SessionId = id;                  session.Created = DateTime.Now;                  session.Expires = DateTime.Now.AddMinutes(pConfig.Timeout.Minutes);                  session.LockDate = DateTime.Now;                  session.LockId = 0;                  session.Timeout = item.Timeout;                  session.Locked = false;                  session.Flags = (int)SessionStateActions.None;                  session.SessionItems = Helper.Serialize((SessionStateItemCollection)item.Items);                   collection.Save(session);              }              else             {                  //update item                  var query = Query.And(Query.EQ("_id", id),                                      Query.EQ("ApplicationName", pApplicationName),                                      Query.EQ("LockId", int.Parse(lockId.ToString())));                  MongoDBSessionEntity entity= collection.FindOne(query);                  entity.Expires = DateTime.Now.AddMinutes(item.Timeout);                  entity.SessionItems = Helper.Serialize((SessionStateItemCollection)item.Items);                  entity.Locked = false;                  collection.Save(entity);              }          }           public override bool SetItemExpireCallback(SessionStateItemExpireCallback expireCallback)          {              return false;          }                    private SessionStateStoreData GetSessionStoreItem(bool lockRecord, System.Web.HttpContext context,                                                               string id,                                                              out bool locked,                                                              out TimeSpan lockAge,                                                              out object lockId,                                                              out SessionStateActions actions)          {              SessionStateStoreData item = null;                lockAge = TimeSpan.Zero;              lockId = null;              locked = false;              actions = 0;               bool foundRecord = false;              bool deleteData = false;               MongoCollection<MongoDBSessionEntity> collection = Helper.GetMongoDBCollection(id);               if (lockRecord)              {                   //update db, set locked=1, lockdate=now                  var query1 = Query.And(Query.EQ("_id", id),                                      Query.EQ("ApplicationName", pApplicationName),                                      Query.EQ("Locked", MongoDB.Bson.BsonValue.Create(false)),                                      Query.GT("Expires", DateTime.UtcNow));                   long count = collection.Find(query1).Count();                  if (count == 0)                  {                      locked = true;                  }                  else                 {                      var update = Update.Set("Locked", true).Set("LockDate", DateTime.Now);                      collection.Update(query1, update);                      locked = false;                  }              }              //get item by id              var query2 = Query.And(Query.EQ("_id", id),                                      Query.EQ("ApplicationName", pApplicationName));              MongoDBSessionEntity entity=collection.FindOne(query2);              if (entity != null)              {                  if (entity.Expires < DateTime.Now)                  {                      locked = false;                      deleteData = true;                  }                  else                 {                      foundRecord = true;                  }              }               //delete item if session expired              if (deleteData)              {                  var query3 = Query.And(Query.EQ("_id", id),                                      Query.EQ("ApplicationName", pApplicationName));                  collection.Remove(query3);              }               if (!foundRecord)                  locked = false;               if (foundRecord && !locked)              {                  if (lockId == null)                      lockId = 0;                  lockId = (int)lockId + 1;                   var query4 = Query.And(Query.EQ("_id", id),                                      Query.EQ("ApplicationName", pApplicationName));                  var update4 = Update.Set("LockId", (int)lockId)                                          .Set("Flags", (int)SessionStateActions.None);                  collection.Update(query4, update4);                   if (actions == SessionStateActions.InitializeItem)                      item = CreateNewStoreData(context, pConfig.Timeout.Minutes);                  else                     item = Helper.Deserialize(context, entity.SessionItems, entity.Timeout);              }              return item;          }      }

由于很多方法会用到MongoCollection,因此写了个static公用函数,如下:

public static MongoCollection<MongoDBSessionEntity> GetMongoDBCollection(string sessionId)          {              IPartitionResolver resolver = new MongoDBSessionPartitionResolver();              string mongoDbConnectionString = resolver.ResolvePartition(sessionId);               MongoClient client = new MongoClient(mongoDbConnectionString);              MongoServer srv = client.GetServer();              MongoDatabase db = srv.GetDatabase(SessionConfiguration.MongoDBName);              if (!db.CollectionExists(SessionConfiguration.MongoDBCollectionName))                  db.CreateCollection(SessionConfiguration.MongoDBCollectionName);               MongoCollection<MongoDBSessionEntity> collection = db.GetCollection<MongoDBSessionEntity>(SessionConfiguration.MongoDBCollectionName);               return collection;          }

运行效果:

如何利用MongoDB打造.Net的分布式Session子系统

点击Set Session后:

如何利用MongoDB打造.Net的分布式Session子系统

点击Get Session后:

如何利用MongoDB打造.Net的分布式Session子系统

点击Abandon后:

如何利用MongoDB打造.Net的分布式Session子系统

源代码已经更新到A2D Framework中了。

上述内容就是如何利用MongoDB打造.Net的分布式Session子系统,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注编程网行业资讯频道。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

如何利用MongoDB打造.Net的分布式Session子系统

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

如何利用MongoDB打造.Net的分布式Session子系统

本篇文章为大家展示了如何利用MongoDB打造.Net的分布式Session子系统,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。Taobao有她自己的分布式session框架,.net阵营也不能落后
2023-06-17

如何利用Golang技术实现混合云分布式系统?

在混合云环境中利用 golang 实现分布式系统提供了可扩展性、可用性和容错性。通过利用 go 语言的并发特性,您可以轻松构建和管理混合云分布式应用程序。实战案例展示了如何使用 kubernetes 在混合云上部署分布式微服务,其中包括 r
如何利用Golang技术实现混合云分布式系统?
2024-05-07

分布式系统在PHP接口性能优化中的应用(如何利用分布式系统提升PHP接口性能?)

分布式系统广泛应用于PHP接口性能优化,通过负载均衡、分布式缓存、消息队列等策略提升吞吐量、降低延迟。此外,垂直或水平拆分数据库、使用分布式文件系统、采用分布式搜索和事务机制、进行容器化和微服务化、实施性能监控和分析、建立服务治理机制等策略,进一步优化PHP接口性能,保障系统稳定性和可靠性。
分布式系统在PHP接口性能优化中的应用(如何利用分布式系统提升PHP接口性能?)
2024-04-02

项目实战:如何利用CSS网格布局打造响应式网页的经验分享

随着移动设备的普及和网页浏览习惯的改变,响应式设计成为了现代网页设计的重要趋势。而在响应式设计中,CSS网格布局被认为是一种非常有效的布局工具。在本文中,我将分享一些我在实际项目中使用CSS网格布局打造响应式网页的经验和技巧。首先,让我们回
项目实战:如何利用CSS网格布局打造响应式网页的经验分享
2023-11-02

基于Elasticsearch构建实时分布式搜索系统的实践(实时搜索系统如何利用Elasticsearch实现分布式搜索?)

利用Elasticsearch构建实时分布式搜索系统,需要考虑以下实践:实时索引:立即添加文档,实现快速更新。分布式搜索:将请求分发到集群节点,汇集结果。分片策略:优化数据分布,提升性能。副本:提供数据冗余,确保可用性。近实时搜索:通过刷新策略控制搜索延迟和索引耐久性。分布式锁:协调并发更新,防止数据不一致。
基于Elasticsearch构建实时分布式搜索系统的实践(实时搜索系统如何利用Elasticsearch实现分布式搜索?)
2024-04-02

项目实战:如何利用CSS打造响应式网页的经验分享

项目实战:如何利用CSS打造响应式网页的经验分享随着移动设备的普及和网页访问量的不断增长,响应式网页设计已经成为现代网页设计的重要一环。通过合理的CSS布局和媒体查询技术,网页可以根据不同设备的屏幕尺寸自动调整布局和样式,以适应不同设备上的
项目实战:如何利用CSS打造响应式网页的经验分享
2023-11-03

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录