秋色园QBlog技术原理解析:系列终结篇:最后的AOP策略(十九)

简介:
开篇闲话:
好几个月没写文章了,从9月15号发布新浪“微博粉丝精灵”V1.0后,持续的几个月都在折腾它,现在都折腾到V3.4版本了。
因此,本篇迟来了三个月了,同时,本篇也是本系列的最后一篇了,也是秋色园最后杀手锏,霸气总该是要外露的。
 
上节回顾:
秋色园 QBlog 将一些简单频繁的数据,借用文本外储,来分减一些压力,从而为并发降温,保障网站的顺利运行
 
本节概要:
文本外储,在一定程序上解决了问题,但是,由于当时技术的薄弱,文本存储无法处理查询排序等问题,导致主体文章表依旧存在access黄金4K问题。
在压力之下,又要处理查询排序等复杂动作,于是苦冥三日,终得一招。
最后的招数:Access与SQLite合体,最后的AOP策略
 
本节内容[AOP+数据库组合+策略分析+最终实现]:
 
一: CYQ.Data  数据框架中的AOP思路简述
 
1:关于最早期CYQ.Data数据框架实现AOP的思想文章,见: AOP 你想干什么 IOC 你服务什么
2:简单的再描述一下:
CYQ.Data数据框架通过在内部所有数据库的操作方法中,内置2两个AOP方法,来实现方法的拦截调整,简单的方法体如下:
public   bool  Fill( object   where params   object [] aopInfo)
{
            _Aop.Begin(Aop.AopEnum.Fill,_TableName, aopInfo);//AOP开始时的拦截

            
bool  result  =  正常的方法体代码及操作结果

            _Aop.End(Aop.AopEnum.Fill, result, aopInfo);//AOP在方法结束时再一个调用
            
return  result;
}
通过这样的简单的拦截,可以轻松的在数据库操作前,先处理事情,在数据库操作后,再处理事情。
详情代码可下载:CYQ.Data V3.0 免费开源版本。
 
二:QBlog数据库的决择
 
首先:秋色园主体数据库是Access,当然是近乎每个表1个数据库,因此,是多个access数据库。
然后:秋色园再伴随着“文本数据库”,来分压一些简单读写的数据。
最后:决择是SQLite数据库,以分压用户的文章压力(没事多体验下其它数据库)。
目前秋色园的内存情况是:VPS总体是512M内存。
秋色园QBlog占用200M以下内存。
微博粉丝精灵占用200M以下内存。
系统默认开销也得占用200M左右。
剩下渣都没的剩了,连“爱说说”也因内存不足,暂时停掉了,当然不可能选用其它大型数据库了。
 
三:实际场景的考虑
 
秋色园是一个多用户博客,而博客系统,每一个用户的数据,基本上是相互独立的,简单的说:多用户可以化整为0,变成无数个单用户博客,然后无数个单用户博客,组合起来,就变成多用户博客。
曾经有这么一种设想:
1:有那么一个数据挂靠平台,博客只要有一份即可。
2:当我来到其它平台交流时,我只要选择授权挂靠就好了。
是不是有点像微博?博客园发展为数据平台,像51cto,csdn等,只要变成API开发者平台就行了,授权后数据直接对接过去,也省的两边发文章,是不?
因此,如果让我重新设计一个新的博客系统,我可能会考虑[单]用户组装形式,这样方便数据独立[进行外挂、内接、或私有成独立单用户博客系统]。
想的有点多,回到正常的思路上考虑:
基于“文本数据库”减压方案的延申,如果,把每个用户的文章独立分散,而每个用户的文章又能自由的查询排序,最终的效果就是:为每个用户建一个sqlite数据库文件保存数据。
这样的话,等于每个用户产生一个1个独立数据库,因此,除了首页,其它访问都变成了单用户博客系统,基本上也就没什么压力了。
 
想归这么想,总会带来一些疑问的:
1:数据库文件会不会产生太多?
其实也不多,十万个文件不算啥,按下日期、用户ID、哈唏、用户名等多种方式分布到不同文件夹下,一个文件夹也顶不了多少个文件。再说,有10万用户你都超越博客园了,估计开始偷笑了。
2:聚合内容怎么办?如网站首页聚合多个用户的文章显示?
这个没啥,因为除了每个用户独立的数据库文件,还有总的access数据库,聚合时读access即可。
3:这么说数据变成一式两份?
这个没错,是成两份了,不过目前策略,文章的内容(数据比较多)独立仅1份,因此占不了多少空间。
4:两个数据库,如何同步?同时写两份?
写两份是要,当然就不可能同时写了,因为同时写,对原来的access还是存在多用户并发操作,具体看下面的详情。
5:这样系统不会变的很乱吧?
“最后的AOP策略”以插件的方式处理这种问题,一插,搞定,一拔,还是正常的,所以对系统完全不影响。
 
