当前位置: 首页 > news >正文

.NET企业级应用架构设计系列之结尾篇

首先说点废话。这段时间有挺多新朋友通过CSDN联系到我,大部分是希望我能给他们的学习和工作提点建议。我很感谢这些朋友对我的兴趣,也感谢他们对我的信任。我总是告诉他们一些听过很多遍的道理,现在想想,也许大家以为我在敷衍。但是请一定相信一句话:之所以常常重复,是因为它真的重要。

对于技术上的提高,不外乎多学习、多实践、多思考。学习可以是看书或者上网,看书是大餐而上网就像是快餐。我家里书架上的书已经把书架装得满满的了,以至于最后放了许多不常看或过时了的书到酒柜里。看书并不是要一字一句的看,要有快速浏览反复研究的习惯。另外就是多实践,这个可能是个程序员都能体会到,脱离了实践就无从谈软件开发。实践有多种形式,一是系统的实践,还有测试性的实践,还有熟悉性的实践。针对不同的目的,有不同的方式方法来实践。最后就是多思考,反复琢磨。说得最直接一点,愚者千虑必有一得。不要偷懒,常做重构,并思考重构前后的得失。我一直觉得完成一次精良的重构会让人精神焕发,如果你没有这样的感觉,我只能说你可能不适合写程序。

软件开发,工夫在诗外。当实践的多了,就会觉得以前认为重要的东西慢慢的已经不那么重要了。做一个技术无关的开发者,品位生活和人生的道理。多发展业余爱好,比如画画或者书法或者旅游、摄影之类的。我们需要养成良好的习惯,写字的时候尽量不要有错别字。多看看古典名著、小说散文之类的。还要记得给自己找个漂亮贤惠的女朋友,如果没有家庭而只获得了一堆代码,我想这样的人生并不算完整。

废话说太多了,说说这篇文字的主题。以前发了三篇关于.NET企业级应用架构方面的文章,很多网友以为发完了。其实还没有,这里才是这个系列的终结篇。这里还是围绕着中间层来展开的,顺便说到了前端的状态服务器。中间层承载着许多东西,它前要面对接入服务器(可能是WEB)后面要面对数据持久化系统,所以要稍微复杂一点点了。

层间调用机制

层间调用涉及到的是跨进程的访问,包括前端系统和应用服务器的交互以及应用服务器和后台数据库的交互。在通常的分布式部署方案中,这样的跨进程调用实际上是跨机器的调用,会对网络环境提出一定的要求。

应用服务器对前端表示层提供的接口隐藏了所有后端的处理逻辑,包括业务逻辑以及数据持久化等。前端应用和应用服务器之间的调用效率直接决定了外在的系统效率,必须采用高效的机制以保证前端服务器能最大限度的发挥计算能力。.NET平台是一个完全面向对象的分布式平台,它提供了许多优秀的特性以实现可扩展的大型分布式系统,其中包括异步调用机制。

通过异步调用Web Service或远程对象的方式可以发挥IIS线程池的最大潜力,因为一台配置固定的IIS Web服务器能运行的最大线程数是有限的,通常不应该配置过高。ASP.NET 2.0的页面生命周期中允许注册异步调用事件,对应用服务器的调用可以安排为异步执行。其实,应该在尽量多的地方采用异步调用机制,包括数据库访问。这样可以提高系统整体的并行度,从而达到更大的系统吞吐量。如果表示层对业务逻辑层采用同步访问的方式,就没有必要将业务逻辑层单独放在应用服务器上运行,将业务逻辑和表示层放在同一个进程空间中运行还能提高部分性能。只有采用异步调用方式才能真正体现出应用服务器的价值,避免服务器处于假忙碌状态。

前端系统调用应用服务器的Web Service的时候要注意一个小问题:HTTP双连接限制。连接到web资源的默认双连接限制可以通过一个名为connectionmanagement的配置元素来控制。connectionmanagement设置允许添加要让其采用非默认连接限制的站点的名称。

数据访问层

之所以用“数据访问层”而不是数据持久层,是因为我通常将数据库系统作为数据持久层,数据访问层是位于应用服务器和数据持久层之间的调用接口,它对外隐藏了数据持久层的细节。Java应用在数据访问层通常采用O-R Mapping来做,业务逻辑被实现为许许多多的业务实体。.NET本身没有对O-R Mapping提供任何支持,对数据访问层提供的是一套底层API,包括ADO.NET和Data Access Application Block。

