**系统性能优化方案

时间:2021-04-24 06:03:12

一、操作系统调优

Linux 调整参数

Linux 操作系统而言,为了获得最佳性能,推荐使用下列设置。

4-4 建议的 Linux

参数

建议值

/sbin/ifconfig lo mtu

1500

kernel.msgmni

1024

kernel.sem

1000 32000 32 512

fs.file-max

65535

kernel.shmmax

2147483648

net.ipv4.tcp_max_syn_backlog

8192

有关 Linux 调整的更多信息,需参考 Linux 供应商提供的文档。

对于操作系统的调优是需要考虑的一个方面,需要相关的人进行调整设置并测试,我这里没有做相关的预研。

一、WEBLOGIC调优

1. 调整Java虚拟机

(1) 选择合适的JVM

 

(2) 配置JVM垃圾回收堆

以下部分提供了调整 VM 堆大小的一般准则:

²     堆大小应设置为一个适当的值,从而使 VM 使用的最大内存量不超过可用物理 RAM 量。如果超过该值,则 OS 会开始分页,性能也会显著降低。VM 使用的内存始终多于堆大小。除了堆大小设置,还要分配内部 VM 功能、VM 之外的本地库和永久代内存(仅适用于 Sun VM:存储类和方法所需的内存)所需的内存。

²     使用分代式垃圾收集方案时,温床大小不应超过 Java 堆总大小的一半。通常情况下,堆大小的 25% 40% 就已足够。

²     在生产环境中,将最小堆大小和最大堆大小设置为同一值,可以避免浪费用于时常调整堆大小所需的 VM 资源。这也适用于新一代堆大小 (Sun) 或温床大小 (BEA Jrockit)

5-3 Java 堆大小选项 

任务

选项

注释

设置新一代堆大小

-XX:NewSize

-XX:NewSize 的大小设置为堆大小的四分之一,这是一条通用规则。如果存在大量短期对象,则增大此选项的值。

在增加处理器的同时,一定要增加新一代堆大小。内存分配可以并行进行,但垃圾收集不可并行进行。

设置最大新一代堆大小

-XX:MaxNewSize

设置新一代堆大小的上限。

设置新堆大小比率

-XX:SurvivorRatio

新一代区域分为三个子区:Eden 和两个大小相等的生存空间。

配置 Eden/生存空间大小的比率。尝试将此值设置为 8,然后监视垃圾收集情况。

设置最小堆大小

-Xms

将最小堆大小 (-Xms) 与最大堆大小 (-Xmx) 设置为相同的值,以便将垃圾收集的消耗降至最低,这是一条通用规则。

设置最大堆大小

-Xmx

设置堆大小的上限。

设置大堆和私有共享内存

-XX:+UseISM -XX:+AggressiveHeap

请参阅 http://java.sun.com/docs/hotspot/ism.html

 

例如,从 java 命令行启动 WebLogic Server 实例时,可使用以下命令指定 HotSpot VM 堆大小值:

$ java -XX:NewSize= 128m -XX:MaxNewSize= 128m -XX:SurvivorRatio=8 -Xms 512m -Xmx 512m

建议省厅财政综合业务系统的设置:

$ java -XX:NewSize= 256m -XX:MaxNewSize= 256m -XX:SurvivorRatio=8 –Xms 1024 m –Xmx 1024 m

注:

²       需要区别的是对于JVM版本的不一样,其设置也不一。请参考以上的各参数说明来设置。

²       堆的大小一定要根据服务器硬件及实际用户访问量、系统资源利用情况、垃圾回收频率等因素综合考虑。

2. 配置产品模式

对于weblogic 有两种模式,分别为产品模式和开发模式,其主要区别在于发布部署方式和对线程数、连接池数的默认设置不一样。具体说明如下:

功能

开发模式

产品模式

部署

替换文件会自动更新

替换文件后不会自动更新

Execute Queues

默认的执行线程为15

默认的执行线程为25

JDBC Connection Pool Capacity

默认的容量为15

默认的容量为25

对于Execute QueuesJDBC Connection Pool Capacity如何设置一个合理的数值,需要根据实际环境测试进行调整。需要注意的是,这两个参数不是越大越好。

3. 调整性能相关的配置参数

(1)  pageCheckSeconds

weblogic中的默认设置是1, 表示WebLogic每一秒钟都针对每个JSP页面进行检查,看是否有新的版本。这在开发时是一个很好的设置,但是在生产中,如果系统有大量的JSP页面,这将会造成巨大的开销。

对于财政综合业务系统,需要把这个参数设置成“-1”。

weblogic.xml 配置如下:

<jsp-descriptor>

<jsp-param>

      <param-name>pageCheckSeconds</param-name>

      <param-value>-1</param-value>

</jsp-param>

</jsp-descriptor>

