性能设计
蒲公英 2022-03-08
# 优化思路
在进行性能指标设计工作前,必须从理论上对性能指标的可实现性进行分析。理论上,系统的扩展模型可以分成两类,系统可扩展模型和不可扩展模型,如下图所示:
上图绿线代表了系统随着并发用户量的增加系统响应时间呈现线性增长的趋势,是一种可扩展的情况;但对于蓝线的方式则是不可扩展的,它将随着用户数量的增大而响应时间大大急剧增加,这种模型是完全不可控制的。
通过系统压力实验发现,即使是遵循可扩展模型设计的系统的响应性能和并发用户量并不能成永远的线性关系,在系统压力超过一定的值之后,如 100 并发,系统响应时间增加非常快,这个点称为拐点。在拐点以下,系统性能呈现良好的线性特性,在拐点以上,则呈现出非线性的特征,同时 CPU 和内存出现相当大的增长,甚至 100%占用。这种现象的出现,说明系统的性能不仅仅取决于软件系统,而也同时取决于承载系统的硬件基础环境,如计算能力和内存大小。为此,系统性能设计的目的就是为系统设置合理的拐点并发值,而不可能无限制的追求无限大的并发下系统响应仍旧呈现线形特征。
性能优化未必一次性就能满足的,可能此处瓶颈消失了,系统一旦运转快速后,在其他地方又发现新的性能瓶颈,所以性能优化是一个迭代的工作。直至满足系统需要的性能指标。
# 优化手段
具体来说将采用下面方式进行:
- 预处理技术的应用:预处理技术是一种在预定计划上由系统激发主动执行的计算模式,它对于一些处理内容固定,处理方式固定的功能非常有效,通过提前处理,实现数据生成时间和数据访问时间的隔离,在数据访问的时候不再需要为拿到结果而执行任何的计算,只需要简单的查询结果即可,这样可以大大增强系统的访问性能,有效的利用系统闲置时间。
- 变动态内容查找为静态数据访问:一些情况下,经过各种调优手段仍不能满足要求,就需要将一些动态的内容进行静态化处理,如可以将复杂的动态报表转化成 HTML 网页并发布在 WEB 服务器上,这种方式可以大大减轻应用服务器的访问压力,进一步减少用户等待的时间。例如,对一段历史时期的数据的汇总报表结果的查询,复杂报表结果等查询。
- 异步功能调用模式:对一些耗时较长的处理内容,如果必须由人工进行启动,那么,可以采用这种方式,用户调用程序的时候,实际上只是发送了一个消息给后台服务器,并在服务器端注册信息处理完后需要回馈的客户端,然后系统提示用户系统正在或很快处理这个任务,这样,立刻就能够解放用户,用户可以利用在后台处理的时间去处理其他的任务,在系统处理完后,采用推技术(push),将处理结果提示给用户,从而完成功能的调用全过程。
- 浏览器显示时采用分页、分时显示技术:用户从数据库查询得到的数据如果行数比较多,比如大于 100 行,在 IE 端显示就需要花费很长时间。分页技术,就是利用先显示结果的一部分,一般结果的前 50 条记录,后面的记录通过翻页的功能去显示其余部分。比如在查询正常计划详细列表页面时,通过查询得到 1000 条记录,如果全部显示这些记录,平均一条需要 0.05 秒,那么显示这些记录就需要 50 秒(近 1 分钟的时间)。利用分页技术,先从数据库结果集,读取前 20 条记录,显示在页面中,按平均一条需要 0.05 秒的显示时间,需要 1 秒钟的时间,这对一般的查询人员就可以接受。剩下的结果集,在通过用户点击下一页或直接定位的某页再从后端传对应的数据并显示。这项技术的使用,使在浏览器端的显示时间都控制在 1.5 秒钟以内。
- 应用层优化:应用层优化侧重于应用层本身的逻辑优化,算法优化,代码优化等。优化算法,选择合适高效的算法,降低不必要的递归,循环、多层循环嵌套等计算。避免申请过多的不必要的内存开销。降低内存泄露(using,Dispose,弱引用,Finalize)。使用频率较低的大文件,大对象,大数组等使用完毕后,及时释放。使用频率较高的大文件,大对象,大数组尽量缓存。考虑多线程技术。选择适当的通信方式:长连接,短连接,有以下方式 Socket、Remoting、Web Services(Rest,Soap)、WCF、 Named Pipes。降低应用之间通信次数,例用户认证服务,工作流服务,数据库服务。缓存机制:缓存常用的,不易变化的,偶有变化,可以考虑缓存依赖机制,支持异步计算,降低等待时间。
- 数据库优化调整策略:优化索引、SQL 语句、分析慢查询;设计数据表的时候,严格根据数据库的设计范式来设计数据库表;使用缓存,把经常访问的又不经常更改的数据放到缓存中,能减少磁盘 I/O;采用 MySQL 内部自带的表分区技术,把数据分成不同的文件,能够提高磁盘的读取效率;垂直分表,把不经常读的数据放在一张表里,以减少磁盘的 IO;主从分离读写,采用主从复制把读操作和写操作分离开来;选择合适的表引擎,参数优化。
- 脚本本地化技术:web 界面显示过程中,有相当大部分的脚本从服务器上下载到客户端。每次下载这些内容是毫无意义的,因此,可以通过在客户端设置缓冲区,将脚本在登陆的时候一次性的下载到本地,这样可以大大减少每次界面打开时从服务器获取的数据量,提升系统性能。
- 重点功能点优化:通过压力测试工具,寻找重点功能点上最占用资源(计算资源和内存资源)的瓶径,然后加以解决。再用压力测试工具寻找下一个最大瓶径,加以解决。这样反复处理,直到性能满足要求为止。