在.NET开源社区,有几个开源框架提供了ORM支持,比如NHibernate、iBATIS.NET。NHibernate诞生于.NET 1.0时代,是一种“全自动”的ORM框架,它无需开发人员编写任何SQL语句。而iBATIS.NET是一种更加灵活的“半自动”数据映射持久化框架(Data Mapper Framework),以SQL开发的工作量和数据库移植性上的让步给系统设计提供了更大的自由空间。另外,DevExpress XPO是一款商业ORM产品,是一个完全透明的数据持久层解决方案,无须建表、建字段、取数据之类的所有数据库相关操作,但需要200$的价格。

使用ORM框架有两个好处,一是可以实现流行数据库的移植,开发人员编写的代码是数据库无关的。这样就可以方便的在数据库之间切换,有利于软件开发商应对众多客户的不同需求。另一个好处是开发人员可以不用了解SQL的细节,降低了SQL方面的学习曲线。同时把实现关注点集中在业务逻辑上,而不是数据持久化上。再者,ORM提供的是一个面向对象的体系,可以采用更多的面向对象思维来实现系统的业务逻辑。

但任何灵活的东西总是有副作用的,ORM的副作用主要表现在性能上。ORM必然导致更多的网络传输,因为数据持久在ORM里面通常被分解成了许许多多的数据库调用。同时,使用ORM也不利于数据库引擎发挥计算能力,数据库变成了一个“瘦服务器”。虽然ORM框架能屏蔽SQL细节,降低了SQL的学习曲线,但同时却带来了框架本身的学习曲线问题。再者,由于对系统内部处理细节的不熟悉,开发人员难以写出高效的代码。另外,ORM框架如果只是对数据库表的映射的话,并没有节约多少开发时间,而且数据库设计的变动会经常引起代码同步的问题。

整体上来说,ORM提供的是一种灵活的高端解决方案,适合软件企业在长期开发的过程中为应对各种不同的客户需求而实现平滑的数据库切换。这也是为什么大多数Java应用系统采用ORM的原因,因为Java体系是一个可移植的解决方案,可以为软件企业带来“客户无关”的开发能力。但可移植总是带来性能上的下降(没人愿意承认),虽然不可移植的代码不一定绝对快过可移植代码。既然选择.NET了,可能在移植性上本身就不是很在乎了。

状态服务器

状态保存的第一个原则是尽量保存少的数据,对于大对象不推荐保存为状态。在实现过程中需要对状态保存做一层封装,让状态保存和其它实现逻辑分离开来。对于.NET状态保存机制,涉及到采用进程内还是采用进程外的问题。

进程外状态保存可以确保应用更新的时候不会影响在线用户的状态。因为电子商务网站的业务变化相对来说多一些,经常会有更改程序的可能。如果采用进程内状态保存机制,每次部署更新的时候所有旧状态都将被清空。

进程外状态保存实现的是一个无共享架构(Share Nothing Architecture),可以增加系统的分布性,有利于提升系统的横向扩展能力。Web Farm中的服务器也将成为真正对等的实体,负载均衡器可以采用更加简单的角度算法。在初期系统服务器设备不足的情况下可以和应用服务器或者WEB服务器部署在同一台机器上。

但进程外保存可能引入性能问题,因为中间有跨进程的数据交换。进程外保存还带来了维护上的麻烦,部署的时候也增加了复杂度。但对本案来说这些都不是问题,采用尽量小的数据保存可以减小性能上的影响,维护和部署的问题也都是时间问题而已。

开发期可以不用对采用何种机制保存状态作太多处理,只需要在部署的时候做相应的调整即可。需要注意的是,只有Serializable对象可以进程外保存为状态。初期系统压力不大的时候可以采用ASP.NET State Server这样的轻量级方案,系统负载增加后可以采用进程外SQL Server来做状态服务器。

服务器群集

服务器群集可以提供一个高可用、高可靠、可伸缩的计算环境。Windows Server 2003 Enterprise Edition提供了NLB以及MSCS支持负载均衡以及服务器集群策略。这是一种软件解决方案,在系统初期压力不大的情况下可以采用此种方式来进行系统横向扩展(Scale Out)。随着系统负载不断增加,可以使用更多的服务器群集和硬件负载均衡器来分配负载。最终的系统性能瓶颈将会推到磁盘读写设备上。