(2)  servlet-reload-check-secs

weblogic中的默认设置是1, 表示WebLogic每一秒钟都针对每个Servlet进行检查,看是否有新的版本。这在开发时是一个很好的设置,但是在生产中,如果系统有大量的servlet,这将会造成巨大的开销。

对于财政综合业务系统,需要把这个参数设置成“-1”。

weblogic.xml 配置如下:

<container-descriptor>

    <servlet-reload-check-secs>-1</servlet-reload-check-secs>

</container-descriptor>

二、WEB

1. 修改JSP<jsp:include> <%@include>

在我们的JSP框架里面,一个JSP需要通过<jsp:include><%@include>包含9个公用页面。其中有7个是<jsp:include>方式的,<jsp:include>这种方式对性能影响较大,然而<%@include>方式又只适合于包含静态页面。因此,在财政综合业务系统当中需要尽量的把没有用的的包含语句删除,提供JSP加载的性能。

需要删除的<jsp:include>有:

<jsp:include page="/WEB-INF/jsp/common/beforeHtml.jsp"></jsp:include>

<jsp:include page="/WEB-INF/jsp/common/bodyStart.jsp"></jsp:include>

<jsp:include page="/WEB-INF/jsp/common/bodyEnd.jsp"></jsp:include>

<jsp:include page="/WEB-INF/jsp/common/afterHtml.jsp"></jsp:include>

 

2. 去除innerHead.jspsession刷新

innerHead.jsp里写了相关刷新session 代码

<script language="javascript">

<!--

       //this method refresh session for expire

              function _refreshSessionForLongTime(){

            var activeXObject = new ActiveXObject("Microsoft.XMLHTTP");

                  activeXObject.open("POST","<%=response.encodeURL("common/refreshSessionAction.do")%>",true);

                  activeXObject.send();

              }

 

 window.setInterval("_refreshSessionForLongTime()",25*60*1000);//25 minute

 //-->

</script>

代码的功能是:每隔25分钟提交一个请求来刷新session 。然而问题是,财政综合业务系统的的页面结构由丰富的框架组成,操作一个功能就同时访问多个页面,并且所有的页面都包含了innerHead.jsp,也就是说,每个页面都会发出刷新session 的请求。这样就增加了对服务端的请求,同时降低性能。

    修改的方法是:独立出一个refreshSession.jsp页面,在top框架的perspective_toolbar.jsp里包含,这样就实现了一个web窗口隔25分钟刷新一次session,防止过多的请求导致性能降低。

3. 去除innerHead.jspgetOtherPropertyValueByUniquePropertyValue方法

innerHead.jsp有个getOtherPropertyValueByUniquePropertyValue方法,功能是根据某已知属性值获取同VO对象的其他属性值。 innerHead.jsp作为一个公共页面被所有的页面调用,并且该功能并没有在任何模块里用到,所以该功能的实现代码是冗余的,反而增加了页面解析后的文件大小,降低了性能。

4. 去除页面对selectBaseData.jsp的包含

selectBaseData.jsp 里封装了很多关于选择基础数据的目录树script接口。问题是每个相关页面都包含这个JSP,其所有的代码都作为包含JSP的一部分,然而它又非常的大,这就导致包含JSP增加了许多的冗余代码。应该改成selectBaseData.js ,每个页面调用这个JS文件为最佳。

5. 禁用Session

对于Session,应用服务器都将对其进行序列化,从而增加了系统的额外负担。如果你没有明确指定的话,每个JSP页面都会缺省地创建一个HttpSession。如果JSP页面不需要使用Session的话就用以下标识符来禁用它。

<%@ page session="false"%>

 

三、业务逻辑及数据操作层

1. 缓存数据权限相关的数据

       数据权限的数据包括两类,一类是用户对应基础数据权限构造的目录树数据,一类是用户对应的基础数据权限数据。前者数据在生成的时候做了缓存处理,缓存期为半小时,当用户重新登入系统,缓存数据过期。后者数据没有对其进行缓存处理,因而在报表查询界面需要调用该接口,取出用户对应的基础数据权限,如果有九大基础数据,就要调用九次数据库查询,大大地增加了系统对访问数据库所带来的负担,因此现在对该接口进行缓存,缓存方案和前者一样。

2. 审批流接口优化

审批流接口是最大的性能瓶颈之一。其存在以下方面的问题。

(1)     执行一次相关审批流的查询要访问4次数据库,分别是生成查询的SQL、查询分页情况、查询审批流对应的业务单据号,根据业务单据号查询业务对象。

(2)     审批流查询要关联已启用的数据权限,而且数据权限表所拥有的数据量有100多万条。如果启用了9个数据权限,也就同时要遍历执行9次对数据权限的子查询,其带来的性能瓶颈可想而知。

