系统性能优化的几个方面

8/3/2015来源:C#应用人气:2769

系统性能优化的几个方面

过去

  很早以前,做管理系统,对性能体会并不是特别明显。因为一些用户非常聪明,会通过调整自己的使用方式来适应系统的处理能力。现在想起来,有环境的原因也有能力的原因,没有做好性能的事情,觉得有些好笑也有些遗憾。  现在做的程序,对响应速度、处理能力都有一定的要求,而且这些指标直接和效益挂钩。这个时候,性能问题就随着系统的运行不断显现出来,并在运行过程中左右一项重要任务不断改进、调优。  性能优化的过程是一种辛苦又有趣的挑战。  改进总是在事关利害的时候才会有推动力。

来自业务上的简化

  很多时候,自己是一个理想主义者,公司的其他一些也是,所以在系统设计时:总试图考虑周全,试图具备很强的扩展性,试图一劳永逸。事实是,在没有对业务成竹于胸、对设计没有深刻立即的时候,很难做到。所以往往过度设计、过度开发。  多做事情,不是好事情,尤其是那些高频度执行的业务流程上,影响尤其严重。多一个环节,都是意味着多消耗计算资源。  很早前,我们做的程序在结算上,要求对交易账号三方进行资金划拨(一方减少,另外一方增加,第三方佣金增加),要记录资金变动明细,要有事务保护。这业务,在交易量不大的情况下,没有问题;小幅度的性能提升也可以通过提升硬件配置来解决。但是对于我们,运营一段时间后,性能真的很难再提升:1、业务逻辑写得很复杂,改动风险很大,2、所有瓶颈在数据库上,事务经常失败  经过很长时间的观察,我们发现业务并没有朝预想的方向发展,我们并不需要三方划账,只需要单方扣款就可以了;我们也发现,资金做好变动日志就可以了,事务也可以不需要。这个业务调整确定下来后,砍掉了这个模块6成的代码,单台的服务性能大幅提高。  事后感叹,真的想多了,业务没有想的复杂。业务上的简化,比其他方面的优化,我认为更加有效,也更加乐意去做:  1. 可以删掉很多无用的东西,维护简单了,  2. 以前不爽的代码终于可以丢掉了

部署上的优化

  业务总是在上升的,单台服务器,总会有一个上限。这是常理,但在开始做程序的时候,只是想过,并有做预案。那时的想法是先完成业务,再考虑性能(这个策略,仁者见仁,智者见智)。因此解决方法必定是增加硬件。  要增加硬件,首先需要硬件,首先要考虑系统自身的伸缩性问题。对之前开发的大而全的程序来说,首先要做的拆解。将业务流程拆解成多个独立的环节,每个环节自成一体,独立运行,环节之间通过网络通讯。业务流程拆解带来诸多好处:降低整体的复杂度,学习、开发、维护成本会大大下降。  系统具备一定伸缩性后,就可以调整部署,我的理解是有两个维度:  1. 不同环节部署到不同的服务器上,分摊压力  2. 关键环节多套部署,增加处理能力  通过部署,基本上能解决性能的问题。在这个过程中,尤其是第二个维度,数据唯一性是一个技术单点。

  就现在的情况看,增加硬件的成本,还是远低于开发、维护的人力成本的,所有这个方式的性能优化,是运维喜欢干的。

来自数据库上优化

  数据库的优化空间,还是挺大的,主要表现在表索引的合理使用、表字段设计、表关联查询、事务。  个人认为:  1、对于性能要求的程序,尽量避免使用事务、和表关联。  2、好的索引能够很大程度上提高速度  3、如果数据量大,要考虑表分区  一些编码的人,对数据库了解不多,没有连主键、索引的都没有,也时常发生。所以优化这个,是程序员,尤其懂数据库的程序员喜欢干的事情。时常听到一些牛人将一些耗时巨大的数据计算,瞬间提升数百、数千倍。

来自程序实现上优化

  一般公司的程序,只是完成某一些业务而且,没有什么大不了的技术攻关,所有也谈不上什么高深的技术。而我们写的程序,经常会因为各种各样的原因,多做一些没用的事情:  1、没有用的for循环  2、可以在一个循环里面搞定的,做了多个循环  3、一个事情反复做,通常是代码相互调用(因为计算结果没有共享或传递)  这个事情,程序员会比较喜欢做。程序员每隔一段时间都会回头看自己的过去,每每发现以前的幼稚表现,都有冲动去修正一下。

来自硬件的提升

  换一个性能高一点的设备。想想比较简单,实际上也是需要有很专业的测试,才知道硬件是否真的合适。  

一些小经验

IIS行吗

  在开发现在这个程序的时候,有人提醒我们IIS容易崩溃,不稳定,性能不行。  在系运行之初,我们的确也是碰到这两个问题,也怀疑IIS是否真的不行。遇到内存消耗居高不下、线程消耗居高不下、CPU满负荷,总是间歇性崩溃。  随着问题的逐步解决,我们发现,其实大部分原因是代码编写不当,一小部分是不了解IIS的运行机制。目前系统还能够持续稳定运行。

内存问题

  .Net有垃圾回收机制,但也不能滥用,少New一点也许会好点  .Net的垃圾回收,并不是一个对象释放了,就马上会回收的,内存占用高,不代表就是真的消耗了那么多

线程消耗

  多线程是解决一些性能问题的良方,但是线程是有成本的,线程太多,CPU会把时间浪费在线切换上  对于IO密集型的,最好采用异步的方式。同步方式意味着一个线程大部分时间消耗在等待上。  对于cpu密集性的,处理升级增加硬件投入,好像没有办法。  不要把ThreadPool中的线程耗光了,不然IIS就不响应了:1、asp.net也用这个线程池;2、每秒只会创建2个新线程;

CPU满负荷

  多数情况下,是死循环了  还有就是做了一些多余的事情

MsSql之Nolock

  通常,在MSSQL中,有Nolock的提示符,表示允许脏读,这种情况下,避免使用锁,非常有效。多数情况下,我们的一些数据并没有那么严格要求,即便是脏读,也没有什么关系。

MsSql之with(rowlock)

  使用Update语句,一些时候是明确只更新单行的,尤其是状态转换的,使用rowlock,会好一些(感觉,没有测试确认过)。