您现在的位置是:首页 > cms教程 > Discuz教程Discuz教程
Discuz!NT的缓存设计是怎么样的
吴资龙2025-07-03Discuz教程已有人查阅
导读最近拜读了代振军同学写的关于Discuz NT的缓存设计的一篇文章Discuz NT 缓存设计简析 [原创],颇有些想法,姑且写在这里让大家拍砖吧。)
最近拜读了代振军同学写的关于Discuz NT的缓存设计的一篇文章Discuz NT 缓存设计简析 [原创],颇有些想法,姑且写在这里让大家拍砖吧。)
缓存真是个好东西,在大型的系统中可以有效地提升系统的速度,此乃废话就不多说了,在.Net 平台下面我把缓存从功用大致分为两类,数据对象缓存和页面输出缓存. 对于数据缓存来讲是由System.Web.Caching.Cache这个类来实现,可以从上下文对象Context.Cache 来获取这个对象的引用.而页面/控件输出缓存则是由.Net环境在运行时依据头部的缓存申明来控制缓存策略. 本文主要论证与数据缓存相关的一些应用与问题.
文中代同学提到了"无法跨Web园共享数据的问题",虽然提到解决方案就是使用XML文件来存放缓存的键值,这里有一个疑惑,就是.Net的Web园既然是进程独立的又何来共享之说呢,真要是这样的话即便是通过XML文档写入缓存键值缓存的对象也不能同时在两个进程 享,而这里获得的好处仅是避免了在其它的进程中读到了已在当前进程中失效的“脏”缓存数据,这样的话开几个Web园就会产生几个缓存的对象对系统资源的利用系就比较低了. 如果是用Web场布署的话浪费就更多了,也许是还少有论坛达到这样的规模故不在设计能力的范围中吧.CommunityServer也是使用了这个系统对象,并对它作了一些包装形成了CommunityServer.Components.CSCache这个类,还是不错的,可以在项目中选择使用.
基于这个类的应注实现还有EnterpriseLibrary的CacheBlock里面的NullBackingStore方式,但是为了满足多进程/服务器共程缓存数据的需求EntLib还提供了将SQL SERVER作为后端存储设备的方案,这样在性能要求不是太严,客户端连接不是太多的情况下也可以使用这种方式.只需要将EntLib 配置为共享数据库分区的工作方式即可,所有的CacheManager实例都有对缓存块的读写权,当然你也可配置为只允许一个实例写,其它的来读.
那么还有没有更好的办法呢,其实是有的. 不过我很奇怪在.Net平台下居然没有“原生态”的分布式缓存解决方案,也许是俺孤陋寡闻吧,有哪位达人知道的请分享。还好我们有Memcached这东西,它在PHP平台上已经取得了巨大的成功,是优秀的分布式缓存解决方案,可以参看这篇文章 , 大型的站点上应该必不可少吧.有举的同学可以去看看, 另外还想好一个思路, 就是在EntLib的基础上作扩展实现IBackingStore 接口从BaseBackingStore派生一个实现出来,再经由Remoting或者ICE这样的分布式中间件技术应该也可以实现的类似的功能吧.
用XML作为缓存键的存储方式倒是一个不错的想法,这样在批量移除缓存项的时候就不需要作扫描而直接得到相应的缓存键值,跟分布式缓存作一个整合应当是一个不错的方案。
好了,让我们再回头看看Discuz NT在页面缓存上有些什么高招.
总的说来我是不怎么喜欢.Net2.0提供的页面输出缓存功能,主要是不能手动地控制页面缓存的过期,而使有缓存依赖项似乎也有点不爽。事实上使用数据绑定控件相对来说是比较消耗资源的,同样的数据我用StringBuilder直接拼出来输出速度要快不少,测试代码比较简单我这里就不给了,大家可以自己去测去,Discuz NT在设计中也大量地采用了这样的方法(怪不得速度这么快呢;))。一般来讲模版被保存后后台会在aspx目录生成对应的页面文件, 比如你有一个页面,上面需要显示一个来访者的姓名,它的伪代码看起来可能是这个样子
模版文件内容show.html:
从另一个角度讲已登陆用户不应该速度比匿名用户还慢吧~~~;)
HOHO,终于完成了,先写这些吧。聊点别的`~~总体上看俺觉得实用的就是较好的,不要说DNT的设计有多烂多烂,层次结构多不合理,代码多不OO,但是在这样一个特定的应用环境下它提供了一种相对灵活和高速的解决的方案,我觉得就是一个正确的选择。量体裁衣做出来的东西虽然可维护可重用性较差还是有它的好处的,俺自己也比较倾向于这种针对性很强的解决方案思路,希望DNT能做得更好~~~正如BlogEngine这样的程序,它几乎将很多的数据都Load到内存里面,数据存储默认的也是XML的存储方式,你很难去讲它是一个糟糕的程序,因为它有特定的应用场景,合适的才是较好的~~~~
缓存真是个好东西,在大型的系统中可以有效地提升系统的速度,此乃废话就不多说了,在.Net 平台下面我把缓存从功用大致分为两类,数据对象缓存和页面输出缓存. 对于数据缓存来讲是由System.Web.Caching.Cache这个类来实现,可以从上下文对象Context.Cache 来获取这个对象的引用.而页面/控件输出缓存则是由.Net环境在运行时依据头部的缓存申明来控制缓存策略. 本文主要论证与数据缓存相关的一些应用与问题.
文中代同学提到了"无法跨Web园共享数据的问题",虽然提到解决方案就是使用XML文件来存放缓存的键值,这里有一个疑惑,就是.Net的Web园既然是进程独立的又何来共享之说呢,真要是这样的话即便是通过XML文档写入缓存键值缓存的对象也不能同时在两个进程 享,而这里获得的好处仅是避免了在其它的进程中读到了已在当前进程中失效的“脏”缓存数据,这样的话开几个Web园就会产生几个缓存的对象对系统资源的利用系就比较低了. 如果是用Web场布署的话浪费就更多了,也许是还少有论坛达到这样的规模故不在设计能力的范围中吧.CommunityServer也是使用了这个系统对象,并对它作了一些包装形成了CommunityServer.Components.CSCache这个类,还是不错的,可以在项目中选择使用.
基于这个类的应注实现还有EnterpriseLibrary的CacheBlock里面的NullBackingStore方式,但是为了满足多进程/服务器共程缓存数据的需求EntLib还提供了将SQL SERVER作为后端存储设备的方案,这样在性能要求不是太严,客户端连接不是太多的情况下也可以使用这种方式.只需要将EntLib 配置为共享数据库分区的工作方式即可,所有的CacheManager实例都有对缓存块的读写权,当然你也可配置为只允许一个实例写,其它的来读.
那么还有没有更好的办法呢,其实是有的. 不过我很奇怪在.Net平台下居然没有“原生态”的分布式缓存解决方案,也许是俺孤陋寡闻吧,有哪位达人知道的请分享。还好我们有Memcached这东西,它在PHP平台上已经取得了巨大的成功,是优秀的分布式缓存解决方案,可以参看这篇文章 , 大型的站点上应该必不可少吧.有举的同学可以去看看, 另外还想好一个思路, 就是在EntLib的基础上作扩展实现IBackingStore 接口从BaseBackingStore派生一个实现出来,再经由Remoting或者ICE这样的分布式中间件技术应该也可以实现的类似的功能吧.
用XML作为缓存键的存储方式倒是一个不错的想法,这样在批量移除缓存项的时候就不需要作扫描而直接得到相应的缓存键值,跟分布式缓存作一个整合应当是一个不错的方案。
好了,让我们再回头看看Discuz NT在页面缓存上有些什么高招.
总的说来我是不怎么喜欢.Net2.0提供的页面输出缓存功能,主要是不能手动地控制页面缓存的过期,而使有缓存依赖项似乎也有点不爽。事实上使用数据绑定控件相对来说是比较消耗资源的,同样的数据我用StringBuilder直接拼出来输出速度要快不少,测试代码比较简单我这里就不给了,大家可以自己去测去,Discuz NT在设计中也大量地采用了这样的方法(怪不得速度这么快呢;))。一般来讲模版被保存后后台会在aspx目录生成对应的页面文件, 比如你有一个页面,上面需要显示一个来访者的姓名,它的伪代码看起来可能是这个样子
模版文件内容show.html:
<html>
<body>
Hello, Your name is <% yourname %>
</body>
</html>
生成的文件 show.aspx
templateBuilder.AppendLine("<html>");
templateBuilder.AppendLine("<body>");
templateBuilder.AppendLine("Hello, Your name is " + this.yourname);
templateBuilder.AppendLine("</body>");
templateBuilder.AppendLine("</html>");
这里的this.yourname对应着相应页面后台类里面的一个属性,由程序在运行时进行初始化赋值,这样之后得到的页面执行结果就可以从这个templateBuilder对象的ToString()方法得到, templateBuilder也就是一个页面后台类里面的StringBuilder类的实例,之后在页面执行完毕后的OnLoad事件中根据不同的页面类型,如首页,频道首页,内容页等, 使用不同的缓存策略将页面执行结果的HTML代码插入到缓存中,下一个请求进来的时候在进入页面生命周期之前的HttpModule(这里面还包含地址重写功能代码)中判断这个缓存是否有效,直接从内存读取缓存发回客户端.这样速度当然就快了, 页面上看到的执行时间自然是0ms. 不过对于登陆用户来说由于要显示不同的登陆信息所以不能使用匿名的缓存文件版本,所以说一旦你登陆页面才会真正执行一次,但是上面要显示的数据都有独立的缓存项,所以仅仅是重新组装一次页面代码罢了,速度还是比较快的,在官方论坛上看到首页加载时间是15ms, 够快的了. 愚以为连这个时间其实也是可以再节省节省的. 比如用户登陆信息这部分东西可以生成一段JS, 在向浏览器发出了匿名用户的缓存版本时再判断如果用户登陆了就追加这样一段JS代码,在里面去把相应的HTML替换掉就可以了,也可以使用AJAX技术在客户端去取,这样就解决了已登陆用户和未登陆用户在共享缓存版本上的问题,至少在首页这一级是可以的吧,其它的主要页面不好说应该也差不多,俺对论坛程序的流程不是很了解.从另一个角度讲已登陆用户不应该速度比匿名用户还慢吧~~~;)
HOHO,终于完成了,先写这些吧。聊点别的`~~总体上看俺觉得实用的就是较好的,不要说DNT的设计有多烂多烂,层次结构多不合理,代码多不OO,但是在这样一个特定的应用环境下它提供了一种相对灵活和高速的解决的方案,我觉得就是一个正确的选择。量体裁衣做出来的东西虽然可维护可重用性较差还是有它的好处的,俺自己也比较倾向于这种针对性很强的解决方案思路,希望DNT能做得更好~~~正如BlogEngine这样的程序,它几乎将很多的数据都Load到内存里面,数据存储默认的也是XML的存储方式,你很难去讲它是一个糟糕的程序,因为它有特定的应用场景,合适的才是较好的~~~~
本文标签:
很赞哦! ()
相关教程
图文教程
Discuz X2.5(PHP) CAS单点登录代码实例
搭载Discuz! X2.5 平台,这个比较简单,我用的是wamp集成服务器,直接next、next...就可以了。之后配置PHP的CAS,先下载客户端我下载的是1.3.1,然后将解压后的CAS文件夹和CAS.php复制到
Discuz X3核心文件解析
[Discuz!] (C)2001-2099 Comsenz Inc.This is NOT a freeware, use is subject to license terms$Id: discuz_application.php 34170 2013-10-28 02:58:29Z nemohou $
Discuz的NT持续集成实战
从SVN中取出源代码到e:\source,编译后发布项目到e:\publish,可直接在IIS中运行。编译状态发送email通知相关人员。软件环境:(以下软件的安装过程非常简单,基本上一路Next就可以了。)
Discuz的NT邮件插件机制分析
大约还是去年12月份,当时项目中遇到了一个很棘手的问题,就是管理员(或站长)在后台设置了邮箱信息之后,使用注册邮件发送激活验证码时,总有用户反映不能收到激活信息的邮件。
相关源码
-
自适应极简风个人博客文章自媒体网站模板基于PbootCMS开源内核开发的极简个人博客模板,采用移动优先设计原则,通过Media Query技术实现320px至1920px六级分辨率适配,确保在手机、平板及PC设备上均呈现良好的视觉体验。查看源码 -
(自适应)html5中英双语通用机械设备pbootcms模板下载本模板基于PbootCMS内核精心开发,为机械设备制造企业量身打造。设计风格大气稳重,充分展现机械行业的专业特质与技术实力。采用HTML5技术构建,支持中英文双语切换,满足国际化业务需求。整站布局合理,充分展示企业产品、案例与服务,帮助访客快速了解企业核心优势。查看源码 -
pbootcms模板(自适应)花店鲜花花卉园艺网站源码一款基于PbootCMS内核开发的花店鲜花配送与花卉园艺企业网站模板。该模板采用响应式设计,自动适配手机、平板等移动设备,确保用户在任何设备上都能获得优质浏览体验。查看源码 -
(自适应响应式)蓝色外贸英文产品介绍展示网站模板本模板采用手工编写的DIV+CSS架构,代码精简高效。适配手机端浏览,数据实时同步更新。内置SEO优化框架,支持独立设置各页面标题、关键词及描述。开源代码结构清晰,便于二次开发。查看源码 -
(PC+WAP)绿色环保设备环保企业网站模板源码下载基于PbootCMS内核开发的响应式企业模板,为环保设备制造、环境技术服务等企业打造,通过模块化设计实现多行业快速适配。查看源码 -
(自适应响应式)高新技术科技能源pbootcms网站HTML5模板本模板基于PbootCMS内核开发,为高新技术、科技研发、能源技术等科技型企业设计。采用HTML5+CSS3前沿技术,具备完善的响应式布局,能够自动适配手机、平板和电脑等多种终端设备。模板设计风格简约大气查看源码
| 分享笔记 (共有 篇笔记) |