(3)     为了要分页,所以必须要对审批流查询SQL执行两次,一次获取分页信息,一次返回查询结果。本来执行较慢的SQL还要执行两次,就更加增大了系统的负担。

(4)     得到相关的业务单据号以后,需要把业务单据组装成IN(  )方式的子查询,如果一页查询数据量大,那查询速度明显降低。

目前已经优化的几点:

(1)  优化存储过程f_base_wk_get_task_sql的取单据项的部分。

(2)  优化存储过程f_base_wk_get_task_sql生成的查询SQL语句的查询条件。

原来的查询条件:

WHERE 1 = 1

   and (A.ENTER_ID = I.ENTER_ID)

   and 1 = 1

   and A.ACCVOUCH_ID in

       (select CHKPRO_CON_VOUID

          from T_BASE_CHECKPROCESS_CONTROL

         where instr(',3001,3011,3009,', ',' || CHKPOS_DEF_ID || ',') > 0

           and CHKPRO_CON_VOUTYPE = '3002')

   and a.ACCVOUCH_ID = z.CHKPRO_CON_VOUID

   and z.CHKPRO_CON_VOUTYPE = '3002'

优化后的查询条件:

WHERE (A.ENTER_ID = I.ENTER_ID)
   and
1 = 1

   and A.ACCVOUCH_ID = z.chkpro_con_vouid
   and CHKPRO_CON_VOUTYPE =
'3002'
   and instr(
',3001,3011,3009,', ',' || CHKPOS_DEF_ID || ',') > 0
 ORDER BY A.ACCVOUCH_ID

通过优化,比较其查询时间,大概减少了100毫秒。

对应审批流接口存在的问题还需要进一步的进行优化完善。审批流接口的性能关系到整个财政系统的性能,是其主要的性能瓶颈。所以在后期主要性能优化的工作重点就是优化审批流接口,解决其主要存在的影响性能的问题。

3. 代码质量相关

(1)     不要用”+”String对象进行连接,一定要用StringBuffer

(2)     当某对象使用之后,要手工的设置为NULL

(3)     不要用System.out.println() 输出调试信息,要用Log4j相关接口。

(4)     尽量不要用in( )的方式查询数据库。

(5)     同时对多条数据对象进行操作,要用批量处理的接口(包括批量添加、修改、删除等)。

(6)      能查询一次得到结果的就查询一次,不要在循环体内调有查询语句。尽量地较少数据库的访问次数。

对应代码质量方面的性能瓶颈,需要专门排查并修改完善。

五、系统部署

1. 启用报表分机部署

       目前的报表跟业务系统之间是部署在同一个应用服务器中的,往往因为报表的查询占用了应用服务器相当多的内存及CPU资源,导致业务系统与报表查询系统互相制约。经过对Weblogic性能监控发现,查询报表的同时,其占用的内存资源马上到了最大值,其占用的CPU资源也同样上升到峰值。

优化的方案是:把报表查询系统和业务系统在部署上分离出来,防止因为报表的性能造成业务系统运行的性能。

2. 启用预编译功能

       因为系统经常性的发布补丁,发布补丁之后必须要清除WeblogicJSP编译之后的缓存,访问某JSP之前要对该JSP编译,所以第一次访问的速度不容乐观。目前的解决方法是手工访问所有页面,这必然存在很多的问题:

(1)     由于个人疏忽或是偷懒现象造成不可能每个页面都能访问到。

(2)     访问页面的同时,有可能用户也在访问,这样对用户来说还是第一次访问。

(3)     在集群环境下需要对每一个节点进行手工访问才可。访问的次数随着节点数成倍增加,浪费了大量的人力。

优化的方案是:使用编译工具来实现预编译,编译的方法可参考weblogic相关文档

六、方案补充说明

       性能问题牵涉面非常的广,很多情况下并不出在环境上,跟本身的程序代码的实现方式,算法密切相关。如何编写质量高的代码,如何让算法最优,如何尽量地减少访问数据库的次数,如何优化访问数据库的SQl等,这些才是关键。它们是导致性能问题的主要瓶颈,只有保证了这些因素的最优化,然后再调整weblogic应用服务、操作系统、数据库等性能才能起到很好的效果。

对于财政综合业务系统的性能优化需要做好如下相关工作:

(1)     排查出存在性能瓶颈的代码并优化完善。

(2)     优化完善审批流及数据权限接口。

(3)     优化查询的SQL

(4)     启用报表分机部署。(需要相关的测试工作)

(5)     启用系统预编译。(需要技术实现预研)

(6)     对于Weblogic执行线程数、连接池数,JVM参数,操作系统参数等的调整需要根据系统实际运行环境来。

对于以上几点的优化工作,需要领导协调好各项目组的资源,统一规划,制定好相关的工作计划。