我记录网站综合系统 -- 技术原理解析[11:ActionProcessor流程-wojilu核心]

news/2024/5/10 16:17:19/文章来源:https://blog.csdn.net/weixin_34106122/article/details/93556968

这篇文章不是专门讲数据缓存的,但是这里有大量缓存内容,wojilu的缓存系统近期升级了,可能我的理解不是最正确的。

改日将会写专门的缓存文章。

源代码位置:\Web\Mvc\Processors:ActionProcessor.cs

Config ->

    wojilu.Web.Mvc.CoreHandler.ProcessRequest - >

          wojilu.Web.Mvc.CoreHandler.ProcessRequest: ProcessContext.Begin ->

               RouteProcess
                    InitContextProcess

        ActionMethodChecker

        ForbiddenActionChecker

        LoginActionChecker 
        HttpMethodChecker

        PermissionChecker

          ActionProcessor

wojilu是一个MVC系统,以前的流程只是一些外围的东西,从这里开始,有点MVC的味道了。

下面对于ActionProcessor的主要处理分段介绍:

1。和其他Processor一样的处理,做广播,告知其他侦听者;如果可以跳过这步,则跳过,不过,由于是核心部分,这里跳过的可能性不多。获得上下文内容,进而获得其中的Controller。

 

1             MvcEventPublisher.Instance.BeginProcessAction( context.ctx );
2             if (context.ctx.utils.isSkipCurrentProcessor()) return;
3 
4             MvcContext ctx = context.ctx;
5 
6             ControllerBase controller = context.getController();

wojilu拥有一套缓存系统:下面这个步骤就是检查缓存。关于wojilu的缓存系统,曾经咨询过 作者 掷鸡蛋者。下面引用当时的邮件的内容:

 

wojilu ORM中的缓存分成两部分:ContextCache(一级缓存)和ApplicationCache(二级缓存)。

ContextCache(一级缓存)这里的ContextCache仅仅存在于一个上下文中,具体到网站访问上,就是页面开始到页面结束,之后就不存在了。虽然缓存时间是瞬间的(比如只有几十毫秒),但也很有意义。它不是静态缓存,作为一级缓存,在web情况下,它是放在HttpContext中的。它的特点是随用随弃,不用考虑缓存策略,不会给内存增加负担,而在实战中很有价值,比如一个很大的页面分成了5个部分,在每个部分进行数据绑定的时候,可能出现重复的数据读取,比如页面头部查询了user,页面中部、数据列表等也查询了user,这些重复的查询都会默认直接从ContextCache中读取。如果是自己手写sql,往往就要细心避免这里的sql重复查询问题。

ApplicationCache(二级缓存)能长时间存在于内存中,作为二级缓存,往往是为了应付性能方面的压力。

ContextCache基本上是必须的、默认的,而ApplicationCache则需要根据实际的应用场景来实施。通常情况下,只有从一级缓存中检索不到数据,才去二级缓存中继续检索,如果二级缓存中也没有,才去数据库读取。

一级缓存是默认自动开启的,你不需要管他。

二级缓存需要手动打开。对于一个网站来说,最容易看出优化效果的,是二级缓存。它的主要目的就是实现透明缓存,所谓“透明缓存”,也就是不需要手工控制缓存的失效或过期,由ORM自动管理。
实现“透明缓存”的关键之处在于,在启用了ApplicationCache之后,每次查询出数据并加入缓存的时候,同时也缓存一个加入时间的时间戳

我们以 ApplicationPool(对象缓存池) 为例,当将一个对象加入缓存的时候——
        public void Add( IEntity obj ) {

            if (obj == null) return;

            String key = CacheKey.getObject( obj.GetType(), obj.Id );
            addToApplication( key, obj );
            CacheTime.updateObject( obj ); // 加入缓存的时候,设置最新 timestamp
        }

