`

关于系统性能的思考

阅读更多

 在评价一个系统的时候,性能指标是很重要的,那么在当前J2EE的系统开发当中,如何来提高系统的性能呢?我觉得应该从对象管理入手,从对象的生命周期开始。虽然大家可能会说,Java有垃圾收集器,我们的对象的生命周期不需要我们自己管理,但是如果要是真的过分依赖java语言本身的特性,那么我相信,系统的性能肯定好不到哪去。所以,下面就主要从三个方面入手来说一下我的想法。

第一:容器化系统功能性组件

    在每个系统中,我想都会存在功能性的组件,比如当前开发当中的service,这些功能性的服务一般来说都是没有状态的,是可以多用户共享的,这种共享的服务对象,我们也需要将其进行统一的管理,幸运的是目前已经存在很多这样的管理功能性服务的框架或者容器,比如目前比较流行的各种IOC容器,或者是重量级的EJB容器,它们都提供了对系统中各种服务组件的管理。

第二:缓存化业务对象

  在说缓存之前,我不得不说一下面向对象的设计,可能有些人认为,为什么缓存会与面向对象的设计扯上关系,其实这就是缓存的关键。首先设想一下,如果开发系统的过程中,都是采用面向过程,面向数据库的思维编程,每一次业务操作,我们都是调用通过数据库操作来完成,这其实就是POEAA中的事务脚本,只适合一些简单的系统的开发,或者一个项目中,比较简单模块的开发,对于复杂的模块,更好的方式就是采用面向对象的方法来进行开发。

  好了,说到了面向对象的设计问题,至于这个问题已经有很多书籍以及很多人讨论了很多年了,就我个人来说,我觉得采用DDD建模是目前比较适合的一种方式。DDD中涉及到得每种模式或者说是每一种模型元素对于缓存设计来说都是很重要的,下面我说说我的想法:

 首先我说一下关于聚合的问题,为什么说聚合对于缓存非常重要呢?这其实涉及到了一种控制访问的问题,一个聚合根控制了对整个聚合的访问,要想访问聚合里的对象必须要通过聚合的根。

 好了,我们以一个实例来说话,比如一个论坛的设计,论坛中有Forum以及ForumState对象,Forum对象是聚合的根,是一个实体模型,而ForumState是一个值对象,并且是属于Forum这个聚合根的子对象,我们把ForumState对象从Forum对象分离出来,好处主要有两个,从事务的角度来说,当我们更新ForumState对象的时候,不用锁住Forum对象,从缓存设计的角度来说,当我们更新ForumState对象的时候不用刷新Forum对象的缓存,因为Forum不是经常改变的,所以不必要因为经常改变属性的改变而改变。那么具体怎么来设计呢?我们可以这样做,在ForumState对象中设置一个状态位,表示它的状态是否已经改变,当Forum状态发生改变,比如有人创建新的帖子或者回复了帖子后,我们可以设置这个状态位为true,表示状态已经改变,这样当再次从缓存中取得Forum时,查看状态位,如果发现已经变化了,那么就重新从数据库加载ForumState。当然要想达到这种效果,我们一定要设计好聚合,所有对子对象的访问都要通过聚合的根,比如所有对ForumState对象的访问都要经过Forum对象,并且要保证所有的数据库操作,都首先从统一的缓冲入口进行,这样保证了整个系统中用的是同一个缓存,大家操作的所有对象都是同一个缓存中的对象。所以这里也给出了一条对象设计的提示,将经常变化的熟悉和不经常变化的属性分开,并且将经常变化的属性独立出去,作为聚合根的 一个子对象,这样做到变和不变分离,不仅有利于高内聚,而且有利于事务的控制和缓存的更新。

 

 

 

<!--EndFragment-->

   上面是关于Repository在对象建模中的作用,下面我也说说关于工厂的作用,既然是工厂,那么它肯定要生产东西出来,但是它不能随便乱生产,它生产出来的应该是整个聚合的根,并且要保证这个聚合的不变量受到保护,这样通过工厂提供一个集中的模型创建的访问点,也方便了控制访问。要设计一个好的工厂,我们首先需要设计一个好的对象模型,分辨出合理的聚合,这样工厂才会发挥真正的效力。

    最后既然说到了缓存,还有一点需要注意,那就是这个缓存的范围,我这里说的缓存是全局的缓存,是一个application级别的缓存。我个人是比较反对在Httpsession中保存大量数据的,这样当用户增多的情况下,比如会浪费很多的内存,浪费性能。所以我们更应该需要的是全局的缓存,这样底层的缓冲框架我们还可以采用分布式的缓存系统,这样以来我们的系统在集群环境下也免去了一些session failover的开销。这其实也是一种SNA架构的思想。

第三:数据库系统优化

 数据库在我们大多数的系统开发中都会涉及到,这方面的优化,主要是基于一些索引等的优化。

    最后,我想说的就是我们应该尽量采用一种面向对象的方式来开发我们的系统,而不是过分的依赖数据库来编程,在系统开发当中,我们操作具体的模型对象,而我们的模型对象由存储在缓存中,尽量减少对数据库的访问操作,从而提升系统的性能。

 

 

 总结上面所述,要想提高系统的性能,我们面临的难题就是对象建模,只有我们针对自己的具体的业务有了合理的对象模型后,我们才能有针对性的对业务对象进行缓存,从而使得缓存的效果最大化,提高系统的性能。

<!--EndFragment-->

分享到:
评论
45 楼 fjlyxx 2009-05-06  
凤舞凰扬 写道
icewubin 写道

你说的第二段很不错,很有想法,但是这条路是不通的,这句话如何理解,我一点点说给你听:
1.确实是有系统如你所说,几乎每步操做都需要极其严格的事务要求(严格序列化,说的通俗点叫做先后顺序必须要保证),单单说到这其实还是比较好实现的,一般的消息队列都能做到这个效果(脑子里先去除关系数据库的桎梏)。但是有些系统除了严格的序列化,还需要有非常高的实时性要求,假设包括外部因素总延时在5秒之内吧,上交所的股票交易系统就是这样的一个典型例子。

这样的系统不是不能做,但是代价太大,而且做法和通常的做法完全不一样,基本没有什么普遍性可言。他们的做法,说的简单点就是全内存操作,巨大的内存几乎加载了所有必要的实时数据。。。

2.第一个例子过于极端,说说第二种情况,绝大多数的银行吧,为了保证核心系统(实际是记账中心)的交易无差错,基本上所有的操作最终都集中在一台大型机上,跑数据库的(你不要幻想数据库集群能有效的提高性能,那是骗人的)。

3.从第二个例子中的数据库集群骗人事件,引出,如果你仔细看过 J2EE Without EJB的话,我记得好像有这么一句话,最好的分布式就是不要做分布式,感觉有点故弄玄虚,主要意思是这样的,一个通常的分布式集群的系统,其各个节点间的通讯(包括各种同步等的开销)代价往往会把集群带来的性能提升完全抵消掉,而且这样的集群基本没有线性的扩展性,集群的机器数量越多,集群中节点间的通讯的代价就越发恐怖。SNA的思想就是尽可能避免这种依赖于一种集中式集群的瓶颈。我个人还认为,节点间互相关系密切的集群系统的集成测试和运维、升级的复杂度是惊人的高的,成本巨大。

4.我再从另一个角度来说,第一点提到消息队列,恩,当你把一个消息队列的功能做得非常完善,或者说当你把一个缓存系统做得非常完善,例如加上一些类似于数据库的事务控制,那你可能就是在自己造一个分布式数据库了。Memcached DB算是一个这样的典型例子吧。这种缓存系统作为产品拿来用用还是比较靠谱的,自己造,而且要没有什么bug,这代价好像大了点吧。

5.如第四点所说,应该把缓存结构独立出来,单独考虑,例如你要用Memcached服务做缓存服务器,先和原本的J2EE的架构分离出来,JVM本身就是大小限制的,真要用Java做大的缓存框架,其实限制是很多的。所以不要迷信各级缓存,缓存结构不是你想像的那么简单的,不仅仅是开发和设计、调试和部署的成本都非常高。

6.做项目好像人生,不如意十有八九,预算成本和时间成本都是有限的,又要结构简单,又要效果好,往往得从业务出发,简单的例子我前面讲过,例如某些实时性要求不高的查询完全可以放弃实时性,可以用来获取简单的结构,和避开性能瓶颈。而复杂的例子,例如寻找外星人的项目,或者是Google的Map/Reduce,或者是林登实验室的Second Life的分布式计算结构,都是针对特殊的业务设计的。这些都不是传统的编程手段或技术能直接实现的。

7.拓展一下思路吧,第六点提到的简单例子“例如某些实时性要求不高的查询完全可以放弃实时性,可以用来获取简单的结构”,这个例子貌似简单,如果对查询的实时性要求不高,但是查询速度要求很高的话,楼主可以看看数据仓库的概念,不是要楼主学习数据仓库,而是拓展一下思路,思维不要局限在Java或者说JVM上,不要局限在事务型关系数据库存储上。

8.再做个引申,大量的事务型操作其实是很容易造成瓶颈的,但是有时候适当的一些假设,就能够部分的不使用事务,例如假设某张表中没有update和delete操作,只有insert操作,整个业务模块按照这个假设设计就能够很简单的实现,实际上现实世界中的财务流水帐在业务模型上就是这么设计的。。。

9.你有一定的项目经验,一般能根据需求估算出一个系统的各方面的负载有多大,然后再根据以往项目实施的经验,就能比较靠谱的掌握一个性能、成本的平衡点了。

    分析比较到位,看来icewubin还是蛮熟悉性能调优的实质,观点中的2,3,5,6,7,9是蛮认同的,赞一个!


关于第二点 还需要仔细的斟酌,因为把业务弄得数据库要考虑数据库的压力问题.业务放置的位置要么在前台逻辑要么在数据库.放在前台可以减缓数据库压力,放在后台可以提高前台处理能力. 但是有这么一个问题,如果前台有需要进行群集的时候  后台数据库的业务逻辑如何处理. 这时候跑数据库也许就是一个瓶颈了. 总之还是要小心跑数据库这个陷阱,需要很充分的考虑.
44 楼 matt.u 2009-05-06  
icewubin总结得蛮到位的。学习一下。
43 楼 凤舞凰扬 2009-05-05  
icewubin 写道

你说的第二段很不错,很有想法,但是这条路是不通的,这句话如何理解,我一点点说给你听:
1.确实是有系统如你所说,几乎每步操做都需要极其严格的事务要求(严格序列化,说的通俗点叫做先后顺序必须要保证),单单说到这其实还是比较好实现的,一般的消息队列都能做到这个效果(脑子里先去除关系数据库的桎梏)。但是有些系统除了严格的序列化,还需要有非常高的实时性要求,假设包括外部因素总延时在5秒之内吧,上交所的股票交易系统就是这样的一个典型例子。

这样的系统不是不能做,但是代价太大,而且做法和通常的做法完全不一样,基本没有什么普遍性可言。他们的做法,说的简单点就是全内存操作,巨大的内存几乎加载了所有必要的实时数据。。。

2.第一个例子过于极端,说说第二种情况,绝大多数的银行吧,为了保证核心系统(实际是记账中心)的交易无差错,基本上所有的操作最终都集中在一台大型机上,跑数据库的(你不要幻想数据库集群能有效的提高性能,那是骗人的)。

3.从第二个例子中的数据库集群骗人事件,引出,如果你仔细看过 J2EE Without EJB的话,我记得好像有这么一句话,最好的分布式就是不要做分布式,感觉有点故弄玄虚,主要意思是这样的,一个通常的分布式集群的系统,其各个节点间的通讯(包括各种同步等的开销)代价往往会把集群带来的性能提升完全抵消掉,而且这样的集群基本没有线性的扩展性,集群的机器数量越多,集群中节点间的通讯的代价就越发恐怖。SNA的思想就是尽可能避免这种依赖于一种集中式集群的瓶颈。我个人还认为,节点间互相关系密切的集群系统的集成测试和运维、升级的复杂度是惊人的高的,成本巨大。

4.我再从另一个角度来说,第一点提到消息队列,恩,当你把一个消息队列的功能做得非常完善,或者说当你把一个缓存系统做得非常完善,例如加上一些类似于数据库的事务控制,那你可能就是在自己造一个分布式数据库了。Memcached DB算是一个这样的典型例子吧。这种缓存系统作为产品拿来用用还是比较靠谱的,自己造,而且要没有什么bug,这代价好像大了点吧。

5.如第四点所说,应该把缓存结构独立出来,单独考虑,例如你要用Memcached服务做缓存服务器,先和原本的J2EE的架构分离出来,JVM本身就是大小限制的,真要用Java做大的缓存框架,其实限制是很多的。所以不要迷信各级缓存,缓存结构不是你想像的那么简单的,不仅仅是开发和设计、调试和部署的成本都非常高。

6.做项目好像人生,不如意十有八九,预算成本和时间成本都是有限的,又要结构简单,又要效果好,往往得从业务出发,简单的例子我前面讲过,例如某些实时性要求不高的查询完全可以放弃实时性,可以用来获取简单的结构,和避开性能瓶颈。而复杂的例子,例如寻找外星人的项目,或者是Google的Map/Reduce,或者是林登实验室的Second Life的分布式计算结构,都是针对特殊的业务设计的。这些都不是传统的编程手段或技术能直接实现的。

7.拓展一下思路吧,第六点提到的简单例子“例如某些实时性要求不高的查询完全可以放弃实时性,可以用来获取简单的结构”,这个例子貌似简单,如果对查询的实时性要求不高,但是查询速度要求很高的话,楼主可以看看数据仓库的概念,不是要楼主学习数据仓库,而是拓展一下思路,思维不要局限在Java或者说JVM上,不要局限在事务型关系数据库存储上。

8.再做个引申,大量的事务型操作其实是很容易造成瓶颈的,但是有时候适当的一些假设,就能够部分的不使用事务,例如假设某张表中没有update和delete操作,只有insert操作,整个业务模块按照这个假设设计就能够很简单的实现,实际上现实世界中的财务流水帐在业务模型上就是这么设计的。。。

9.你有一定的项目经验,一般能根据需求估算出一个系统的各方面的负载有多大,然后再根据以往项目实施的经验,就能比较靠谱的掌握一个性能、成本的平衡点了。

    分析比较到位,看来icewubin还是蛮熟悉性能调优的实质,观点中的2,3,5,6,7,9是蛮认同的,赞一个!
42 楼 凤舞凰扬 2009-05-05  
OOspurs 写道

我认为影响系统性能的几个因素:
1 memory 慎用池化,有可能造成memory leak。
2 同步   
3 数据库  索引,IO等。


   这位同学说得非常好,第一,池是个好东西,但是容易被滥用,或者说对于系统的设计以及定位有着比较严格的要求,它非常容易出现memory leak. 第二,同步,尤其是不太动脑筋的同步,是性能的一个关键瓶颈,尤其在并发达到30-50时(是对同一个功能的并发,而不是虚假的并发测试),就会出现明显的性能抖动。 三,数据库的访问(而不仅仅是索引),尤其是在使用hibernate, toplink等ORM时所产生的大量数据库访问吞吐,对于系统的性能确实是一个主要问题
41 楼 凤舞凰扬 2009-05-05  
justshare 写道
根据JE童鞋们的回复,作个总结,提高性能系统的根本:
1. 一个系统通常要考虑的不是性能,而是单位时间内的吞吐量和响应时间的均衡。
2. 技术可以提高性能,池话,负载均衡,分布式都可以提高性能,但是这些都有瓶颈。性能的根本在于业务设计,进行业务的深度分析才能从根本上提高性能。
3. 系统的瓶劲主要集中在数据库的吞吐量。真正最为常见地影响软件系统性能的是对数据库的访问,而非数据库本身的优化。

获益非浅啊,投精华。


    呵呵,要纠正纠正楼上这位同学的几个问题了。
1. 性能是什么? 所谓单位时间内的吞吐量与响应时间的均衡有时什么? 我们谈性能优化究竟是去谈极致化的性能优化(比如网络服务响应从1秒优化到0.5秒,比如说支持数以万计的并发)还是谈在业务范围内的性能优化。呵呵,性能好和差,都是相对的,并且是永远没有优化的止境的。
2. 谈性能的设计的前提,便是假设系统的业务分析不存在较大或者说严重的问题,否则软件的所有问题都可以归属到系统的需求不明确,业务分析不到位。业务设计,准确地说应该是业务定位,会对系统的性能产生关键的影响,但绝对不会说性能的根本在于业务设计,这完全是技术人员推卸责任的一种托词。
3. 在我8年多来所开发、设计甚至遇到过的系统中,没有一个系统的性能问题是集中在数据库的吞吐量的。即使是数据库的吞吐大,也是因为系统设计和实现的问题(比如滥用ORM)。
40 楼 shuai45 2009-05-05  
弄来弄去 怎么成系统构架了
39 楼 justshare 2009-05-05  
根据JE童鞋们的回复,作个总结,提高性能系统的根本:
1. 一个系统通常要考虑的不是性能,而是单位时间内的吞吐量和响应时间的均衡。
2. 技术可以提高性能,池话,负载均衡,分布式都可以提高性能,但是这些都有瓶颈。性能的根本在于业务设计,进行业务的深度分析才能从根本上提高性能。
3. 系统的瓶劲主要集中在数据库的吞吐量。真正最为常见地影响软件系统性能的是对数据库的访问,而非数据库本身的优化。

获益非浅啊,投精华。
38 楼 icewubin 2009-05-04  
狂放不羁 写道
呵呵,多谢老哥耐心的讨论。实战经验方面确实欠缺很多。那个领域驱动设计我也接触不久,还不到2年时间,并且我只是看了<<领域驱动设计>>后很有感触,所以在自己的创业项目中应用了(不幸的是创业失败了,不过还是学到很多),其它关于领域驱动设计的知识也都是从infoq,yahoo group,TSS上面学习的,自己实战的不多,很多公司也不用呵呵。

对于第一点,SNA的缓存设计首先避免分布式的开销这点我理解,但是第一点后面的不太理解,我觉得缓存的设计与对象图是有关系的(或者我没理解老哥的对象图的含义),以前一个项目中,因为我应用了全局的缓存,但是因为面向对象的设计功底不好,没有设计好合理的聚合根,结果最后导致了全局缓存中的对象在并发环境下状态很难控制,最后不得不重构对象模型,经过重构后,对象状态也变得更加容易了,所以我觉得缓存首先应该要确定一个全局的入口,系统所有设计到缓存的操作,都首先要从全局的缓存入口得到对象,并且这个很大程度上是一个聚合根,聚合根对象要封装好整个聚合的状态,不能将状态暴漏给客户,这样容易控制聚合的状态不变量。还请老哥能解释一下呵呵,多谢。

你说的第二段很不错,很有想法,但是这条路是不通的,这句话如何理解,我一点点说给你听:
1.确实是有系统如你所说,几乎每步操做都需要极其严格的事务要求(严格序列化,说的通俗点叫做先后顺序必须要保证),单单说到这其实还是比较好实现的,一般的消息队列都能做到这个效果(脑子里先去除关系数据库的桎梏)。但是有些系统除了严格的序列化,还需要有非常高的实时性要求,假设包括外部因素总延时在5秒之内吧,上交所的股票交易系统就是这样的一个典型例子。

这样的系统不是不能做,但是代价太大,而且做法和通常的做法完全不一样,基本没有什么普遍性可言。他们的做法,说的简单点就是全内存操作,巨大的内存几乎加载了所有必要的实时数据。。。

2.第一个例子过于极端,说说第二种情况,绝大多数的银行吧,为了保证核心系统(实际是记账中心)的交易无差错,基本上所有的操作最终都集中在一台大型机上,跑数据库的(你不要幻想数据库集群能有效的提高性能,那是骗人的)。

3.从第二个例子中的数据库集群骗人事件,引出,如果你仔细看过 J2EE Without EJB的话,我记得好像有这么一句话,最好的分布式就是不要做分布式,感觉有点故弄玄虚,主要意思是这样的,一个通常的分布式集群的系统,其各个节点间的通讯(包括各种同步等的开销)代价往往会把集群带来的性能提升完全抵消掉,而且这样的集群基本没有线性的扩展性,集群的机器数量越多,集群中节点间的通讯的代价就越发恐怖。SNA的思想就是尽可能避免这种依赖于一种集中式集群的瓶颈。我个人还认为,节点间互相关系密切的集群系统的集成测试和运维、升级的复杂度是惊人的高的,成本巨大。

4.我再从另一个角度来说,第一点提到消息队列,恩,当你把一个消息队列的功能做得非常完善,或者说当你把一个缓存系统做得非常完善,例如加上一些类似于数据库的事务控制,那你可能就是在自己造一个分布式数据库了。Memcached DB算是一个这样的典型例子吧。这种缓存系统作为产品拿来用用还是比较靠谱的,自己造,而且要没有什么bug,这代价好像大了点吧。

5.如第四点所说,应该把缓存结构独立出来,单独考虑,例如你要用Memcached服务做缓存服务器,先和原本的J2EE的架构分离出来,JVM本身就是大小限制的,真要用Java做大的缓存框架,其实限制是很多的。所以不要迷信各级缓存,缓存结构不是你想像的那么简单的,不仅仅是开发和设计、调试和部署的成本都非常高。

6.做项目好像人生,不如意十有八九,预算成本和时间成本都是有限的,又要结构简单,又要效果好,往往得从业务出发,简单的例子我前面讲过,例如某些实时性要求不高的查询完全可以放弃实时性,可以用来获取简单的结构,和避开性能瓶颈。而复杂的例子,例如寻找外星人的项目,或者是Google的Map/Reduce,或者是林登实验室的Second Life的分布式计算结构,都是针对特殊的业务设计的。这些都不是传统的编程手段或技术能直接实现的。

7.拓展一下思路吧,第六点提到的简单例子“例如某些实时性要求不高的查询完全可以放弃实时性,可以用来获取简单的结构”,这个例子貌似简单,如果对查询的实时性要求不高,但是查询速度要求很高的话,楼主可以看看数据仓库的概念,不是要楼主学习数据仓库,而是拓展一下思路,思维不要局限在Java或者说JVM上,不要局限在事务型关系数据库存储上。

8.再做个引申,大量的事务型操作其实是很容易造成瓶颈的,但是有时候适当的一些假设,就能够部分的不使用事务,例如假设某张表中没有update和delete操作,只有insert操作,整个业务模块按照这个假设设计就能够很简单的实现,实际上现实世界中的财务流水帐在业务模型上就是这么设计的。。。

9.你有一定的项目经验,一般能根据需求估算出一个系统的各方面的负载有多大,然后再根据以往项目实施的经验,就能比较靠谱的掌握一个性能、成本的平衡点了。
37 楼 狂放不羁 2009-05-04  
icewubin 写道
狂放不羁 写道
呵呵,多谢。
1. 至于SNA,我大3的时候在台湾一家互联网公司实习时,他们就用到了这种架构。SNA虽然是PHP首先提出的,但是思想大家可以共用,SNA主要避免了在session保存大量的数据,减少了集群环境下session failover的开销。

2 音乐博士的without ejb,我是在大3学习完ejb后看的,其实我个人是很喜欢ejb的,EJB和spring本来就是两个层面的东西,EJB是分布式的组件,如果spring也提供这种分布式的功能,那么也会变得重量起来。所以如果用spring做项目,只能实现集群,不能实现分布式的。个人认为<<服务器端组件模式>>对学习EJB很有帮助。

3 不知道你有没有看过<<领域驱动设计>>这本书,我个人很喜欢领域驱动设计,这本书我是和<<uml和模式应用>>一起看的。我这篇文章的意思也就是:结合DDD以及缓存来达到提升系统的性能。为什么?因为如果没有设计好对象模型,没有设计好聚合,那么整个系统的对象网的状态就很难控制,这种情况下,即使用了缓存也是自找苦吃,在并发环境下,如何控制全局缓存中的聚合根对象的不变量就很头疼,尤其是在聚合根的不变量约束是有很多状态构成的时候,这一点我深有感触。

4 我说缓存的重要性的时候,其实隐含了面向对象的设计以及并发编程的重要的性。以前我们并发通过底层数据库事务锁来实现,而如今为什么不能通过内存中的对象模型来控制并发,而事务用来保证操作的原子性和一致性。

不错,1、2、3的书你都看过,那我只能说你确实是实战经验不够了。

你说的第3和第4提到的思想在一定的前提下是完全正确的,但是和第1点是矛盾的:
1.SNA架构下的缓存的设计首先要避开分布式通讯的问题,然后就是缓存结构和对象图没有必然联系,或者说缓存占用的内存和JVM没有必然联系,再或者说用JVM做缓存是有很大的约束条件的。

2.缓存设计和业务是紧密相关的,首先是确定数据实时性的要求,有T+1、6小时、3小时、1小时、5分钟、严格事务实时,不是所有查询需求都是要严格事务实时要求的,举个具体的例子就是,不是所有业务系统的信息展示的要求是要达到股票交易的实时性的。这是业务分析重要性的一点,我起了个头。因为从软件工程角度来说,一个架构设计是寻找各方面成本的平衡点,开发成本、部署成本(包括硬件)、维护成本等,针对不同业务实时性的特点,不同的模块的缓存设计是不同的,之所以不同,是因为有些设计可以极大的降低某一类成本。例如像JE的某个圈子的首页,除了一些个人登录信息以外,大部分统计类的信息的实时性要求是很低的,如果要设计一个小功能点,显示某个圈子的发贴总数,你可以有N多种的实现方法,至于你最终选择哪一种,更多的是根据业务特点来定的,而不是根据某个万精油一样的技术模式(不是领域设计模式,更高一层的模块设计模式)来决定的。这个例子表示了,业务分析的重要性,一个合适的系统的设计一定是更多的根据业务特点来的。


呵呵,多谢老哥耐心的讨论。实战经验方面确实欠缺很多。那个领域驱动设计我也接触不久,还不到2年时间,并且我只是看了<<领域驱动设计>>后很有感触,所以在自己的创业项目中应用了(不幸的是创业失败了,不过还是学到很多),其它关于领域驱动设计的知识也都是从infoq,yahoo group,TSS上面学习的,自己实战的不多,很多公司也不用呵呵。

对于第一点,SNA的缓存设计首先避免分布式的开销这点我理解,但是第一点后面的不太理解,我觉得缓存的设计与对象图是有关系的(或者我没理解老哥的对象图的含义),以前一个项目中,因为我应用了全局的缓存,但是因为面向对象的设计功底不好,没有设计好合理的聚合根,结果最后导致了全局缓存中的对象在并发环境下状态很难控制,最后不得不重构对象模型,经过重构后,对象状态也变得更加容易了,所以我觉得缓存首先应该要确定一个全局的入口,系统所有设计到缓存的操作,都首先要从全局的缓存入口得到对象,并且这个很大程度上是一个聚合根,聚合根对象要封装好整个聚合的状态,不能将状态暴漏给客户,这样容易控制聚合的状态不变量。还请老哥能解释一下呵呵,多谢。
36 楼 fjlyxx 2009-05-03  
从技术角度来说,要进行性能的提高 一般先要找到性能的瓶颈所在,那个地方性能是性能的瓶颈,为什么会有这样的瓶颈进行分析.如果性能的瓶颈是来自于系统逻辑实现本身 那么你实现要考虑的如果消除这种逻辑瓶颈.一般可以通过分解逻辑进行消除,把本来一气呵成的东西分成很多小东西进行.其次你要好考虑能否用批量的任务进行处理.比如系统日志模块是否有必要用户每次的操作都要实时的记录还是先把用户操作记录写道缓存 然后再批量入库呢,是否对某些轮询任务进行休眠等等...
如果这个瓶颈是来自于一些外部环境,比如网络,数据库等等.这时候你要考虑的就是这么和减少这些外部环境交互的次数.一次IO能完成的就没必要用两次,连接长短的选择,SQL的优化等等.如果这些瓶颈是完全出在外部环境,比如数据库查询效率很低,那么你就该考虑如何去优化.比如数据库的索引,数据区域的整理等等.
很多时候CPU和内存是冤家,你高我低,你低我高的.这时候就要具体考虑了.

反正一句话, 找瓶颈,判断瓶颈类型,进行解决方案论证,解决问题,回归测试. 如果是在不行那么也只能靠群集,负载均衡了.
35 楼 icewubin 2009-05-03  
狂放不羁 写道
呵呵,多谢。
1. 至于SNA,我大3的时候在台湾一家互联网公司实习时,他们就用到了这种架构。SNA虽然是PHP首先提出的,但是思想大家可以共用,SNA主要避免了在session保存大量的数据,减少了集群环境下session failover的开销。

2 音乐博士的without ejb,我是在大3学习完ejb后看的,其实我个人是很喜欢ejb的,EJB和spring本来就是两个层面的东西,EJB是分布式的组件,如果spring也提供这种分布式的功能,那么也会变得重量起来。所以如果用spring做项目,只能实现集群,不能实现分布式的。个人认为<<服务器端组件模式>>对学习EJB很有帮助。

3 不知道你有没有看过<<领域驱动设计>>这本书,我个人很喜欢领域驱动设计,这本书我是和<<uml和模式应用>>一起看的。我这篇文章的意思也就是:结合DDD以及缓存来达到提升系统的性能。为什么?因为如果没有设计好对象模型,没有设计好聚合,那么整个系统的对象网的状态就很难控制,这种情况下,即使用了缓存也是自找苦吃,在并发环境下,如何控制全局缓存中的聚合根对象的不变量就很头疼,尤其是在聚合根的不变量约束是有很多状态构成的时候,这一点我深有感触。

4 我说缓存的重要性的时候,其实隐含了面向对象的设计以及并发编程的重要的性。以前我们并发通过底层数据库事务锁来实现,而如今为什么不能通过内存中的对象模型来控制并发,而事务用来保证操作的原子性和一致性。

不错,1、2、3的书你都看过,那我只能说你确实是实战经验不够了。

你说的第3和第4提到的思想在一定的前提下是完全正确的,但是和第1点是矛盾的:
1.SNA架构下的缓存的设计首先要避开分布式通讯的问题,然后就是缓存结构和对象图没有必然联系,或者说缓存占用的内存和JVM没有必然联系,再或者说用JVM做缓存是有很大的约束条件的。

2.缓存设计和业务是紧密相关的,首先是确定数据实时性的要求,有T+1、6小时、3小时、1小时、5分钟、严格事务实时,不是所有查询需求都是要严格事务实时要求的,举个具体的例子就是,不是所有业务系统的信息展示的要求是要达到股票交易的实时性的。这是业务分析重要性的一点,我起了个头。因为从软件工程角度来说,一个架构设计是寻找各方面成本的平衡点,开发成本、部署成本(包括硬件)、维护成本等,针对不同业务实时性的特点,不同的模块的缓存设计是不同的,之所以不同,是因为有些设计可以极大的降低某一类成本。例如像JE的某个圈子的首页,除了一些个人登录信息以外,大部分统计类的信息的实时性要求是很低的,如果要设计一个小功能点,显示某个圈子的发贴总数,你可以有N多种的实现方法,至于你最终选择哪一种,更多的是根据业务特点来定的,而不是根据某个万精油一样的技术模式(不是领域设计模式,更高一层的模块设计模式)来决定的。这个例子表示了,业务分析的重要性,一个合适的系统的设计一定是更多的根据业务特点来的。
34 楼 OOspurs 2009-05-02  
狂放不羁 写道
icewubin 写道
狂放不羁 写道
呵呵,那你讲一下什么是SNA?那请你说一下“业务分析的重要性”是什么,我洗耳恭听。你说出你的,我理解下,如果大家觉得对的话,然后我打破我的思想。

1.SNA表示Shared Nothing Architecture,不是说要你每个项目都要做到,是让你了解一下为什么有些项目要做SNA的设计。

2.你现在知道的一些观点和结论基本上是被灌输的,不是说这些观点是错的,特定时代的产物而已。建议你下个电子版的《J2EE Without EJB》看看,里面其实不是讲技术的,是讲思想的。

3.业务分析太大了,无从说起,前两个你都了解一下再讨论比较合适一点。



呵呵,多谢。
1. 至于SNA,我大3的时候在台湾一家互联网公司实习时,他们就用到了这种架构。SNA虽然是PHP首先提出的,但是思想大家可以共用,SNA主要避免了在session保存大量的数据,减少了集群环境下session failover的开销。

2 音乐博士的without ejb,我是在大3学习完ejb后看的,其实我个人是很喜欢ejb的,EJB和spring本来就是两个层面的东西,EJB是分布式的组件,如果spring也提供这种分布式的功能,那么也会变得重量起来。所以如果用spring做项目,只能实现集群,不能实现分布式的。个人认为<<服务器端组件模式>>对学习EJB很有帮助。

3 不知道你有没有看过<<领域驱动设计>>这本书,我个人很喜欢领域驱动设计,这本书我是和<<uml和模式应用>>一起看的。我这篇文章的意思也就是:结合DDD以及缓存来达到提升系统的性能。为什么?因为如果没有设计好对象模型,没有设计好聚合,那么整个系统的对象网的状态就很难控制,这种情况下,即使用了缓存也是自找苦吃,在并发环境下,如何控制全局缓存中的聚合根对象的不变量就很头疼,尤其是在聚合根的不变量约束是有很多状态构成的时候,这一点我深有感触。

4 我说缓存的重要性的时候,其实隐含了面向对象的设计以及并发编程的重要的性。以前我们并发通过底层数据库事务锁来实现,而如今为什么不能通过内存中的对象模型来控制并发,而事务用来保证操作的原子性和一致性。


我来说说我的看法:
1 因为网络本身是无状态的,所以用SNA能更好地利用网络的特性来提高性能。
2 很多时候用集群比分布式更好,网络之间的远程调用是有代价的。EJB这种重量级组件对服务器的要求就很高,用得不好反而直接影响系统的性能。
3 软件的核心当然是业务啦, 再好的技术没有好的业务也没用,SUN就是个例子。
4 如果多台server集群就会出现缓存失效的问题, 使用底层数据库作为全局锁是一种解决方案,当然memcache那种分布式缓存也是一种解决方案。

我认为影响系统性能的几个因素:
1 memory 慎用池化,有可能造成memory leak。
2 同步   
3 数据库  索引,IO等。

33 楼 狂放不羁 2009-05-02  
icewubin 写道
狂放不羁 写道
呵呵,那你讲一下什么是SNA?那请你说一下“业务分析的重要性”是什么,我洗耳恭听。你说出你的,我理解下,如果大家觉得对的话,然后我打破我的思想。

1.SNA表示Shared Nothing Architecture,不是说要你每个项目都要做到,是让你了解一下为什么有些项目要做SNA的设计。

2.你现在知道的一些观点和结论基本上是被灌输的,不是说这些观点是错的,特定时代的产物而已。建议你下个电子版的《J2EE Without EJB》看看,里面其实不是讲技术的,是讲思想的。

3.业务分析太大了,无从说起,前两个你都了解一下再讨论比较合适一点。



呵呵,多谢。
1. 至于SNA,我大3的时候在台湾一家互联网公司实习时,他们就用到了这种架构。SNA虽然是PHP首先提出的,但是思想大家可以共用,SNA主要避免了在session保存大量的数据,减少了集群环境下session failover的开销。

2 音乐博士的without ejb,我是在大3学习完ejb后看的,其实我个人是很喜欢ejb的,EJB和spring本来就是两个层面的东西,EJB是分布式的组件,如果spring也提供这种分布式的功能,那么也会变得重量起来。所以如果用spring做项目,只能实现集群,不能实现分布式的。个人认为<<服务器端组件模式>>对学习EJB很有帮助。

3 不知道你有没有看过<<领域驱动设计>>这本书,我个人很喜欢领域驱动设计,这本书我是和<<uml和模式应用>>一起看的。我这篇文章的意思也就是:结合DDD以及缓存来达到提升系统的性能。为什么?因为如果没有设计好对象模型,没有设计好聚合,那么整个系统的对象网的状态就很难控制,这种情况下,即使用了缓存也是自找苦吃,在并发环境下,如何控制全局缓存中的聚合根对象的不变量就很头疼,尤其是在聚合根的不变量约束是有很多状态构成的时候,这一点我深有感触。

4 我说缓存的重要性的时候,其实隐含了面向对象的设计以及并发编程的重要的性。以前我们并发通过底层数据库事务锁来实现,而如今为什么不能通过内存中的对象模型来控制并发,而事务用来保证操作的原子性和一致性。








32 楼 icewubin 2009-05-02  
狂放不羁 写道
呵呵,那你讲一下什么是SNA?那请你说一下“业务分析的重要性”是什么,我洗耳恭听。你说出你的,我理解下,如果大家觉得对的话,然后我打破我的思想。

1.SNA表示Shared Nothing Architecture,不是说要你每个项目都要做到,是让你了解一下为什么有些项目要做SNA的设计。

2.你现在知道的一些观点和结论基本上是被灌输的,不是说这些观点是错的,特定时代的产物而已。建议你下个电子版的《J2EE Without EJB》看看,里面其实不是讲技术的,是讲思想的。

3.业务分析太大了,无从说起,前两个你都了解一下再讨论比较合适一点。
31 楼 狂放不羁 2009-05-02  
icewubin 写道
狂放不羁 写道
shenrd666888 写道
楼主,我也一直追求系统性能的提升,也算是绞尽脑汁。
您现在是什么级别了,项目经理还是架构师了?


呵呵,我现在仅仅是一个即将毕业的应届生而已。这些观点也是我对自己项目的一点总结吧。

建议你看看SNA的思想,把现有的想法彻底打破,重新思考软件的本质。

但是楼主实战经验不够,无法分辨出书上哪些是忽悠人的,哪些是过时的,哪些是当前可借鉴的。例如这里已经有不少高人提到业务分析的重要性,楼主可能要很久以后才能彻底明白什么叫“业务分析的重要性”。



呵呵,那你讲一下什么是SNA?那请你说一下“业务分析的重要性”是什么,我洗耳恭听。你说出你的,我理解下,如果大家觉得对的话,然后我打破我的思想。
30 楼 icewubin 2009-05-01  
狂放不羁 写道
shenrd666888 写道
楼主,我也一直追求系统性能的提升,也算是绞尽脑汁。
您现在是什么级别了,项目经理还是架构师了?


呵呵,我现在仅仅是一个即将毕业的应届生而已。这些观点也是我对自己项目的一点总结吧。

建议你看看SNA的思想,把现有的想法彻底打破,重新思考软件的本质。

但是楼主实战经验不够,无法分辨出书上哪些是忽悠人的,哪些是过时的,哪些是当前可借鉴的。例如这里已经有不少高人提到业务分析的重要性,楼主可能要很久以后才能彻底明白什么叫“业务分析的重要性”。
29 楼 vanlin 2009-05-01  
我感觉 硬件很必要  现在 从技术上把 实现分成多层,大多数应用都集中到单台服务器上,由于 硬件 io 限制,不管是用缓存还是其它技术,也不能突破这些,

应该把分层合理布置到不同的高性能服务器上就能充分利用硬件特性,提高系统性能。
28 楼 狂放不羁 2009-05-01  
shenrd666888 写道
楼主,我也一直追求系统性能的提升,也算是绞尽脑汁。
您现在是什么级别了,项目经理还是架构师了?


呵呵,我现在仅仅是一个即将毕业的应届生而已。这些观点也是我对自己项目的一点总结吧。
27 楼 狂放不羁 2009-05-01  
凤舞凰扬 写道
   给楼主三个建议做个小小的点评吧。
1. 池化服务器组件:其实按照楼主的意思,更加应该是指容器化(EJB有池,但是Spring似乎没池)。而如果是容器化的话,那么它的目的并不是对性能的优化(如果只是减少对象的产生,工厂就够了)。即使是池,也面临另外一个问题,那就是池对象的泄漏处理(比如讲,一个程序在大循环中从池中获取组件,或者获取组件后并不归还)。对于类似于数据库的连接池来说,因为对象是继承实现同一接口的,那么也就是容易有一个池实现。而对于基于POJO的服务组件来说,去实现这样一个池支持的实现(解决上述泄漏问题)并不容易。
2.  缓存:没错,如果一个企业级系统没有使用缓存或者没有使用好缓存,是绝对不可能获取良好性能的。但是在大型企业系统中,使用缓存又得面临几个问题。第一,如果存在分布式的负载均衡或集群,缓存间的同步;缓存失效的设定,对于业务数据,是需要准确的读写分析,否则的话,缓存算法就成了空谈。也许许多人都认为LRU是最合适的,其实并非如此,许多时候,固定时间失效是常用的。
3.  数据库系统优化:也许每个人都认为它影响了系统的性能,这话并没错。但实际上是大家低估了数据库的处理能力。真正最为常见地影响软件系统性能的是对数据库的访问,而非数据库本身的优化。这种访问包括:比如循环中去读取数据库,比如滥用ORM工具,比如采用非索引查询等等。

    楼主看到的只是影响系统性能的表面,这些问题的原因也许所谓的书中或者忽悠的咨询师口中是经常见的。但真正解决系统性能的优化是无定式的,是需要架构师根据实际情况分析的。



呵呵,多谢老哥的点评。我改下第一点的标题。那个第一点我更侧重对无状态线程安全组件的生命周期的管理,容器管理这些组件对性能也是有好处的。我这篇文章的侧重点是如何通过合理的对象建模,然后借助于合理的对业务对象模型的缓存来提升系统性能。

呵呵也许某些企业级的系统,人家也本来更看重数据安全性,完整性,以及项目管理等方面,对性能考虑的不多。性能不好,高性能的服务器,高性能的应用服务器,高性能的数据库服务器顶着。
26 楼 shenrd666888 2009-05-01  
楼主,我也一直追求系统性能的提升,也算是绞尽脑汁。
您现在是什么级别了,项目经理还是架构师了?

相关推荐

    电力拖动自动控制系统运动控制系统课后思考题习题答案

    电力拖动自动控制系统运动控制系统课后思考题习题答案 本资源为电力拖动自动控制系统运动控制系统课后思考题习题答案,涵盖了电力拖动自动控制系统运动控制系统的主要知识点,包括直流电动机的调速方法、直流PWM...

    航空订票系统性能方案(手写完整版)

    航空订票系统性能方案(手写完整版) 航空订票系统性能方案是 LR 自带航空订票系统的性能方案,旨在指导航空订票系统的测试。该方案对航空订票网站系统的性能测试进行了详细的规划和设计。 航空订票系统的主要功能...

    系统性能测试报告

    在进行系统性能测试时,通常会依据一套既定的框架来组织测试报告,这份XX系统的性能测试报告即是按照这样的框架来展开的。下面将基于报告内容,详细解释系统性能测试中需要考虑的关键点。 首先,测试目的清晰地指出...

    及偶极子对系统性能的影响

    在自动控制系统设计中,系统性能的评估至关重要,主要包括稳定性、动态性能和稳态性能三个方面。稳定性是控制系统的基础,它衡量的是系统在受到扰动后能否自行恢复到平衡状态。一个稳定的系统,其闭环特征方程的所有...

    系统性能测试报告模板

    - **测试结果:** 在长时间运行后的系统性能指标。 - **结果分析:** 分析稳定性测试的结果,评估系统长期运行下的可靠性和性能下降情况。 **5.4 EOD 批处理测试** - **日常批处理:** 日常需要进行的批量处理任务...

    性能测试-系统吞吐量及用户并发量

    ### 性能测试中的核心知识点解析 #### 一、系统吞吐量的理解 - **定义**: 系统吞吐量是指单位时间内系统...这些知识点对于理解和优化系统的性能至关重要,有助于开发者和测试人员更好地评估和提升系统的性能表现。

    电力拖动自动控制系统第4版_思考题答案

    电力拖动自动控制系统是...总的来说,电力拖动自动控制系统的分析和设计涉及电动机的电气特性、控制策略、反馈机制等多个方面,需要深入理解电动机的工作原理以及自动控制理论,以便有效地实现系统的调速和性能优化。

    web应用系统性能测试

    ### Web应用系统性能测试 #### 一、引言与背景 随着互联网技术的快速发展和企业信息化建设的深入,Web应用已成为现代企业业务运作的核心部分。然而,随着Web应用的广泛使用,用户数量激增和数据量剧增的问题也日益...

    软件系统性能的常见指标.doc

    软件系统性能的常见指标 软件系统性能的常见指标是衡量软件系统性能的重要指标,它们可以帮助我们了解软件系统的运行状况,查找性能瓶颈,并优化系统性能。下面是常见的软件系统性能指标: 1. 响应时间(Response ...

    Go-《关于Go性能优化的思考》概述了编写高性能Go代码的最佳实践

    《关于Go性能优化的思考》这本书提供了许多关于如何编写高效Go代码的策略和技巧。本文将深入探讨这些最佳实践,帮助开发者提升程序性能。 1. **内存管理与垃圾回收** Go语言采用自动垃圾回收机制,但在某些场景下...

    从啤酒游戏看系统思考.pptx

    【啤酒游戏】是一种模拟供应链管理的互动教学工具,旨在揭示系统思考的重要性。在这个游戏中,参与者分别扮演制造商、批发商和零售商的角色,通过订单和交货进行互动,模拟真实市场环境中的供求关系。游戏的设计旨在...

    经典性能测试用例参考模板

    - **结果评估标准**:测试结果需满足预设的系统性能需求。 **结果评估**: 1. **响应时间**:通过测试收集的数据,分析平均响应时间是否在10秒以内,以验证系统在高并发下的处理速度。 2. **资源利用率**:监控...

    成功的Web应用系统性能测试

    【Web应用系统性能测试】是确保系统稳定性和用户体验的关键步骤。在进行性能测试时,我们需要考虑多种因素,包括但不限于Web服务器配置、FTP服务、日志服务器以及邮件中继服务等。性能测试的目标是评估系统在高负载...

    淘宝性能测试白皮书V1.0

    性能测试模型,如PV计算模型、PV-&gt;TPS转换模型、TPS波动模型以及共享中心性能测试模型和前端页面性能测试模型,都是为了更准确地模拟和预测系统性能而构建的。这些模型有助于测试人员深入理解系统行为,并以此为基础...

    深度:国产嵌入式操作系统发展思考.docx

    LiteOS 是一个轻量级的嵌入式操作系统,具有低功耗、低成本和高性能的特点。 二、国产嵌入式操作系统的挑战 国产嵌入式操作系统面临着许多挑战,例如技术门槛高、人才缺乏、市场竞争激烈等。同时,国产嵌入式操作...

    系统工程 思考与练习题.docx

    系统分析是系统工程的核心,它包括问题定义、模型建立、方案评估和决策制定等步骤,旨在优化系统性能。 第四章关注系统模型的特性,如解释结构模型,它用于表示系统元素之间的因果关系。模型化是理解和预测系统行为...

Global site tag (gtag.js) - Google Analytics