我的架构经验小结(四)-- 实战中演化的三层架构

简介: 在06、07年的时候,我写过一些关于三层架构方面的东西(参见这里),现在看来,觉得有很多实用性的内容需要补充到里面去。我们还是先从架构图看起,然后一一解释,你就会发现相比于两年前,这个架构做了哪些变化和调整。

      在06、07年的时候,我写过一些关于三层架构方面的东西(参见这里),现在看来,觉得有很多实用性的内容需要补充到里面去。我们还是先从架构图看起,然后一一解释,你就会发现相比于两年前,这个架构做了哪些变化和调整。

一.三层架构图

 

二.系统各层次职责

1.UIUser Interface)层的职责是数据的展现和采集,数据采集的结果通常以Entity object提交给BL层处理。

  Web表示我们常用的B/S应用,WinForm表示我们常用的C/S应用。

Network层以Socket的方式提供服务给客户端。

Service层用于将业务或数据资源发布为服务(如WebServices)。

 

2.BLBusiness Logic&Platform层的职责是按预定的业务逻辑处理UI层提交的请求,并对核心资源进行管理。

1Business Function 子层负责基本业务功能的实现。

2Business Flow 子层负责将Business Function子层提供的多个基本业务功能组织成一个完整的业务流。

3Platform子层用于统一管理有状态的数据和资源。

4)注意:Transaction只能在BusinessFlow/Platform层开启。

5BL最好是没有状态的,而必需的状态管理可以放到Platform中的某些模块/子系统进行。如此可增强系统的可伸缩性。

6Cache子层用于缓存系统常用的数据信息,Cache对于提供系统的并发量和吞吐能力起到至关重要的作用。Cache可以分为以下几类:

StaticCache

HotCache

SyncEntityCache

RefreshCache 

SubObjectCache

   StaticCache:如果某数据表中的数据是静态的、不会发生变化的,那就非常容易,我们只需要在系统启动的时候,将其加载到内存,以后每次从内存读取数据即可。

   HotCache:如果数据表中的记录非常多,并且修改方面只会有Insert操作,那么我们可以使用HotCache,把那些经常使用的记录缓存在内存中,并且可设定超时机制删除内存中长期不使用的记录。

   SyncEntityCache:如果我们的某个数据表中的数据会发生变化(增删改),但是变化的频率比较低,但是我们的系统对这个表的数据的实时性的敏感度也特别高,那这时候我们就需要用到【实时同步的实体缓存】,这个缓存中的数据在任何时候都与数据表中的数据是完全一致的。

   RefreshCache:如果数据表中的数据会发生变化(增删改),但是变化的频率非常低,而恰巧我们的系统对数据实时性的敏感度也不是特别高,那我们可以使用定时刷新的缓存。

   SubObjectCache:如果某个数据表的修改经常是InsertUpdate操作,但是无论如何Update,每条记录有些固定栏位的值都是不会发生变化的,那我们可以把这些不会发生变化的栏位封装在一个【子对象SubObject】中,然后在内存中缓存这些子对象。

 

3DataAccess层的职责是提供全面的资源访问功能支持,并向上层屏蔽资源的来源。

BEMBusiness Entity Manager)子层负责从数据库中存取资源。

DB Adapter子层负责屏蔽数据库类型的差异。

ORM子层负责提供对象-关系映射的功能。

Relation子层提供ORM无法完成的基于关系(Relation)的数据访问功能。

 

4Entity侧层跨越UI/BL&Platform/DataAccess层,在这些层之间传递数据。Entity侧层中包含三类Entity,如下图所示:

 

5.DB层可以采用数据库分散放置、读写分离策略来支持超大并发。图中数据库名称,M代表Master(主库),S代表Slave(从库)。

 

6.Tools层,架构图中还一个虚线表示的Tools层,之所以用虚线,是因为它并不真的是系统交付的一部分,它并不实现系统的逻辑功能。但它的存在是如此的重要,特别是在我们的开发和测试阶段。它的主要作用有:

