高并发Web应用系统的性能优化分析与研究
2014-12-23王亚楠吴华瑞
王亚楠,吴华瑞+,黄 锋
(1.北京农业信息技术研究中心,北京100097;2.国家农业信息化工程技术研究中心,北京100097;3.农业部农业信息技术重点实验室,北京100097)
0 引 言
Web应用系统在大量用户并发访问的情况下,容易出现网站响应时间过慢的情况,甚至会由于服务器负担过重,导致系统的崩溃和瘫痪。因此如何对应用系统性能进行最大限度地优化处理,已成为设计开发人员不可忽视的问题。现阶段针对高并发Web应用系统性能低下的问题,解决方案主要围绕以下几个方面:提高服务器配置,提高数据库性能,提高Web容器的性能等,但上述手段很大程度限制了系统的扩展性,并加重了系统开发与维护成本。本文以全国基层农业技术推广体系管理信息系统为例,从影响系统性能的因素着手进行分析,针对Web前端、后台程序、数据库、Web应用中间件以及服务器5部分的处理给出了优化方案。由于在每一部分的方案中,并不能穷举所有的优化手段,因此只从典型常用而又容易被忽视的几点着手进行说明。
1 系统性能优化必要性
一个Web应用系统性能的优劣主要由以下几项决定:页面响应时间、最大并发连接数、单位时间内处理的HTTP事物数以及服务器HTTP带宽。虽然可以通过扩大服务器内存、增加网络出口带宽等方式在一定程度上提升系统性能,但却不是解决问题的根本方法。为充分发挥系统效能,达到最佳的运行效果,只有从系统自身入手,打造一个精简、性能优良的高质量Web应用系统,而不是完全依赖于服务器的硬件配置,才是最有效、最彻底的优化手段。
2 系统优化方案
在实际运行过程中,影响Web应用系统性能的因素有很多种,本节主要针对Web 应用前端、后台程序、数据库、Web应用中间件以及服务器这5大部分进行分析,并分别根据分析结果提出具体的优化方案。
2.1 Web前端的优化方案
在对Web前端进行优化之前,需要了解页面的加载过程。页面加载时,首先下载到浏览器的是纯粹的HTML 文档,其不包括任何图片、样式,只是一个页面的HTML 骨架,此过程只占整个页面加载过程的10%。在HTML框架加载完成后,进入到页面的解析步骤,浏览器将会由上至下依次进行解析。首先对HEAD 标签进行解析,期间如果遇到引用的JS文件、CSS文件等,浏览器将会停止页面的加载过程,转而对该文件进行请求,请求完成后将会继续加载页面。HEAD 标签解析完成后,会进入到BODY 标签的解析过程,如果在解析过程中遇到IMG 标签,浏览器将会请求IMG 标签对应的SRC内容,如果有多个IMG 标签,那么浏览器会并发的请求IMG 标签对应的SRC。解析过程中的时间线如图1所示。
图1 各部分响应时间
基于以上对于页面加载过程的描述,可以发现,对于高并发网站,页面质量严重影响到网站的运行速度。如果页面过大,在页面加载时便会耗费巨大的网络带宽,因此页面设计时应该尽可能的简洁,以此减少不必要的网络流量,来缓解高并发所带来的带宽压力[1]。因此,对Web前端的优化,可以从以下几个方面入手。
(1)减少外部文件的引用,必要时可通过合并多个外部文件实现。通过该方法可以尽量减少HTTP请求。
(2)将页面加载时未用到的外部文件放到页面底部加载,以减少页面加载过程中请求外部文件时的等待时间。
(3)将网站中用到的重复文件缓存到浏览器,将会减少HTTP请求以及远程服务器负载,大大缩短页面的载入时间。
(4)图片压缩。通过对页面的像素处理、格式转换、清除图片注释等方式来减少图片大小。
(5)AJAX 异步加载。该方法可以在不刷新页面的情况下来更新页面上的内容,避免了JS文件、图片等的重新载入,减少用户等待页面渲染的时间。
2.2 后台程序的优化方案
2.2.1 session的设置
当多个请求和服务器建立Web连接的时候,由于无状态记忆的特点,连接之间不能进行状态的共享。例如在用户登录时,记录用户的唯一标识为 “login_1”,但在之后进行其它请求,例如修改密码时,将无法定位该用户来获得用户的信息。而由于一个session中定义的变量在session的生命周期内可作用于用户访问的所有链接,因此session经常被用来用作全局变量的传递。在这种情况下,用户登录时,将用户的唯一标识 “login_1”存储在session 内,当用户需要修改密码时,系统将session中的标识码与存储数据进行比对,便可成功定位到该用户,修改该用户的密码。
正是由于session的便捷性、安全性,致使很多技术开发人员在程序代码中大量使用session 变量,由于session是以文本形式存储在服务器端的,因此在用户高并发访问时会产生大量用于session 持久性的内存,增加服务器的压力。
考虑到这种情况,应尽量精简session中的信息,只把用户触发事件时经常用到的信息存储到session内,同时,当用户退出此次访问后,应立即销毁释放对应的session,以此降低其占有的服务器内存。另外,为了防止不活跃session长时间占有内存的情况出现,可以根据实际情况自主设置session的超时时间,代码片段如下:
2.2.2 数据库操作语句的优化
目前,对于关系型数据库,都需要通过编写数据库操作语句来访问数据。因此对数据库操作语句的优化成为必不可少的一部分,在实际编写过程中,需要根据项目规模、数据关系等因素反复进行分析以实现语句的最优化。
举一个简单的例子,示例表中存储了不同单位历年的人员信息,见表1。
表1 示例
当需要从表中查询2012年A 单位的人员姓名时,在查询语句拼写过程中很容易出现以下的情况:
select*from tabel_1where year=?and unitName=?
该语句会根据查询条件将所有满足要求的元组查询出来,相比之下,如下的语句将大大减少与数据库信息交换时产生的流量,降低I/O 代价:
select peopleName from tabel_1 where year=?and unitName=?
再进一步优化成如下语句:
select peopleName from tabel_1 where unitName=?and year=?
该语句较上一语句,调换了单位名称和年份的查询顺序。分析该条语句的查询过程,首先在根据单位名称进行查询时,结果会筛选出A 单位对应的2条数据,之后再在这2条数据中,筛选出2012 年的信息;而上一条查询语句,首先是根据年份进行查询,筛选出3 条数据,之后在这3条数据中,筛选出A 单位对应的信息,过程对比如图2所示。基于以上分析,当进行海量数据查询时,这一优化策略会使得中间结果大大变小,大幅度提高查询效率。
图2 中间过程对比
2.2.3 数据分页技术
利用分页技术使得每次展示给用户的固定的数据量,减少数据库查询的工作量,降低网络传输的负荷,同时也可以避免用户在使用过程中因查阅大量数据产生的疲倦感[2]。
例如每一页显示的数据条数为PageCount,当前页数为CurrentBegin,当查询从第PageCount* (CurrentBegin-1)开始的PageCount条数据时,得到的结果就是当前页中的数据,当需查询 “上一页”数据的时候,只需将Current-Begin设置为CurrentBegin-1,重新检索即可。当需查询“下一页”数据时,将CurrentBegin设置为CurrentBegin+1,即可得到所需数据。
2.2.4 数据缓存
每当程序与数据库创建连接时,都需要通过匹配用户名、密码与数据库进行连接验证,该过程耗费很大的资源和时间。在高并发情况下,程序频繁访问数据库表,势必会造成系统性能的降低,因此在数据处理过程中,针对频繁访问的数据,在中间层建立数据缓存[3],减少数据库的访问次数,可以较大程度上提高系统响应速度。
对于会被频繁查询而很少或几乎不被修改的基准表,如全国行政区划数据库表,在程序启动时,可以将其数据缓存到静态类里,在用户需要用到表中内容时,便可直接到缓存内进行查找,以减轻数据库访问的压力,提高系统性能。Spirng中提供了@Component注释,可以把普通pojo实例化到Spirng容器中,代码片段如下:
在对该类进行@Component注释后,Spring启动时便会自动调用initDao方法,查询一次数据库,将表内内容以Map格式存储到全局变量内。当该数据表中的数据有所更改时,可在程序相应部分调用initDao方法,以实现数据库与缓存中内容的完全一致。
2.2.5 页面静态化
在类似首页、门户等的汇总展示页面中,不可避免的会调用大量的数据库操作语句,获取信息来填充页面框架,在读取存储在数据库或者其它存储媒介中内容的时候,由于其操作语句的复杂性、频繁性会造成服务器端处理数据的压力,影响到系统性能以及用户体验。针对该类页面,可以将其做静态化处理,在不改变页面原本内容的情况下作为HTML静态页面存储,可以省去频繁连接数据库等一系列动态操作的过程,从而使整个页面的渲染变得更加迅速。读取静态页面流程如图3所示。
图3 读取静态页面流程
在用户发送请求后,如果存在对页面信息的更改操作,则删除其对应的静态页面,该过程保证了所存储的HTML页面内始终为最新信息。如果该请求为读取操作,需要判断是否存储了相应的HTML 页面,如果有则直接读取,没有则对请求进行编译,生成静态页面。该过程保证了在页面没有更改信息的情况下,只动态读取一次信息,之后的请求都将直接访问静态页面,从而避免了与存储媒介进行数据交互的过程,访问速度较动态页面有大幅度提升,同时也降低了数据库的访问压力,系统在性能上也有显著改善。
2.3 数据库的优化方案
数据库优化的主要目的是最大限度的降低数据响应时间和提高数据库的吞吐量[4]。为达到此目的,需要了解系统具体需求以及数据的逻辑结构,甚至需要在不同优化策略之间进行权衡。
2.3.1 创建索引
当数据库执行操作语句时,在默认情况下是根据条件进行全表扫描,每当遇到匹配项时,便将其添加到搜索结果内;在已经对某唯一标识建立索引的情况下,查询时会先去索引中定位符合条件的纪录行数,从而得到所需结果。如果把数据库理解为一本书,那么索引便是这本书的目录,根据目录去书里查找内容显然比逐页查找要迅速。索引的结构与二叉树类似,根据关键码完成对信息的访问,根据少量的信息读取便可以定位到正确的行[5]。建立索引的本质目的是提高数据库检索效率,进而提高应用系统的性能,但是索引的建立和存储会占用一定的物理空间,更改表内数据时索引也要进行相应的动态维护,从而影响到维护数据的速度,通常需要在有下列特征的字段上建立索引[6]:①建立了主键或者外键的字段;②需要频繁、快速查询的字段;③定义了排序规则的字段;④在检索过程中,相互之间需要组合到一起的字段。
2.3.2 数据分表存储
对于存储大量纪录的数据库表,执行一次操作会耗费相对较长的时间,尤其在高并发访问下,容易造成服务器负荷激增,检索速度急速下降。而将数据分表存储,可以减少查询时操作的纪录条数,避免无关数据的访问,提高检索速度。数据分表存储,找到适合的分表方法非常重要,例如可以将数据按照某种标识进行分表,如将标记为已删除的记录、标记为存档不做修改的记录进行分表存储。又如:将历史数据与当前数据分放在不同的数据表内,这样逐次累积的数据量几乎影响不到当前表的大小,可以使得当前表的记录条数、维护效率都维持在一定的范围内。
2.3.3 修改缺省配置
数据库可用内存是影响其性能的一个重要因素,但大多数数据库服务默认安装后,都设有一个缺省内存,如SQL服务使用的缺省内存不超过1.8G,在此情况下,即便较大幅度的升级了服务器的配置,系统性能也不会因此而有明显提升。因此为了提供给数据库最适宜的内存需求,需要修改数据库服务的参数配置。如可对NON_HEAP_SE (DBM)、MAXAPPLS (DB)等参数进行重新设置,具体配置参照有关数据库专业资料。
2.4 Web中间件的配置优化方案
中间件独立于服务器客户端的操作系统之上,其作用是用来管理网络通信以及计算机资源[7]。其根本作用是为应用层提供运行开发环境,进行信息的交换,以实现集成复杂应用的目的。中间件原理如图4所示。
图4 中间件原理
中间件的结构体系由数据库、中间件、Web服务构成,其本身不能够独立运行,必须部署在中间件容器之中,才能够正常运行[8]。中间件的使用不仅可以缩短开发周期,也减少了维护、运行和管理的工作量。因此,中间件是一个完整系统的重要组成部分,如果在项目初期没有制定合理的规范,将会严重到系统的性能甚至稳定性,所以,制定合理的中间件环境规范是十分必要的。
2.4.1 更改默认连接数
在高并发访问情况下,请求连接中间件的线程数量会增多,这会导致大部分请求一直处于排队的情况中,随着请求的增多,等待排队的最大时间也会越来越大,这会导致响应时间的增大,影响到系统性能。因此需要根据实际项目情况,修改中间件的默认配置。以tomcat为例,配置文件中和连接相关的参数有maxThreads、acceptCount、connnectionTimeout和minSpareThreads等。默认配置如下:
如maxThreads表示可创建的最大连接线程数;accept-Count表示当连接线程数达到最大时,可以接受排队的请求个数。因此可以适当修改默认配置的值,增大并发连接数,以满足系统需求。
2.4.2 增加中间件可使用内存
Tomcat本身不能直接在计算机上运行,需要依赖于操作系统和一个java虚拟机。在大负载情况下,应用程序会占用更多的内存,当应用程序需要的内存超出堆的最大值时,虚拟机就会提示内存溢出,并且导致应用服务的崩溃,因此需要更改java虚拟机可使用的内存值来提升系统性能。
例如:在文件/bin/catalina.bat的前面,增加如下设置:JAVA_OPTS='-Xms256m-Xmx512m',表示初始化内存为256 MB,可以使用的最大内存为512 MB。
2.5 服务器的优化方案
在系统实际应用中,尤其在多节点、高并发访问的情况下,经常会出现服务器负载过重的情况,而单纯的升级一台服务器的配置已经不能满足需求,必须设置多台物理服务器,采用负载均衡技术构建系统。负载均衡技术在减少网络堵塞以及提高服务器响应速度方面具有显著的效果,其原理是根据具体的策略,将接收到的请求分配给特定的服务器。通过软件或者硬件技术均可以实现负载均衡,常用的软件有LVS,ginx等,硬件有F5,A10等。在性能方面,硬件设备比软件更为可靠[9]。负载均衡的方法有很多种,以下是目前较为常用的几种方式:①软件负载均衡;②反向代理负载均衡;③DNS负载均衡;④硬件负载均衡;⑤基于NAT 的负载均衡[10]。
3 实例分析
全国基层农业技术推广体系管理信息系统目前拥有部级用户8 人,省级用户4000 余人,市级用户200 000 人,县级用户400 000人,其中峰值并发访问量可达10 000人。另外系统每季度均会进行一次全国范围的数据采集工作,每次采集到的各类信息可达200 0000余条。针对这种大用户、大数据、高并发访问的情况,系统的性能面临很大的考验,因此系统基于本方案对各部分进行了优化。
在Web应用系统中,请求的响应时间为网络响应时间、服务器响应时间和页面渲染时间之和 (图5),即:TTLB= (N1+N2+N3+N4)+ (A1+A2+A3)+W1。
图5 请求响应时间构成
在网络带宽一定的情况下,只考虑服务器响应时间以及页面渲染时间即可验证系统的响应性能是否有显著优化。以并发访问量较高的登陆功能为例,单个请求的各部分响应时间对比见表2。
表2 各部分响应时间对比
由表2结果可知,通过执行系统前后端的各项优化策略,单个请求的页面响应时间缩短了20%。
而在6000用户并发访问的情况下,登陆响应时间、应用服务器CPU 利用率、数据库服务器CPU 利用率对比结果见表3。
表3 响应时间及利用率对比
通过表3对比可知,系统无论是在响应时间还是服务器CPU 利用率上都有了较大幅度的提高,其中应用服务器CPU 利用率降低了40%,数据库服务器CPU 利用率降低了35%。
在最近一次的数据采集工作中,系统的各部分功能运行正常,各个服务器的利用率均未突破85%,响应时间维持在2.5秒以内,这也验证了本方案的有效性以及可应用性。
4 结束语
本文针对全国基层农业技术推广体系管理信息系统,分析并提供了高并发Web应用系统的性能优化策略。首先分析了Web应用在大量用户并发访问的情况下,网站响应时间过慢、服务器超负载的原因并随后提出了较为典型的优化方案。从Web页面渲染到服务器负载均衡优化这五大方面,给出了Web应用系统在高并发情况下的优化方案,在最大并发连接数、单位时间内处理的HTTP事物数以及服务器HTTP带宽等方面,较大程度上提高了系统性能。该优化方案在实际应用中得到了有效验证,成功地提高了Web应用系统的响应时间以及负载能力,对高并发Web应用系统的优化具有重要的意义。
[1]LI Junfeng,HE Mingxin.Design and implementation of Webbased air ticket seckill system with high-concurrency [J].Computer Engineering and Design,2013,34 (3):778-782(in Chinese).[李军锋,何明昕.高并发Web航空票务秒杀系统的设计与实现 [J].计算机工程与设计,2013,34 (3):778-782.]
[2]SUN Daiyao.Paging technology achieved by java and sqlserver[J].Heilongjiang Science and Technology Information,2009,13 (10):62 (in Chinese).[孙代耀.谈java与sqlserver结合实现数据分页技术 [J].黑龙江科技信息,2009,13(10):62.]
[3]CHEN Liyan.Design and implementation of medicine distribution system in multiple shops based on J2EE [J].Computer Engineering and Design,2009,30 (4):1010-1012 (in Chinese).[陈立岩.基于J2EE 连锁医药经销系统的设计与实现[J].计算机工程与设计,2009,30 (4):1010-1012.]
[4]DU Zhiyuan,LIU Gang,WANG Yongzhi.Research on performance optimization of database in university educational administration management system [J].Computer Engineering and Design,2007,28 (20):5066-5068 (in Chinese).[杜志源,刘刚,王永智.高校教务管理系统数据库性能优化的研究 [J].计算机工程与设计,2007,28 (20):5066-5068.]
[5]ZENG Chuanjun,FU Xiufen.Intelligence information management system based on index performance analysis [J].Computer Engineering and Design,2012,33 (2):571-574 (in Chinese).[曾传军,傅秀芬.基于索引性能分析的情报信息管理系统研究[J].计算机工程与设计,2012,33 (2):571-574.]
[6]HE Dongli.Discussion on database design and optimization method in teaching [J].Science and Technology Information(Academic Research),2007,25 (24):329-330 (in Chinese).[何冬黎.数据库原理教学中数据库设计优化方法探讨[J].科技信息 (学术研究),2007,25 (24):329-330.]
[7]QIN Wei,HE Xinhua.Research of Web tickets platform based on high availability load balancing [J].Computer Engineering and Design,2009,30 (23):5321-5324 (in Chinese). [覃伟,何新华.基于高可用性负载均衡的Web 票务平台研究[J].计算机工程与设计,2009,30 (23):5321-5324.]
[8]ZHANG Yonghua.Research and practice of middleware performance optimization based on Web EOMS [J].Telecommunications Science,2011 (11):147-154 (in Chinese). [张永华.基于Web中间件的运维管理系统的性能优化方法研究与实践 [J].电信科学,2011 (11):147-154.]
[9]BAO Lihui,HUANG Yanfei.Research on architecture of high concurrent website and its solution [J].Computer Science,2012,39 (10):184-187 (in Chinese).[包立辉,黄彦飞.高并发网站的架构研究及解决方案 [J].计算机科学,2012,39(10):184-187.]
[10]XUE Zhi.Research and design of performance tunning and high availability in e-commerce Web platform [D].Shanghai:Shanghai Jiao Tong University,2007:41-45 (in Chinese).[薛质.电子商务平台的性能优化和高可靠性研究与实现[D].上海:上海交通大学,2007:41-45.]