论文部分内容阅读
摘 要:本文主要简述了改进应用系统性能的常用策略,并从系统层次架构角度分别介绍了在不同领域所采用的方法,本文的侧重点放在解决问题的方法论上,期待能够达到抛砖引玉之效。
笔者在金融系统从事软件开发工作,目前在金融领域的绝大多数应用系统,包括储蓄、会计、信贷、财务、国际业务、网上银行等业务系统以及OA、"1104"、反洗钱、经营决策等低柜管理系统,均采用分布式三层技术架构,即持久层、业务逻辑层和展示层,对性能的持续改进是系统推广后是不得不面对的问题,下面我从应用系统的三层架构方面浅谈改进系统的性能的一些方法。
关键词:改进;应用系统;性能;常用策略
一、问题的提出
做过软件项目的人都深有体会,经过辛辛苦苦的需求、设计、开发、测试、部署上线等系列工作,还没来得及松口气就要不断接听接踵而至的用户电话,面对大量用户访问、高并发请求,技术人员最郁闷的事莫过于心爱的系统响应缓慢甚至宕机,这不仅会造成业务的延误,领导的问责,而且先天的心理自豪感也会荡然无存,面对表现不佳的分布式系统:是用户操作问题,应用程序问题,还是数据库问题?应该从何处进行改进?
在客观环境以及主观形式下,有人会在三层架构中根据经验斗胆选择一层作出推测,不再继续从浩繁的代码寻找错误或者低效率的算法,或者放弃彻底搜寻SQL语句和数据库表的做法。但遗憾的是,这种解决问题的方式经常是过度简化的,因为系统前端展示、应用程序、数据库都不是在孤立地运转。对系统性能的改进需要一种综合解决方法,应该提高对这个相互联系的系统内所有三个部分的能见度:数据库操作的执行效率、应用程序架构以及资源的利用和配置,还包括基本的硬件基础设施性能。
二、解决方案
在改进应用系统性能的解决方案中,首先让人想到的集中在这样几个环节:使用更高性能的服务器(或者为服务器增配)、更高性能的数据库、还有更高性能的容器中间件等等。如此解决思路并非不可,但也是最容易的,同时在一定程度上还意味着更大的资金投入和更难的决策层支持,并且这样的方案具备瓶颈,没有很好的扩展性,无法从根本上解决系统面临的高负载和高并发问题。笔者认为需从以下几个方面对系统进行"综合治理"。
(一)持久层面
该层在具体实现上一般表现为某一类数据库,其性能的改进主要体现在逻辑设计、物理设计和运行管理上。
1、数据库的逻辑设计结果不是唯一的,为提高基于数据库的应用系统的性能,通常以规范化理论为指导,适当地修改、调整数据模型的结构,称之为数据模型优化,要求数据模型达到第三范式以上。笔者曾经见到一个数据库设计采用自增1的sequences作为表的主键,非常值得商榷。
2、数据库物理设计需要对时间效率、空间效率、维护代价和各种用户要求进行权衡,结果会产生多种方案,必须对此进行细致评价,选择一个较优的方案作为数据库的物理结构。例如,存放n年业务数据的物理表,随着时间的增加会达到千百甚至上亿数据量级的记录,对于复杂查询几乎就是一种灾难,此时应该采用数据库分区技术,能够成倍提高系统的响应速度。
3、数据库的运行管理主要通过对数据库的参数进行调整来达到改进性能的目的。在决定进行系统性能调优级时,首先应制定一个完善的调优级方案,先监控系统并分析问题所在,然后根据分析结果每次调整一个参数,再进一步监控系统查看系统性能有无变化,然后做进一步调节。其中有一个重要的原则:每次最好只调节一个参数。
数据库性能通常与磁盘I/O、CPU、共享内存和网络4个方面有关,孰轻孰重,要根据整个系统的实际情况具体分析。
(二)业务逻辑层面
该层实现了应用系统的主要业务逻辑,包含典型的应用程序、关键技术以及支撑整个系统运转的应用服务器等硬件设备,其性能的改进主要体现在下述几个方面。
1、应用程序
应用程序的优化通常可分为两个方面:源代码优化和SQL语句优化,前者可以采取更高效率的算法、增加并发处理能力以及及时回收空闲资源等等,除了一些程序BUG必须进行调整外,源代码优化很大程度在时间成本和风险控制上代价很高;后者,一个好的SQL往往可以使系统的性能提高数十倍,那种认为SQL优化是DBMS的任务,与程序中的SQL语句关系不大的想法是错误的!尽管现在数据库产品在SQL优化方面做得越来越好,但很难设想一个原本糟糕的SQL经过系统优化后会变得高效,因此SQL语句的优劣至关重要,优化SQL的建议如下:
(1)合理使用索引:where子句中的变量顺序应与索引键顺序相同。
(2)将最具有限制性的条件放在前面,大值在前,小值在后。
(3)尽量避免采用matches或like通配符匹配查询。
(4)尽量避免相关子查询,嵌套层次越多效率越低,如果子查询不可避免,要在其中过滤掉尽可能多的行。
(5)尽量避免或简化排序,正确地增建索引,若排序不可避免,应试图简化,如缩小排序字段的范围等。
(6)消除对大型表行数据的顺序存取。比如采用顺序存取策略,一个嵌套3层的查询,若每层查询1000行,则此查询要查询1,000,000,000行数据,这种查询可能会导致非常严重的后果,避免这种情况的主要方法就是对连接的字段进行索引。
(7)对大数据量的求和尽量避免使用单一的sum命令,可采用group by方式与其结合,有时效率可提高几倍甚至百倍。
(8)select操作时避免会引起磁盘读写的rowid操作,这是一个物理过程,会影响性能。
(9)使用临时表加速查询,把表的一个子集进行了排序并创建临时表,有助于避免多重排序操作,能加速查询。
(10)有批量SQL语句的任务,可以使用存储过程,不将这些语句编码在应用程序中,还能减少网络流量。
(11)只返回应用程序需要的数据,筛除所有非必要的行和列。
2.关键技术
缓存技术
应用系统的缓存技术非常重要,在整个生命周期内将频繁访问的对象、数据、页面或者元素放在缓存中,在需要时直接读取,从而有效避免频繁访问持久性存储器,提高系统响应性能。具体可以从架构方面、程序开发方面进行改进,各种语言基本都有自己的缓存模块和方法。
流量管理技术
包括在局域网和广域网两种情况下管理网络流量,采用流量管理技术,可以充分利用服务器和网络带宽资源,使系统达到智能流量管理的方式,能够在发生拥塞的网络中,保证各个业务的服务质量。
镜像技术
是大型应用常采用的提高性能和数据安全性的方式,镜像技术可以解决不同网络接入和地域带来的用户访问速度差异,使数据进行定时更新或者实时更新。具体实现方面有很多专业的现成的解决架构和产品可选,也有通过软件实现的方案,比如Linux上的rsync等工具。
负载均衡技术
负载均衡将是大型应用高负荷访问和大量并发请求采用的终极解决办法,它提供了一种有效的方法来扩充服务器带宽,增加吞吐量,提高网络的灵活性和可用性。其中有两个架构供参考:一是硬件四层交换,知名产品如F5、Alteon等,能够提供非常优秀的性能和很灵活的管理能力;二是基于OSI模型来实现的软件四层交换,性能稍差,但对满足一定的系统压力还是游刃有余的。
对负载均衡的应用,可以从网络的不同层次入手,具体情况要看瓶颈所在,不外乎从传输链路聚合、采用更高层网络交换技术和设置服务器集群策略三个角度实现,一个典型的使用负载均衡的策略就是,在软件或者硬件四层交换的基础上搭建集群,这样的架构成本低、性能高还有很强的扩张性,随时往架构里面增减节点都非常容易。
专用技术
对于特定类型的应用,比如基于J2EE实现的B/S架构应用系统,可以考虑从专用技术角度实现性能改进,兹举两例:
i、HTML静态化:WEB服务器中效率最高、消耗最小的就是纯静态化的html页面,所以尽可能使应用上的页面采用静态页面来实现,这是最简单也是最有效的方法,同时,html静态化也是某些缓存策略使用的手段,对于系统中频繁使用数据库查询但是内容更新很小的应用,可以考虑使用html静态化来实现。此外,在进行html静态化的时候还可以使用一种折中的方法,就是前端使用动态实现,在一定的策略下进行定时静态化和定时判断调用,这个能实现很多灵活性的操作。
ii、图片服务器分离:对于WEB服务器来说,不管是WebLogic、Apache、IIS还是其他容器,图片都是比较消耗资源的,有必要将图片与页面进行分离,大型应用基本上都会采用的这种策略,可以降低提供页面访问请求的服务器系统压力,还可以保证系统不会因为图片问题而崩溃。
3、应用服务器
对于一个高负载的应用系统,采用多服务器的分布结构也是一个不错的选择。多服务器并行工作的方式可以选择以下两种之一:一是所有服务器的内容完全相同,根据用户的IP来决定访问哪一台;另一种方式是每台服务器所起的作用不同,属于非对称的体系结构,例如一台服务器用于提供静态网页,另一台用于提供动态网页等。
(三)展示层面
在展示层面,主要是应用缓存技术,将服务器的数据或文件缓存到客户端本地,使重复访问相同的内容时,直接从本地缓存读取发送给用户,而不且再连接到远程服务器,提高访问速度并减少网络流量。
(四)其他方面
1、持久层与业务逻辑层之间如果没有采用连接池技术,则十分有必要改进原数据库连接方式,试想用户的每次请求都要进行重新连接、交互、释放,在大并发量的情况下简直不可想象。
2、提高应用系统的性能,还可以从操作系统方面进行改进。
(1)进行定期的磁盘检查和磁盘空间清理,当系统运行一段时间后,会出现一定的文件错误和磁盘碎片,此时就需要进行磁盘整理。
(2)自动关闭停止响应的程序,无须进行手工干预。
(3)调整应用程序优先级,让常用程序拥有较高的优先权,自然运行速度就会快些。
三、结束语
分析应用系统性能还需要有针对性选择性能诊断工具,当然经验也是至关重要的,在应用系统性能改进过程中,一件有效的工具和解决问题的方法能有效的将各类问题分配给合适的专家,减少跟踪性能问题的人数,减少解决问题时的挫折、费用和时间,从而提高用户的满意程度。
在对应用系统改进所采取的策略中,前面提到的每个方法可能都会被用到,本文介绍得比较粗浅,具体实现过程中很多细节还需要慢慢熟悉和体会,有时一个很小的参数设置,对于系统性能的影响就会很大,在此仅概而述之,以期达到抛砖引玉之效。
笔者在金融系统从事软件开发工作,目前在金融领域的绝大多数应用系统,包括储蓄、会计、信贷、财务、国际业务、网上银行等业务系统以及OA、"1104"、反洗钱、经营决策等低柜管理系统,均采用分布式三层技术架构,即持久层、业务逻辑层和展示层,对性能的持续改进是系统推广后是不得不面对的问题,下面我从应用系统的三层架构方面浅谈改进系统的性能的一些方法。
关键词:改进;应用系统;性能;常用策略
一、问题的提出
做过软件项目的人都深有体会,经过辛辛苦苦的需求、设计、开发、测试、部署上线等系列工作,还没来得及松口气就要不断接听接踵而至的用户电话,面对大量用户访问、高并发请求,技术人员最郁闷的事莫过于心爱的系统响应缓慢甚至宕机,这不仅会造成业务的延误,领导的问责,而且先天的心理自豪感也会荡然无存,面对表现不佳的分布式系统:是用户操作问题,应用程序问题,还是数据库问题?应该从何处进行改进?
在客观环境以及主观形式下,有人会在三层架构中根据经验斗胆选择一层作出推测,不再继续从浩繁的代码寻找错误或者低效率的算法,或者放弃彻底搜寻SQL语句和数据库表的做法。但遗憾的是,这种解决问题的方式经常是过度简化的,因为系统前端展示、应用程序、数据库都不是在孤立地运转。对系统性能的改进需要一种综合解决方法,应该提高对这个相互联系的系统内所有三个部分的能见度:数据库操作的执行效率、应用程序架构以及资源的利用和配置,还包括基本的硬件基础设施性能。
二、解决方案
在改进应用系统性能的解决方案中,首先让人想到的集中在这样几个环节:使用更高性能的服务器(或者为服务器增配)、更高性能的数据库、还有更高性能的容器中间件等等。如此解决思路并非不可,但也是最容易的,同时在一定程度上还意味着更大的资金投入和更难的决策层支持,并且这样的方案具备瓶颈,没有很好的扩展性,无法从根本上解决系统面临的高负载和高并发问题。笔者认为需从以下几个方面对系统进行"综合治理"。
(一)持久层面
该层在具体实现上一般表现为某一类数据库,其性能的改进主要体现在逻辑设计、物理设计和运行管理上。
1、数据库的逻辑设计结果不是唯一的,为提高基于数据库的应用系统的性能,通常以规范化理论为指导,适当地修改、调整数据模型的结构,称之为数据模型优化,要求数据模型达到第三范式以上。笔者曾经见到一个数据库设计采用自增1的sequences作为表的主键,非常值得商榷。
2、数据库物理设计需要对时间效率、空间效率、维护代价和各种用户要求进行权衡,结果会产生多种方案,必须对此进行细致评价,选择一个较优的方案作为数据库的物理结构。例如,存放n年业务数据的物理表,随着时间的增加会达到千百甚至上亿数据量级的记录,对于复杂查询几乎就是一种灾难,此时应该采用数据库分区技术,能够成倍提高系统的响应速度。
3、数据库的运行管理主要通过对数据库的参数进行调整来达到改进性能的目的。在决定进行系统性能调优级时,首先应制定一个完善的调优级方案,先监控系统并分析问题所在,然后根据分析结果每次调整一个参数,再进一步监控系统查看系统性能有无变化,然后做进一步调节。其中有一个重要的原则:每次最好只调节一个参数。
数据库性能通常与磁盘I/O、CPU、共享内存和网络4个方面有关,孰轻孰重,要根据整个系统的实际情况具体分析。
(二)业务逻辑层面
该层实现了应用系统的主要业务逻辑,包含典型的应用程序、关键技术以及支撑整个系统运转的应用服务器等硬件设备,其性能的改进主要体现在下述几个方面。
1、应用程序
应用程序的优化通常可分为两个方面:源代码优化和SQL语句优化,前者可以采取更高效率的算法、增加并发处理能力以及及时回收空闲资源等等,除了一些程序BUG必须进行调整外,源代码优化很大程度在时间成本和风险控制上代价很高;后者,一个好的SQL往往可以使系统的性能提高数十倍,那种认为SQL优化是DBMS的任务,与程序中的SQL语句关系不大的想法是错误的!尽管现在数据库产品在SQL优化方面做得越来越好,但很难设想一个原本糟糕的SQL经过系统优化后会变得高效,因此SQL语句的优劣至关重要,优化SQL的建议如下:
(1)合理使用索引:where子句中的变量顺序应与索引键顺序相同。
(2)将最具有限制性的条件放在前面,大值在前,小值在后。
(3)尽量避免采用matches或like通配符匹配查询。
(4)尽量避免相关子查询,嵌套层次越多效率越低,如果子查询不可避免,要在其中过滤掉尽可能多的行。
(5)尽量避免或简化排序,正确地增建索引,若排序不可避免,应试图简化,如缩小排序字段的范围等。
(6)消除对大型表行数据的顺序存取。比如采用顺序存取策略,一个嵌套3层的查询,若每层查询1000行,则此查询要查询1,000,000,000行数据,这种查询可能会导致非常严重的后果,避免这种情况的主要方法就是对连接的字段进行索引。
(7)对大数据量的求和尽量避免使用单一的sum命令,可采用group by方式与其结合,有时效率可提高几倍甚至百倍。
(8)select操作时避免会引起磁盘读写的rowid操作,这是一个物理过程,会影响性能。
(9)使用临时表加速查询,把表的一个子集进行了排序并创建临时表,有助于避免多重排序操作,能加速查询。
(10)有批量SQL语句的任务,可以使用存储过程,不将这些语句编码在应用程序中,还能减少网络流量。
(11)只返回应用程序需要的数据,筛除所有非必要的行和列。
2.关键技术
缓存技术
应用系统的缓存技术非常重要,在整个生命周期内将频繁访问的对象、数据、页面或者元素放在缓存中,在需要时直接读取,从而有效避免频繁访问持久性存储器,提高系统响应性能。具体可以从架构方面、程序开发方面进行改进,各种语言基本都有自己的缓存模块和方法。
流量管理技术
包括在局域网和广域网两种情况下管理网络流量,采用流量管理技术,可以充分利用服务器和网络带宽资源,使系统达到智能流量管理的方式,能够在发生拥塞的网络中,保证各个业务的服务质量。
镜像技术
是大型应用常采用的提高性能和数据安全性的方式,镜像技术可以解决不同网络接入和地域带来的用户访问速度差异,使数据进行定时更新或者实时更新。具体实现方面有很多专业的现成的解决架构和产品可选,也有通过软件实现的方案,比如Linux上的rsync等工具。
负载均衡技术
负载均衡将是大型应用高负荷访问和大量并发请求采用的终极解决办法,它提供了一种有效的方法来扩充服务器带宽,增加吞吐量,提高网络的灵活性和可用性。其中有两个架构供参考:一是硬件四层交换,知名产品如F5、Alteon等,能够提供非常优秀的性能和很灵活的管理能力;二是基于OSI模型来实现的软件四层交换,性能稍差,但对满足一定的系统压力还是游刃有余的。
对负载均衡的应用,可以从网络的不同层次入手,具体情况要看瓶颈所在,不外乎从传输链路聚合、采用更高层网络交换技术和设置服务器集群策略三个角度实现,一个典型的使用负载均衡的策略就是,在软件或者硬件四层交换的基础上搭建集群,这样的架构成本低、性能高还有很强的扩张性,随时往架构里面增减节点都非常容易。
专用技术
对于特定类型的应用,比如基于J2EE实现的B/S架构应用系统,可以考虑从专用技术角度实现性能改进,兹举两例:
i、HTML静态化:WEB服务器中效率最高、消耗最小的就是纯静态化的html页面,所以尽可能使应用上的页面采用静态页面来实现,这是最简单也是最有效的方法,同时,html静态化也是某些缓存策略使用的手段,对于系统中频繁使用数据库查询但是内容更新很小的应用,可以考虑使用html静态化来实现。此外,在进行html静态化的时候还可以使用一种折中的方法,就是前端使用动态实现,在一定的策略下进行定时静态化和定时判断调用,这个能实现很多灵活性的操作。
ii、图片服务器分离:对于WEB服务器来说,不管是WebLogic、Apache、IIS还是其他容器,图片都是比较消耗资源的,有必要将图片与页面进行分离,大型应用基本上都会采用的这种策略,可以降低提供页面访问请求的服务器系统压力,还可以保证系统不会因为图片问题而崩溃。
3、应用服务器
对于一个高负载的应用系统,采用多服务器的分布结构也是一个不错的选择。多服务器并行工作的方式可以选择以下两种之一:一是所有服务器的内容完全相同,根据用户的IP来决定访问哪一台;另一种方式是每台服务器所起的作用不同,属于非对称的体系结构,例如一台服务器用于提供静态网页,另一台用于提供动态网页等。
(三)展示层面
在展示层面,主要是应用缓存技术,将服务器的数据或文件缓存到客户端本地,使重复访问相同的内容时,直接从本地缓存读取发送给用户,而不且再连接到远程服务器,提高访问速度并减少网络流量。
(四)其他方面
1、持久层与业务逻辑层之间如果没有采用连接池技术,则十分有必要改进原数据库连接方式,试想用户的每次请求都要进行重新连接、交互、释放,在大并发量的情况下简直不可想象。
2、提高应用系统的性能,还可以从操作系统方面进行改进。
(1)进行定期的磁盘检查和磁盘空间清理,当系统运行一段时间后,会出现一定的文件错误和磁盘碎片,此时就需要进行磁盘整理。
(2)自动关闭停止响应的程序,无须进行手工干预。
(3)调整应用程序优先级,让常用程序拥有较高的优先权,自然运行速度就会快些。
三、结束语
分析应用系统性能还需要有针对性选择性能诊断工具,当然经验也是至关重要的,在应用系统性能改进过程中,一件有效的工具和解决问题的方法能有效的将各类问题分配给合适的专家,减少跟踪性能问题的人数,减少解决问题时的挫折、费用和时间,从而提高用户的满意程度。
在对应用系统改进所采取的策略中,前面提到的每个方法可能都会被用到,本文介绍得比较粗浅,具体实现过程中很多细节还需要慢慢熟悉和体会,有时一个很小的参数设置,对于系统性能的影响就会很大,在此仅概而述之,以期达到抛砖引玉之效。