1DataMonitor:能将数据库中最重要的信息方便的呈现给工程师,比如重要表和超大表的记录数等。

2DataChecker直接对数据库中的数据进行完整性、一致性检查。使我们能最及时的发现业务逻辑在数据处理方面的重大失误和错漏。

3DataRepairer:当发现了数据错误并对程序的bug进行修正后,Tools能够对数据进行补充或修复。以使后续开发和测试能立即继续进行。

(4)上述的三个工具构成了一个可测试、可调试的环境的基础,我们可能还要写一些额外的工具为方便地测试及调试提供支持。

     只有有过深切体会的人才会知道,一个可测试、可调试的环境对于快速定位和解决bug是多么重要。

 

三.Aspect

Aspect贯穿于系统各层,是系统的横切关注点。通常采用AOP技术来对横切关注点进行建模和实现。

1Securtiy Aspect:用于对整个系统的Security提供支持。

2ErrorHandling Aspect:整个系统采用一致的错误/异常处理方式。

3Log Aspect:用于系统异常、日志记录、业务操作记录等。

1)通常我们会记录相邻两层的交互接口所引发的所有异常的详细信息,包括方法调用的堆栈帧、调用方法的参数的具体值。(参考这里

2)通常我们会跟踪相邻两层的交互接口的每个方法执行所消耗的时间,用于检查系统的性能瓶颈在哪些地方。(参考这里

3)通常我们会记录所有数据库访问异常的详细信息,包括sql语句内容、各参数的具体值。(参考这里

4)在测试阶段,通常我们会记录所有每个事务访问数据表的顺序,通过对比这些顺序,我们可以发现可能出现死锁的地方,从而加以调整。(DataRabbit内置支持

5)另外,一些重要的作业操作我们也会记录到日志。

 

四.规则

1.系统各层次及层内部子层次之间都不得跨层调用。

2.使用Entity object 在各个层之间传递数据,而不是关系型的DataSet。只有在特殊情况下,才将UI绑定到DataTable,比如返回的结果集没有Entity与之对应的时候。

3UI层和BL层禁止出现任何SQL语句。

4.对于每一个数据库表(Table)都有一个DB Entity class与之对应,针对每一个Entity class都会有一个BEM Class与之对应。

5.有些跨数据库或跨表的操作(如复杂的联合查询)也需要由相应的BEM Class来提供支持。

6.对于相对简单的系统,可以考虑将Business Function子层和Business Flow 子层合并为一个。

 

五.错误与异常

        异常可以分为系统异常(如网络突然断开)和业务异常(如用户的输入值超出最大范围),业务异常必须被转化为业务执行的结果。

1.     DataAccess层不得向上层隐藏任何异常(该层抛出的异常几乎都是系统异常)。

2.     要明确区分业务执行的结果和系统异常。比如验证用户的合法性,如果对应的用户ID不存在,不应该抛出异常,而是返回(或通过out参数)一个表示验证结果的枚举值,这属于业务执行的结果。但是,如果在从数据库中提取用户信息时,数据库连接突然断开,则应该抛出系统异常。

3.     在有些情况下,BL层应根据业务的需要捕获某些系统异常,并将其转化为业务执行的结果。比如,某个业务要求试探指定的数据库是否可连接,这时BL就需要将数据库连接失败的系统异常转换为业务执行的结果。

4.     UI(包括Service)除了从调用BL层的API获取的返回值来查看业务的执行结果外,还需要截获所有的系统异常,并将其解释为友好的错误信息呈现给用户。

5.     WebService的参数或返回值需要是复杂类型――即架构图中的Service Entity,则Service Entity应该在对应的*.EntranceParaDef.dll中定义。WebService定义的方法中的复杂类型应该使用Xml字符串代替,而Xml字符串和复杂类型对象之间的转换应当在*.Entrance.dll中实现。

 

      最后,系统架构的思想是重要的,但是架构不能纸上谈兵、不能脱离实践。

      不知您有何补充或建议,请指点一二,呵呵。

 