除了将对象放入缓存 addToApplication ,还保存了一个时间戳 CacheTime.updateObject( obj ) 。有了这个时间戳,那么,ORM就会知道哪些对象是更新过的,哪些对象是没有更新过的。在对象更新或删除的时候,会让缓存的对象刷新时间戳,比如在 UpdateOperation 中——
CacheTime.updateTable( entityInfo.Type );
表明这个对象已经被更新过了,所以下次客户端再检索就不会从缓存中取过期的对象。

对于一系列对象的列表,会在缓存中维护一个对象的id的列表,而不是直接将List<Object>放进去,请看 ApplicationPool 的 addList 方法,
            List<int> ids = new List<int>();
            foreach (IEntity obj in objList) ids.Add( obj.Id );
            addToApplication( key, ids );

缓存中存放的是 ids。

总结一下:二级缓存的好处有两个:一是大幅度提高性能,降低数据库压力,不用重复查询数据库;二是全自动管理缓存,避免手工管理缓存的复杂度和bug。
 
目前是三级缓存体系
1)对象缓存(ORM层,内部又分成ContextCache上下文缓存和ApplicationCache应用缓存)
2)Action缓存
3)Page缓存
2)和3)是1.7版新增的,
 
下面的文章里面的缓存不属于ORM缓存。同时在1.7正式版里面缓存的名字可能变化。
【从这里开始的以下内容,可能会有变化,是1.7正式版针对1.7beta版有变化】
你可以通过下面两个属性来打开或者关闭Action和Page缓存。
1         /// <summary>
2         /// 是否启用action缓存(如果关闭,所有action缓存都会失效)
3         /// </summary>
4         public Boolean IsActionCache { get { return _isActionCache; } }
5 
6         /// <summary>
7         /// 是否启用页面缓存(如果关闭,所有页面缓存都会失效)
8         /// </summary>
9         public Boolean IsPageCache { get { return _isPageCache; } }

      如果曾经这个Controller被访问过,第一次访问时候的数据将被缓存,直到数据被更新为止,缓存一直有效。下面的代码就是检查缓存。cacheKey 是Action的一个Key,在所有的Action缓存中,找寻缓存是否存在,如果存在的话,取得缓存内容,将内容放入当前的上下文中,接着从缓存里面获得页面的内容。由于直接从缓存中获得了需要的数据,整个过程在这里为止。

 1             // 检查缓存
 2             String cacheKey = null;
 3             if (MvcConfig.Instance.IsActionCache) {
 4 
 5                 IActionCache actionCache = ControllerMeta.GetActionCache( controller.GetType(), ctx.route.action );
 6 
 7                 cacheKey = getCacheKey( actionCache, ctx );
 8                 if (strUtil.HasText( cacheKey )) {
 9                     Object cacheContent = checkCache( cacheKey );
10                     if (cacheContent != null) {
11                         logger.Info( "load from actionCache=" + cacheKey );
12                         context.setContent( cacheContent.ToString() );
13                         getPageMetaFromCache( ctx, cacheKey );
14                         return;
15                     }
16                 }
17             }

 getCacheKey

这里的ActionCache只是在GET的时候起作用。GET一般为了获取内容,POST一般是为了处理事件,所以这里的GET设计是非常好的。