四:最后的AOP策略的实现
 
1:创建新的项目,开始AOP切换项目。
由于AOP内置以反射调用DLL插件式注入,因此原有逻辑代码不改变,只要开新的项目处理即可。
然后配置文件配置一下相关的调用即可,各家实现不一,仅供参考说明:
<add key="Aop" value="Web.Aop,Web.Aop.AopAction"/>
2:为每个用户创建SQLite数据库
主要为三步:
1:创建SQLite数据库;
2:创建文章表结构;
3:将主表的原有的用户文章复制一份到新数据库去。
以下为代码节选:
再接下来,就是处理各种“增删改查”的数据库同步问题:
3:增加数据的处理流程:
先看一个插入代码AOP的伪方法:
public bool Insert(params object[] aopInfo)
{
            _Aop.Begin(Aop.AopEnum.Insert,_TableName, aopInfo);//AOP开始时的拦截,写SQLite数据库

            
bool result = 正常的方法体代码及操作结果// 正常的写Access数据库

            _Aop.End(Aop.AopEnum.Insert, result, aopInfo);//AOP在方法结束时再一个调用SQLite数据库
            
return result;
 }
这果按这原有的AOP逻辑,将造成一种情况,写完SQLite数据后,同时又将继续写Access数据库,这明显是有问题的,假设多个用户发布文章,虽然SQLite是写在不同的数据库,可是同时写主数据库Access,必然又出现并发4K问题。
为此,对于主Access,必须使用新的方式来实现,再借文本,定时插入:
实现原理:
A:当写完SQLite数据库后,将文章内容写成json输入到临时文本中。
B:写完直接跳过写Access数据库,直接返回。
C:定时器,定时从文本中按顺序执行插入或修改的内容。
简单的说:把并发写Access数据库,变成队列式,1条接1条的插入,如此一来,并发写就解决了。
为了适应这种变化,原有的AOP必须稍的改进,AOP.Begin方法需要增加返回值,以便作为条件,可以跳过下面的执行,为此,增加了返回值的枚举:
    /// <summary>
    /// Aop函数的处理结果
    /// </summary>
    public enum AopResult
    {
        /// <summary>
        /// 本结果将执行原有事件,但跳过Aop.End事件
        /// </summary>
        Default,
        /// <summary>
        /// 本结果将继续执行原有事件和Aop.End事件
        /// </summary>
        Continue,
        /// <summary>
        /// 本结果将跳过原有事件,但会执行Aop End事件
        /// </summary>
        Break,
        /// <summary>
        /// 本结果将直接跳出原有函数的执行
        /// </summary>
        Return,
有了返回值,插入后,跳过Access的插入执行,返回成功即可。
参考代码:
4:删除数据的处理流程:
当用户操作删除文章时,默认Begin不执行,先走原来流程,删除主表,再从End事件删除SQLite表。
参考代码:
5:修改数据的处理流程:
由于Access已改装成队列式执行,因此更新流程需比插入多了一步要考虑的:
如:用户更新了A字段,这时队列还没更新进数据库,然后用户又更新了B字段。
这时候,只能产生2个更新文件到队列中,后者B不能直接复盖A,不然会造成A的修改丢失。
参考代码:
6:数据的查询功能:
根据条件判断,如果是单用户的数据,直接Begin方法查完SQLite后返回即可。
示例的查询代码:
至此,整体的最后的AOP策略处理就基本结束了。
 
总结
通过AOP策略,将用户博客变成单数据库查询,直接跳过主数据库Access查询,基本灭掉了Access被并发的机率,同时新的策略,将Access数据库的并发写,变更成队列式写,因此不再有并发锁库出现,对于需要综合数据查询的,仍然返回Access数据库查询综合数据,由于整体是插件式操作,如果有一天access升级换成其它数据库,不需要SQLite配合时,只要注释配置文件代码将插件去掉,依旧是正常的运行,如果用户想独立出去弄个域名,直接把sqlite数据库下载回去即可。
 
到此,秋色园技术原理系列估计就写到这里了,本系统的技术内幕,基本也外露完了。
 
感谢网友对本系列的支持!!!
 
历史文章回顾:
1:  秋色园QBlog技术原理解析:开篇:整体认识(一) --介绍整体文件夹和文件的作用
2:  秋色园QBlog技术原理解析:认识整站处理流程(二) --介绍秋色园业务处理流程
4:  秋色园QBlog技术原理解析:UrlRewrite之URL重定向体系(四) --介绍URL如何定位到处理程序
5:  秋色园QBlog技术原理解析:Module之页面基类设计(五) --介绍创建基类和自定义生命周期
12: 秋色园QBlog技术原理解析:性能优化篇:字节与缓存与并发(十二) --介绍性能优化:字节,并发及缓存
附章:
 






     本文转自cyq1162 51CTO博客,原文链接:http://blog.51cto.com/cyq1162/739559 ,如需转载请自行联系原作者


相关文章
|
29天前
|
人工智能 搜索推荐 安全
打造精准营销!营销电子邮件以客户为中心策略解析!
营销电子邮件是数字营销的核心,用于建立客户关系、推广产品和服务,提高品牌忠诚度和转化率。它们在客户旅程中扮演关键接触点角色,如欢迎邮件、购物车提醒和个性化推荐。电子邮件营销能提升品牌知名度,细分营销可带来760%的收入增长。然而,大量邮件可能导致邮件过载,缺乏个性化可能引起收件人反感,甚至网络安全问题。收件人和IT团队可通过过滤、优化设置、启用2FA等措施改善体验。营销团队则需克服管理、个性化和法规遵从等挑战,采用先进技术同时确保隐私和安全,以同理心驱动的策略建立客户连接,实现业务成功。
21 1
打造精准营销!营销电子邮件以客户为中心策略解析!
|
1月前
|
缓存 监控 NoSQL
解析Redis缓存雪崩及应对策略
解析Redis缓存雪崩及应对策略
|
25天前
|
存储 JSON 安全
【C++ 泛型编程 综合篇】泛型编程深度解析:C++中的五种类型泛型策略综合对比
【C++ 泛型编程 综合篇】泛型编程深度解析:C++中的五种类型泛型策略综合对比
65 1
|
15天前
|
负载均衡 算法 Linux
深度解析:Linux内核调度器的演变与优化策略
【4月更文挑战第5天】 在本文中,我们将深入探讨Linux操作系统的核心组成部分——内核调度器。文章将首先回顾Linux内核调度器的发展历程,从早期的简单轮转调度(Round Robin)到现代的完全公平调度器(Completely Fair Scheduler, CFS)。接着,分析当前CFS面临的挑战以及社区提出的各种优化方案,最后提出未来可能的发展趋势和研究方向。通过本文,读者将对Linux调度器的原理、实现及其优化有一个全面的认识。
|
23天前
|
算法 IDE Linux
【CMake 小知识】CMake中的库目标命名和查找策略解析
【CMake 小知识】CMake中的库目标命名和查找策略解析
98 1
|
26天前
|
SQL 安全 网络安全
构筑数字堡垒:网络安全漏洞解析与防御策略
在数字化时代,网络安全已成为维护信息完整性、保障用户隐私和确保商业连续性的关键。本文将深入探讨网络安全领域的核心议题—安全漏洞及其防御机制。通过分析常见网络攻击手段,如SQL注入、跨站脚本攻击(XSS)及拒绝服务(DoS)攻击,揭示其背后的原理与潜在危害。同时,文章将重点介绍加密技术的种类和应用场景,以及如何通过强化安全意识,构建多层次的防御体系来有效预防和应对网络安全威胁。本研究旨在为读者提供一份系统性的网络安全防护指南,帮助个人和组织在不断演变的威胁面前保持警惕,并采取适当的安全措施。
20 2
|
1月前
|
运维 监控 安全
运维工程师的转型与升级:解析35岁半衰期现象及其应对策略
运维工程师的转型与升级:解析35岁半衰期现象及其应对策略
82 1
|
1月前
|
运维 监控 网络虚拟化
|
2月前
|
缓存 前端开发 JavaScript
深入解析前端性能优化策略
本文将探讨前端性能优化的关键策略,包括减少HTTP请求、使用CDN加速、缓存优化、代码压缩等方面的技术手段,帮助前端开发者提升网站性能和用户体验。
|
3月前
|
Go
Go反射深度解析:规则与优化策略
Go反射深度解析:规则与优化策略
17 0

推荐镜像

更多