本系统的服务器共有四种:前端WEB服务器,旁边的状态服务器,中间的应用服务器,后端的数据库服务器。其中,状态服务器没必要做集群,因为状态服务一方面要为所有的消费者提供同一的状态数据,另一方面因为状态数据一般都很小。其余几种服务器都是系统中的关键设施,任何一个环节出现问题都可能导致系统整体表现的急剧下降。

WEB服务器群集构建的是展现层的对等计算体系(WEB Farm),它的吞吐量直接决定了系统的整体性能。应用服务器的群集和WEB服务器差不多,所有计算实体均为对等单元。这样,单台WEB服务器和应用服务器都可以随时从群集中分离出来进行离线更新(在线更新有可能会失败或者引起客户端表现异常)。但这需要集群软件或集群硬件的支持,Windows 2003 Server NLB可以允许集群运行状态下进行扩展或压缩。数据库方面,SQL Server 2005可以配置为最多8个结点的集群。


OVER

BTW:湖南广播电台快乐975(快乐就起舞)的高洁主持的一挡音乐节目挺好听。

相关文章:

  • 谱聚类
  • XX^{T} 和 X^{T}X 的关系
  • Think in Code,用代码思考
  • PCA 主成分分析
  • 范数的共轭函数
  • Python几种开发工具介绍
  • 对偶锥与自对偶
  • VC2005使用SQLite,适用于WIN32以及WINCE
  • 凸函数的梯度的单调性 (Monotonicity of gradient)
  • 恢复Debian下root用户bash高亮显示
  • SVM——支持向量机
  • VMWare桥接模式虚拟机网络配置
  • SVM——支持向量机【Latex原稿】
  • VMWare Pocket ACE实例包的创建
  • AdaBoost 算法
  • ----------
  • Google 是如何开发 Web 框架的
  • (十五)java多线程之并发集合ArrayBlockingQueue
  • cookie和session
  • Django 博客开发教程 8 - 博客文章详情页
  • flutter的key在widget list的作用以及必要性
  • gcc介绍及安装
  • HashMap ConcurrentHashMap
  • nodejs实现webservice问题总结
  • opencv python Meanshift 和 Camshift
  • PHP面试之三:MySQL数据库
  • SpingCloudBus整合RabbitMQ
  • 解析带emoji和链接的聊天系统消息
  • 老板让我十分钟上手nx-admin
  • 如何设计一个微型分布式架构?
  • 通过几道题目学习二叉搜索树
  • 我建了一个叫Hello World的项目
  • 由插件封装引出的一丢丢思考
  • Oracle Portal 11g Diagnostics using Remote Diagnostic Agent (RDA) [ID 1059805.
  • ​ 无限可能性的探索:Amazon Lightsail轻量应用服务器引领数字化时代创新发展
  • # 飞书APP集成平台-数字化落地
  • #LLM入门|Prompt#2.3_对查询任务进行分类|意图分析_Classification
  • (day 2)JavaScript学习笔记(基础之变量、常量和注释)
  • (Matalb时序预测)PSO-BP粒子群算法优化BP神经网络的多维时序回归预测
  • (ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY)讲解
  • (读书笔记)Javascript高级程序设计---ECMAScript基础
  • (分类)KNN算法- 参数调优
  • (附源码)springboot太原学院贫困生申请管理系统 毕业设计 101517
  • (译) 函数式 JS #1:简介
  • (转) Face-Resources
  • (转)【Hibernate总结系列】使用举例
  • (转)EOS中账户、钱包和密钥的关系
  • .mat 文件的加载与创建 矩阵变图像? ∈ Matlab 使用笔记
  • .NET Core 中的路径问题
  • .NET Framework 和 .NET Core 在默认情况下垃圾回收(GC)机制的不同(局部变量部分)
  • .Net 路由处理厉害了
  • .NET/C# 利用 Walterlv.WeakEvents 高性能地中转一个自定义的弱事件(可让任意 CLR 事件成为弱事件)
  • .NET教程 - 字符串 编码 正则表达式(String Encoding Regular Express)
  • .NET连接数据库方式
  • .py文件应该怎样打开?