1         private String getCacheKey( IActionCache actionCache, MvcContext ctx ) {
2             if (actionCache == nullreturn null;
3             if (ctx.HttpMethod.Equals( "GET" ) == falsereturn null;
4             return actionCache.GetCacheKey( ctx, ctx.route.action );
5         }

  getPageMetaFromCache

 从缓存里面获取页面内容

1         private static void getPageMetaFromCache( MvcContext ctx, String cacheKey ) {
2 
3             PageMeta p = CacheManager.GetApplicationCache().Get( cacheKey + "_pageMeta" ) as PageMeta;
4             if (p != null) {
5                 ctx.utils.setPageMeta( p );
6             }
7         }

这里的一个概念先说明一下:缓存里面的东西有2种,数据和页面布局.[应该是这样的]

我们在这里根据Action进行数据的获取或者处理,GET是获取,POST是处理。同时将获得的数据放入缓存(Action),以便下次使用,注意,这里是不分GET和POST的。这里的ActionRunner是实行业务逻辑的入口,在这里我们开始执行Action,也就是业务逻辑。同时将业务逻辑的结果放入缓存中。如果页面里面有INPUT的话,由于不能进行简单的替换,我们通过PostValueProcessor进行Input控件的值的设置和输入控件的验证错误的表示(在输入控件旁边标红,错误是前面业务逻辑执行的结果)。关于这部分,也和作者确认过了:以下是邮件原文:

 

这段的内容是做Action处理,加入缓存,最后将页面上的Input设置Value是吧。
例如 ActionRUn的时候做检索,结果加入缓存,然后设置结果页面上的Input?——是的,就是这个流程。其中ProcessPostValue是自动给表单赋值,如果有错误,同时给出错误提示。它的优点在于“自动”,我见过的所有框架,都需要手动在视图中提供错误的占位符,唯独wojilu是自动在form的顶部自动显示。见 http://www.wojilu.com/Common/Page/10 中的效果图:

 

 1         MethodInfo actionMethod = ctx.ActionMethodInfo; // context.getActionMethod();
 2 
 3             // 设值模板并载入全局变量
 4             setControllerView( controller, actionMethod );
 5 
 6             // 运行并处理post值
 7             ActionRunner.runAction( ctx, controller, actionMethod, controller.utils.runAction );
 8             String actionContent = controller.utils.getActionResult();
 9 
10             // 加入缓存
11             if (MvcConfig.Instance.IsActionCache) {
12                 if (strUtil.HasText( cacheKey )) {
13                     addContentToCache( cacheKey, actionContent );
14                     // 加入PageMeta
15                     addPageMetaToCache( ctx, cacheKey );
16                 }
17             }
18 
19             actionContent = PostValueProcessor.ProcessPostValue( actionContent, ctx );

 

     如果这个Action是一个Ajax局部页面的更新的话,我们将这个页面内容直接输出,ShowEnd可以指示后面的过程是否需要继续。showEnd 会跳过下面所有处理器,除了RenderProcessor[这个Processor不在前面所述的列表中,是一个单独的Processor,用来生成HTML字符串] 既然是一个AJAX,我们直接调用最后的RenderProcessor,生成HTML结果。如果是更新一个iFrame,也算是页面的一部分,我们获得需要的框架的HMTL后,同样ShowEnd。如果前面由于某些原因isEnd了,例如错误等等,这里也ShowEnd。不然的话,我们将Action的内容保存到上下文中,等待后续操作。最后如果是POST方法的话,数据可能有改动,所以我们updateActionCache,更新ActionCache。GET的时候不需要更新。 

 1             actionContent = PostValueProcessor.ProcessPostValue( actionContent, ctx );
 2 
 3             if (ctx.utils.isAjax) {
 4                 context.showEnd( actionContent );
 5             }
 6             else if (ctx.utils.isFrame()) {
 7 
 8                 int intNoLayout = ctx.utils.getNoLayout();
 9 
10                 if (intNoLayout == 0) {
11 
12                     String content = MvcUtil.getFrameContent( actionContent );
13                     context.showEnd( content );
14                 }
15                 else {
16                     context.setContent( actionContent );
17                 }
18 
19 
20             }
21             else if (ctx.utils.isEnd()) {
22                 context.showEnd( actionContent );
23             }
24             else {
25                 context.setContent( actionContent );
26             }
27 
28             updateActionCache( ctx );

 这篇文章是MVC的中核,关于数据缓存等内容,等1.7发布后再介绍

转载于:https://www.cnblogs.com/TextEditor/archive/2011/06/21/2085461.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_764099.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大型网站的高可用分析

本文主要分析网站的高可用性&#xff0c;从应用需求、用户角度展开分析。 1.1 高可用性 “高可用性”(High Availability) 通常用来描述一个系统&#xff0c;经过特殊设计&#xff0c;减少停止服务的时间&#xff0c;从而使其服务保持高度的可使用性。 计算机系统的可靠性用平均…

网站安全技术—预防脚本攻击

阅读目录 一&#xff1a;脚本攻击 二&#xff1a;模拟脚本攻击 三&#xff1a;运行效果 四&#xff1a;预防脚本攻击的主要方法 一&#xff1a;脚本攻击 脚本攻击是指将恶意的字符插入到网页中来&#xff0c;浏览器无法验证这些插入的字符&#xff0c;并且会将它们作为网页的一…

We7网站群的共享机制

2019独角兽企业重金招聘Python工程师标准>>> 1.独立部署共享服务器 独立布署共享服务器 共享服务器作为一个独立的服务&#xff0c;允许布署在不同的物理服务器上&#xff0c;从而满足更大负载与更佳性能的要求。 技术支撑&#xff1a;信息打包技术 信息通过数据…

windows server 2008 配置1个服务器多个网站

简略&#xff1a;创建网站的三种虚拟技术&#xff1a;①多IP地址&#xff1b;②一个IP地址多个端口号&#xff1b;③主机头名。1、多IP地址架设多个网站 增加另一个网站&#xff1a;测试成功运行两个网站&#xff1a;2、同一IP地址 多端口3、同一IP地址 不同主机名增加域名…

详细的图文介绍如何利用XAMPP本地建站的环境配置教程

原文:详细的图文介绍如何利用XAMPP本地建站的环境配置教程WordPress 是一个简便快捷&#xff0c;用途广&#xff0c;人气旺的一个开源的博客建站程序。很有很多等您去发现。 简便快捷&#xff1a;在性能上易于操作、易于浏览&#xff1b; 用途广&#xff1a;可以建博客&#xf…

ExtJs学习网站

为什么80%的码农都做不了架构师&#xff1f;>>> ExtJs 入门教程: http://www.cnblogs.com/iamlilinfeng/archive/2012/12/31/2840663.html Sencha Docs 脚本娃娃 (Ext4.1.0 Doc中文版 V1.0.0 Beta) http://extjs-doc-cn.github.io/ext4api/#!/api/Ext ExtJs云盘下载…

网站运维——Chrome 神奇的21秒

2019独角兽企业重金招聘Python工程师标准>>> 1、报障 ①、用户使用chrome进行访问&#xff08;下载&#xff09;&#xff0c;需要等待一段时间&#xff0c;才会提示下载框&#xff0c;debug发现时间都花在Stalled&#xff0c;状态显示pending&#xff0c;无论是跳转…

.net网站常见问题及解决方案

1、解决方法&#xff1a;三个文件放到项目Bin文件夹2、解决方法 &#xff1a; requestValidationMode"2.0" 加到 3、 你在浏览器输入网址报这样的错误 然后打开你的internet信息服务&#xff08;IIS&#xff09;管理器 点击“应用程序池” 在右边找到你的网站名字&a…

检测到目标url存在客户端(javascript)cookie引用_利用Zabbix监控系统自动检测网站运行状态...

我们要检测一个网站是否正常运行&#xff0c;最好的方式是啥呢&#xff1f;我想最直接的办法就是打开浏览器输入要访问的网址&#xff0c;能打开网页说明网站是正常运行的&#xff0c;不能打开了则说明网站存在问题。通过上一篇文章《HTTP协议及其工作原理介绍》&#xff0c;我…

linux搭建cdn教程_云计算视频教程:Linux大型网站高并发架构及自动化运维

随着互联网技术的不断进步和发展&#xff0c;对运维人员提出了更高的要求和挑战&#xff0c;如何才能将运维工作自动化&#xff0c;提升工作的效率&#xff1f;让大家学完后可以具备企业真正的大型网站搭建能力以及自动化运维的实战能力。在企业中运用zabbix监控企业数据&#…

springboot做网站_面试中必须掌握的15道《Spring Boot 高频面试题》

做 Java 开发&#xff0c;没有人敢小觑 Spring Boot 的重要性&#xff0c;现在出去面试&#xff0c;无论多小的公司 or 项目&#xff0c;都要跟你扯一扯 Spring Boot&#xff0c;扯一扯微服务&#xff0c;不会&#xff1f;没用过&#xff1f; Sorry &#xff0c;我们不合适&…

服务器架设了网站还能架设游戏吗,可以在云服务器里架设游戏吗

可以在云服务器里架设游戏吗 内容精选换一换标签是弹性云服务器的标识。为弹性云服务器添加标签&#xff0c;可以方便用户识别和管理拥有的弹性云服务器资源。您可以在创建弹性云服务器时添加标签&#xff0c;也可以在弹性云服务器创建完成后&#xff0c;在云服务器的详情页添加…

javaweb-41:网站注册发送邮件实现

发送带图片及附件的邮件 核心代码&#xff1a; package com.gongyi;import com.sun.mail.util.MailSSLSocketFactory;import javax.activation.DataHandler; import javax.activation.FileDataSource; import javax.mail.*; import javax.mail.internet.InternetAddress; imp…

0基础做网站

1.vscode下载 https://az764295.vo.msecnd.net/stable/784b0177c56c607789f9638da7b6bf3230d47a8c/VSCodeUserSetup-x64-1.71.0.exe 2. vscode安装 3.安装完毕 安装插件 ctrlshiftx 安装liveserver 4. 下载git文件路径 打开终端 altt altN mkdir website 回车 cd website…

《Flash建站技术》系列6-LoadVars数据提交与表单处理

1.LoadVars vs getURL send()getURL有很多的限制&#xff0c;LoadVars则弥补了这一点Flash时间轴脚本:System.useCodepagetrue;signBtn.onReleasefunction(){var formVars:LoadVarsnew LoadVars();formVars.userNamesignForm.userName.text;formVars.userPasssignForm.userPass…

网站架构演变过程-------从传统项目到分布式项目再到微服务

网站架构演变过程 传统项目&#xff08;单点应用&#xff09;----》分布式架构 &#xff08;以项目进行拆分&#xff09;----》SOA架构&#xff08;面向服务架构&#xff09;----》微服务架构 传统项目的架构&#xff1a; 传统项目框架其实就是SSH或SSM,属于单点应用&#x…

推荐12个优秀的 HTML5 网站设计案例欣赏

HTML5 有用很多新特性&#xff0c;网页设计师和开发人员可以使用这些特性制作出更加优秀的网站。这篇文章收集了12个HTML5网站设计案例&#xff0c;让大家感受一下HTML5网站的魅力&#xff0c;一起欣赏。 The Wired Mind Nike Better World Ben The Bodyguard Quentind Analog …

图解大型网站技术架构演变过程!

1、大型网站的特点 高并发&#xff0c;大流量&#xff1a;PV量巨大。即页面浏览量&#xff1b;用户每1次对网站中的每个网页访问均被记录1次。用户对同一页面的多次访问&#xff0c;访问量累计。 高可用&#xff1a;7*24小时不间断服务。 海量数据&#xff1a;需要储存、管理…

用tomcat部署和花生壳内网映射进行远程访问自己电脑上的网站

第一步&#xff1a;将编写好的html页面放在tomcat安装目录Tomcat 6.0\webapps\下[新建个目录如&#xff1a;myhtml]里面。 第二步&#xff1a;在tomcat安装目录[Tomcat 6.0\conf\]下用记事本/其他文本软件打开server.xml文件&#xff0c; 文件末尾</Host>前添加 <Cont…

Python爬虫(三)Beautiful Soup 实战,爬取前程无忧网站

Beautiful Soup介绍 Beautiful Soup提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。Beautiful Soup自动将输入文档转换为Unicode编码&#xff0c;输出文档转换为utf-8编码。Beautiful Soup已成为和lxml、html5lib一样出色的python解释器&#xff0c;为…