张永华
(中国移动通信集团公司广西分公司 南宁530022)
近年来,随着电信运营商市场的发展,为适应全业务发展和市场竞争需要,对运维管理系统能力提升提出了更高的要求,运维管理系统经过长期建设,各种应用规模越来越庞大,所承载的应用范围不断拓宽,其中电子运维系统(electric operation maintenance system,EOMS)作为业务开通和网络运维集中管理的重要支撑系统,随着用户量的不断扩大,新功能模块的更新上线,其性能开始下降,影响了用户使用感知。EOMS采用基于中间件的Web应用模式建设,这种分布式体系具有易扩展和方便维护的特点,但其多层的体系架构也给整体性能优化带来了新的问题与挑战,以往对这种Web应用性能优化研究主要集中在数据库访问的性能优化上,并没有从整个体系考虑系统的性能优化策略。针对这一问题,本文以EOMS系统的性能优化实践为背景,在保持系统良好体系结构和易于扩展、维护的基础上,从主机系统、网络、数据库、中间件、应用结构多个层面对基于中间件的Web应用提出性能优化方法,并对这些方法的实施效果作了测试比较。
参照EOMS系统用户数量在广西省与中国移动通信集团公司广西分公司(简称广西移动)同等规模的公司系统运行情况,同时结合广西省网络现状,将本次优化活动的目标设定如下:将EOMS系统日常处理访问量最大的模块——流程管理模块下的工单处理速度作为本次优化效果评估的主要指标,最终把EOMS工单处理时间缩短到7 s以内(当前性能13 s)。
EOMS是一套支撑网络运维工作集中化、流程化、电子化、自动化、智能化的系统。广西移动的EOMS由2006年开始建设,经过4年多不断的完善,目前系统主要分为流程管理、值班管理、业务开通、信息发布、代维管理、作业计划等6大模块。系统在用账号已经达到2 400个,日均在线人数600~700人,日均工单流转量达到7 000~10 000张。随着电信市场全业务的发展,EOMS将成为支撑全业务开通及保障的重要系统。
EOMS采用基于中间件的3层软件结构体系,自下而上分别是数据库、中间件、Web服务(如图1所示),这种架构应用本身不具备独立运行的能力,必须将其部署到中间件容器中,应用系统才可以正常地运行。随着EOMS用户量的增加,用户经常抱怨常用的应用模块(如工单、维护作业、信息发布等)访问速度慢、页面提交处理及查询反应时间长等问题。EOMS性能优化必须结合系统的技术特点,对影响性能的各层面因素(包括主机系统、数据库、中间件(应用服务器)、应用(服务层与应用层)自身)进行全面分析。以下分别从主机、数据库、Web中间件、应用4个层面,对可能存在的性能影响因素与影响特性进行阐述。
目前EOMS系统采用SPARC Enterprise M9000服务器。该型号服务器的性能有如下特点。
SPARC Enterprise M9000服务器是采用对称式多处理(symmetric multi-processing,SMP)体系结构开发的 Unix 服务器,兼具超级计算机的高速技术和 Unix服务器的开放性。如果在运行过程中发生了问题,可以自我修正或隔离导致异常的环节,而无需停止系统。此特性可在许多情况下最大限度地减少系统故障,从而提高作业的连续性。
每个SPARC Enterprise M9000服务器都包含一个或多个SPARC64TMⅥ/SPARC64TMⅦCPU。它们可像多个服务器一样运行,允许灵活地使用资源(包括更有效地执行作业操作),有利于虚拟化技术的应用。针对M9000服务器可分区分片利用的新特性,结合EOMS应用特性,可通过配置多个应用节点且分布式部署的方式,使系统的资源利用率达到最优。
另外,主机操作系统版本为Sun Solaris 10,其影响I/O性能的主要参数介绍如下。
(1)ulimit
ulimit是一种 Solaris系统的内键功能,具有一套参数集,用于由它生成的 shell进程及其子进程的资源使用设置限制。
假设有这样一种情况,一台 Unix主机上同时登录了10个人,在系统资源无限制的情况下,这 10个用户同时打开了 500个文档,而假设每个文档的大小有 10 MB,这时系统的内存资源就会受到巨大的挑战。
而EOMS实际应用的环境要比这种假设复杂得多,EOMS作为在线式数据库处理应用,对操作系统的文件资源操作更为频繁,例如一个典型工单流操作中,每个工单文件流转环节、步骤都对开启文件描述符的数量、分配堆栈的大小、CPU时间、虚拟内存大小等有非常严格的要求。资源的合理限制和分配,不仅仅是保证系统可用性的必要条件,也与系统上软件运行的性能有着密不可分的联系。这时,ulimit可以起到很大的作用,是一种简单并且有效的实现资源限制的方式。
ulimit用于限制 shell启动进程所占用的资源,支持对以下各种类型资源的限制:所创建的内核文件的大小、进程数据块的大小、shell进程创建文件的大小、内存锁住的大小、常驻内存集的大小、打开文件描述符的数量、最大分配堆栈的大小、CPU时间、单个用户的最大线程数、shell进程所能使用的最大虚拟内存。同时,它支持硬资源和软资源的限制。
(2)TCP_TIME_WAIT_INTERVAL
该参数用于通知TCP/IP将已关闭的连接控制块保留的时间。在应用程序完成 TCP/IP连接后,控制块将保留指定的时间。当连接比率较高时,该保留时间的设置可能导致累积大量的 TCP/IP连接,从而导致服务器性能下降。当EOMS系统在线用户并发处理统一应用模块(如维护作业模块)时,服务器在某些峰值期间会延迟,用netstat命令显示 HTTP Server打开的许多套接字处于 CLOSE_WAIT或 FIN_WAIT_2状态。明显的延迟可能会长达 4 min,其间服务器无法发送任何响应,但是 CPU利用率很高,所有活动都在系统进程中。
(3)TCP_FIN_WAIT_2_FLUSH_INTERVAL
该参数用于指定禁止处于 FIN_WAIT_2状态的连接保持该状态的计时器时间间隔。该参数与TCP_TIME_WAIT_INTERVAL配合使用,可以让EOMS的数据操作应用访问操作系统时,网络等待时间达到合理水平。
数据库常用的几种定量分析方法主要包括:响应时间和吞吐量之间的权衡、数据库的可用性和命中率、内存的使用情况。
(1)响应时间和吞吐量之间的权衡
响应时间是指应用做出反应的时间,以毫秒或秒表示,该值越低越好。吞吐量是指每个单位时间完成的工作,或是单位时间内数据库完成的 SQL语句数目,以每秒的事务量表示,该值越高越好。
(2)数据库的高可用性和命中率
高可用性:数据库系统保障能长时间运行,减少计划内(甚至是计划外)停机时间,最好能够24 h×7无障碍运行,这就是高可用性标准。
命中率:Oracle数据库通过使用LRU算法,将最近访问的数据块存放到缓存中,从而使对磁盘数据的访问效率优化到接近内存访问的速度。由于数据库应用的核心操作就是数据的访问和处理,因此如果应用系统访问的大部分数据块已在缓存中,也就是数据在缓存中命中,即数据命中率。
(3)内存分配调优
内存分配是在系统运行期间动态完成的,以EOMS的Oracle 10版本为例,数据库管理员可以根据数据库运行状况调整数据库系统全局区(SGA区)的数据缓冲区、日志缓冲区和共享池的大小;还可以调整程序全局区(PGA区)的大小。合理地分配SGA与PGA内存,可以提高缓存的性能,降低 SQL语句解析的时间,减少页面调度及换页,另外一方面,数据库索引配置不合理,会导致Oracle数据库产生大量的全表扫描,全表扫描必然造成数据内存页面的频繁调度。
本文中的EOMS系统优化,将重点从数据库的可用性和命中率、内存的使用情况两个方面进行分析。
中间件是一种独立的系统软件或服务程序,分布式应用软件借助这种软件在不同的技术之间共享资源。中间件位于客户机/服务器的操作系统之上,管理计算机资源和网络通信,是连接两个独立应用程序或独立系统的软件。相连接的系统,即使具有不同的接口,通过中间件彼此也能交换信息。
EOMS采用的是IBM WebSphere Process Server V6(WPS)中间件产品,WPS是运行于 WebSphere ApplicationServer(WAS)之上的业务流程集成服务,WAS中的各种参数的设置都会对 WPS的运行性能产生直接影响。影响WAS运行性能的主要参数如下。
(1)追踪和日志相关的参数
追踪和日志是进行问题分析最重要的手段之一,详细的追踪和日志可以帮助用户和 WAS开发、支持人员获得更多的运行信息,但同时也带来了较大的 I/O资源消耗,降低了 WAS的性能。
(2)Java虚拟机 (JVM)相关的参数
其中aBn为集合Bn中元素的策略状态,an0表示用户n退出信道竞争时的策略状态,aBn/n为用户n的相邻用户在n退出信道竞争时的策略状态.然而博弈过程中,n只对集合In中的用户产生干扰,则有:
IBM JVM默认的 Java GC规则是标记-清除-整理 ,IBM在Java 5.0之后引入新的 Java GC规则,该规则在许多情况下通过调整短生命周期对象和长生命周期对象所占用 Java堆的空间大小提高性能。初始堆大小用于指定JVM代码可使用的初始堆大小(以兆字节计)。增加最小堆大小可改进启动,减少发生垃圾回收的次数,并且可实现 10%的性能增益。通常,增加 Java堆的大小会改进吞吐量,直到堆不再驻留在物理内存中。当堆开始交换到磁盘后,Java性能将大幅下降。
(3)线程池大小相关的参数
对于每个WAS的Server,有3个线程池的参数需要调整:Default、ORB、Web Container。
Default线程池中的线程为分配给 MDB的实例使用,除非单独指定其他的线程池。这意味着Default线程池要比较大,尤其是当增大激活规范的 maxConccurency参数时。
ORB(object request broker,对象请求代理)线程池用于运行 ORB请求,如远程 EJB(enterprise Java beans)调用。如果有大量的远程 EJB被调用,比如人工任务 API被调用,需要加大 ORB线程池大小提高远程 EJB调用的并发处理能力。
Web Container线程池中的线程用于处理 HTTP和Web服务的请求,且被所有应用共用,因此需要增大线程池,以提高 HTTP和 Web服务请求的并发处理能力。
(4)数据源连接池大小相关的参数
最大连接数指可以在数据源连接池中创建的最大物理连接数,最大连接数会影响数据库操作的并发能力。
应用不是独立于它的操作环境而存在的,相反,内存资源、磁盘输入/输出和 CPU的使用直接影响它的操作环境,应用优化得越好,就越容易优化支持这个应用的环境。由于其他系统硬件或软件的原因而导致的瓶颈,如应用系统本身的设计问题、超出系统吞吐量(在一定时间内系统处理数据的能力)的限制、使用的 SQL结构和语句不合理等,必须联合应用软件开发商,从设计上分析影响性能的问题,并对其进行改进和调整。常见的问题如下。
·大量使用固定参数,SQL硬编码过多。
·SQL语句中编码不严谨,查询条件设计不合理。
·频繁和无序的逻辑数据块读写,导致物理I/O的读取次数过多。
·代码关键字不合理,以“不等于”和“等于”为例:SQL中带有很多“<>”的查询,如果字段值是有限个不重复值,要改写为多个OR连接的“=”查询,例如deleted<>1,deleted字段只出现2个值,即 0和 1,不如写为deleted=0,“<>”查询会导致字段的索引失效,应尽量避免。
(1)Solaris 文件描述符(ulimit)
文件描述符是Unix系统内核中用于表示特定进程打开的特定文件的方式,通常是一个整型的变量。如果此参数的值过低,在系统日志中显示打开过多文件错误,从而影响用户的请求。根据EOMS用户访问量和工单数据处理量的估算,对EOMS操作系统Solaris 10的相应参数调整如下。
缺省值:无;
建议值:65 535。
(2)Solaris TCP_TIME_WAIT_INTERVAL
该参数是通知TCP/IP保留已关闭连接控制块的时间。在应用程序完成 TCP/IP连接后,控制块保留指定的时间。根据EOMS数据连接方式和TCP网络访问特点,对EOMS操作系统Solaris 10的相应参数调整如下。
缺省值:缺省为 2 400 s。
建议值:60 s。
(3)Solaris TCP_FIN_WAIT_2_FLUSH_INTERVAL
该参数指定禁止处于 FIN_WAIT_2中的连接保留在此状态中的定时器间隔。根据EOMS数据连接方式和TCP网络访问特点,对EOMS操作系统Solaris 10的相应参数调整如下。
缺省值:缺省为 675 000。
建议值:67 500。
EMOS系统的分布式部署方案如图2所示。
EOMS系统,现有软件部署架构由一台ISA服务器在最前端实现移动运维内部网络与移动OA网络间的互连互通。
在ISA服务器后端,引入一个HTTP服务中间件NGINX。NGINX起到负载均衡、按端口提供映射服务的作用。其优点如下:由于系统实现分布式处理,以NGINX替换原IBM提供的负载分流软件HIS以提高负载分流时的性能;通过NGINX配置文件的修改调整,当系统某组节点出现故障时,可以快速切换,将使用用户分流到其他节点。切换时间2 s,不影响用户。
在NGINX服务器后端,通过NGINX和M9000虚拟化分区技术,对应用中间件建立了7组节点服务。采用7组节点的原因如下:原有EOMS系统WPS软件应用集群只有两个节点,两个节点共同承载整个EOMS系统的所有应用,当EOMS软件因为线程或者应用高负荷导致系统崩溃时,无备用节点提供系统服务。
当某个EOMS应用内部异常导致某个WPS节点崩溃时,通过NGINX配置快速切换,不会影响其他应用资源,以保障应用可用性和稳定性。
EOMS系统既存在人工任务(如派发工单、处理工单等),也存在自动任务(如网管告警派单接口、各类轮循任务等)。由于人工任务与自动任务的特点及要求是不同的,如果混杂在一起,将会导致系统越在忙时越忙的情况,影响系统运行。所以在新的系统环境中按照业务特点,对系统进行拆分及分布式部署,使自动任务与人工任务相隔离,各行其道,互不干扰。
数据库承载服务在原EOMS系统采用的HA技术上,引入了Oracle Data Guard同步备份机制,保证了在数据库出现异常时,可以在线切换到备用的数据库进行业务承载,达到应用24 h不间断处理服务的目的。
本次结合EOMS日常工单处理量及人工任务并发访问量,对数据库进行DBA跟踪,主要对Hit Ratio、PGA、LOG buffer、Hash join语句等参数作出以下调整:
·因Hit Ratio命中率低,将db_cache_size增加到7 086 MB,同时 SGA_MAX_SIZE相应增加,Hit Ratio调整前后指标变化如图3所示;
·因PGA的命中率极低,将pga_aggregate_target提高一倍后,数据库TEMP表空间现象明显减少,大幅增加了涉及sort和Hash join操作的语句执行效率;
·因LOG buffer相关等待事件明显,增大log_buffer大小为2 MB;
·按照顺序扫描的SQL语句创建或重建相关表的索引;
·新增索引,对无索引或条件语句涉及的字段未建有索引的表创建相应的索引,通过statspack筛选所有table access full的语句,判断全表扫描的必要性,对于走索引合理的语句创建合适的索引,通过梳理新建了35个索引,调整后全表扫描前后的对比如图4所示;
·把使用最频繁的几个索引单独放在一个dbspace里,暂时不需要对单个索引作分片处理。
索引表空间分布如图5所示。SYSTEM和XDB为系统索引表空间,indexdbs表空间是主要的用户索引表空间,包含306个用户索引,EOMS30和emosdbs是次要用户索引表空间,分别包含184个和175个用户索引。
通过对IBM WebSphere的中间件运行日志进行跟踪分析,结合IBM官网给出中间件性能问题指南手册,重点对JVM、线程、数据库连接池等方面进行分析调优。
(1)VM 检查
目前系统分配给WPS JVM的大小为1 GB,在实际JVM消耗情况跟踪中,发现系统运行过程中,其JVM的峰值已经与系统设定的阈值很接近了,在用户请求集中而可用资源较少的情况下,就会出现系统等待的情况,原因是中间件必须将内存回收后,才会分配排队等待的请求,所以JVM要进行适当的调整,把最大堆调整至1 500 MB。
(2)线程池
EOMS所有用户访问请求最终都转化成中间件用户响应线程的形式完成处理,线程池解决了用户响应线程的创建与销毁所消耗的时间,可以有效地提高对用户请求的响应,所以给线程池设置一个合适的值,满足目前系统吞吐量是一个很重要的工作。目前系统分配给中间件的线程数是150个,即线程池中有150个线程循环响应用户的请求。结合系统设置和对忙时EOMS应用日志的观察,认为需要增大线程池,以满足现有的业务需求,因此将线程数设置为200个。
(3)数据库连接池
EOMS应用并不直接管理数据库连接,而是通过中间件提供的连接池管理。在每次建立数据库物理连接时,数据库要为该连接分配多种资源,反之,释放连接时,要把这些资源及时释放掉。分配和释放资源也都是耗时的操作,因此,反复建立/释放数据库连接会对系统的效率产生不良影响。IBM WebSphere自身提供连接池技术,在连接池中维护多个活动的数据库物理连接,当系统需要进行数据库访问操作时,从池中获得一个连接,操作完毕后并不直接释放,而是把连接放回池中,以便以后使用,这样可以大大减少建立/释放连接的次数。通过对连接池物理连接数量大小的调整,可以获得最佳性能。结合系统设置和EOMS忙时的应用日志的观察,需要相应地对数据连接池参数进行调整,经过评估,250个足以满足现有业务需求,因此连接池的最大并发数设置为250个。
完成以上3个层面的调整后,发现还有30%~40%的系统性能问题未得到明显改善,需要进一步对应用代码进行分析。主要提出以下EOMS开发编码规范,以“关键模块代码走查”和“框架代码复查”为主要方式,对代码提出了调整策略。
(1)批量查询代码调整策略
一次操作中提取尽量多的数据 (N+1):通过代码循环优化,增加一次性数据读取的数量集合,减少与数据库交互的次数,以便大量数据操作在内存中完成,保证代码执行效率。
(2)将需要存取的块的数量减到最小,必要时重写代码及SQL语句
即能定义为包体的局部过程或局部变量的,就不要在包中定义;能在过程内定义的子过程或变量,就不要定义为包体中的局部过程或局部变量;子过程使用的变量,不要在父过程中定义。从而执行部分缩小,减少网络传输以及内存交互的负荷。
(3)对关键字编码进行规范
规则如下。
·变量未赋值前,保持进行Null的引用,避免因内存泄露导致系统性能下降。
·减少SQL硬编码,硬编码即每个SQL查询条件都使用固定参数形式写死,这样导致每一次参数的变动Oracle数据库都会当作一条新的SQL解析并执行,无法利用Oracle的缓存命中区,从而增加了Oracle数据库解析的开销。
·不要随意使用distinct、<>等关键字,如必须使用,注意分析其必要性。
·避免未捕获的异常抛出,每个SQL都有可能出错。需要使用异常捕获语句包裹每个SQL,并给出恰当的提示。比如某系统前段时间一直有no_data_found的错误,程序抛出的异常就是这个。很简单,这说明程序中有个select语句查询结果为空,但并没有捕获这个异常,所以直接抛出了no_data_found,这个错误是无法定位的。过多未被捕获异常会产生额外的性能开销。
通过程序代码走查修改,逐步优化程序代码,减少不规范,从每周统计的同一类工单查询的执行效率趋势图,可以看出优化效果明显,如图6所示。
(1)优化效果
对EOMS访问量最多的流程管理模块下的工单处理模块处理速度进行优化前后效果比对分析,优化前后的对比趋势如图7所示。
经过优化,工单平均处理时间下降到7 s以下,性能效果较优化前提升了50%。
(2)优化任务贡献度
根据优化顺序,针对主机系统、中间件、数据库、应用代码4个方面,每做完一项优化措施,对运维系统的性能优化效果提升贡献情况进行记录和统计,详见图8。
可以看出,对于基于Web中间件的运维系统调优,建议的调优任务的实施顺序依次为:数据库调优、应用代码调优、中间件调优、主机系统调优。
本文结合具体实践,对基于中间件的Web应用系统进行性能调优,从主机系统、中间件、数据库、应用结构4方面提出了分析和优化策略,并最终取得较好的成效。同时对各层面调优实施后对整体优化效果的贡献情况进行记录与分析,为后续同类型技术架构的运维管理系统性能问题优化提供了参考依据和优化方向性指导。
1 中国移动通信集团有限公司.中国移动电子运维系统技术规范(第 3 版),2009
2 郭海峰,阳国贵.Oracle数据库性能调优技术与实现.计算机工程,2006(19)
3 孙磊.构建高性能WebSphere企业级应用.北京:电子工业出版社,2008
4 邢文英.QC小组基础教材(修订版).北京:中国社会出版社,2005