目录
相关文章
|
1月前
|
Cloud Native Java API
聊聊从单体到微服务架构服务演化过程
本文介绍了从单体应用到微服务再到云原生架构的演进过程。单体应用虽易于搭建和部署,但难以局部更新;面向服务架构(SOA)通过模块化和服务总线提升了组件复用性和分布式部署能力;微服务则进一步实现了服务的独立开发与部署,提高了灵活性;云原生架构则利用容器化、微服务和自动化工具,实现了应用在动态环境中的弹性扩展与高效管理。这一演进体现了软件架构向着更灵活、更高效的方向发展。
|
7天前
|
运维 NoSQL Java
后端架构演进:微服务架构的优缺点与实战案例分析
【10月更文挑战第28天】本文探讨了微服务架构与单体架构的优缺点,并通过实战案例分析了微服务架构在实际应用中的表现。微服务架构具有高内聚、低耦合、独立部署等优势,但也面临分布式系统的复杂性和较高的运维成本。通过某电商平台的实际案例,展示了微服务架构在提升系统性能和团队协作效率方面的显著效果,同时也指出了其带来的挑战。
40 4
|
1月前
|
存储 设计模式 前端开发
什么是SpringMVC?简单好理解!什么是应用分层?SpringMVC与应用分层的关系? 什么是三层架构?SpringMVC与三层架构的关系?
文章解释了SpringMVC的概念和各部分功能,探讨了应用分层的原因和具体实施的三层架构,以及SpringMVC与三层架构之间的关系和联系。
21 1
什么是SpringMVC?简单好理解!什么是应用分层?SpringMVC与应用分层的关系? 什么是三层架构?SpringMVC与三层架构的关系?
|
3月前
|
运维 Cloud Native 开发者
云原生时代下的微服务架构演化之路
【8月更文挑战第20天】在数字化转型的浪潮下,企业级应用纷纷拥抱云原生架构。本文将深入探讨微服务架构在适应云原生环境的过程中所面临的挑战与机遇,并分析如何通过优化设计、容器化技术及自动化运维,实现高效、灵活且可靠的系统构建。
178 65
|
1月前
|
存储 前端开发 API
DDD领域驱动设计实战-分层架构
DDD分层架构通过明确各层职责及交互规则,有效降低了层间依赖。其基本原则是每层仅与下方层耦合,分为严格和松散两种形式。架构演进包括传统四层架构与改良版四层架构,后者采用依赖反转设计原则优化基础设施层位置。各层职责分明:用户接口层处理显示与请求;应用层负责服务编排与组合;领域层实现业务逻辑;基础层提供技术基础服务。通过合理设计聚合与依赖关系,DDD支持微服务架构灵活演进,提升系统适应性和可维护性。
|
2月前
|
运维 持续交付 API
深入理解并实践微服务架构:从理论到实战
深入理解并实践微服务架构:从理论到实战
128 3
|
2月前
|
存储 缓存 负载均衡
亿级流量架构理论+秒杀实战系列(二)
亿级流量架构理论+秒杀实战系列(二)
|
2月前
|
运维 监控 持续交付
深入浅出:微服务架构的设计与实战
微服务,一个在软件开发领域如雷贯耳的名词,它代表着一种现代软件架构的风格。本文将通过浅显易懂的语言,带领读者从零开始了解微服务的概念、设计原则及其在实际项目中的运用。我们将一起探讨如何将一个庞大的单体应用拆分为灵活、独立、可扩展的微服务,并分享一些实践中的经验和技巧。无论你是初学者还是有一定经验的开发者,这篇文章都将为你提供新的视角和深入的理解。
75 3
|
2月前
|
SQL 缓存 运维
亿级流量架构理论+秒杀实战系列(一)
亿级流量架构理论+秒杀实战系列(一)
|
2月前
|
消息中间件 应用服务中间件 数据库
亿级流量架构理论+秒杀实战系列(三)
亿级流量架构理论+秒杀实战系列(三)