zoukankan      html  css  js  c++  java
  • [置顶] 项目后期开发中的项目优化

    1. 概述

    本次的性能优化主要是针对windows平台开展优化。

    建议:如果系统可以替换成64位的系统,最好安装64位系统。这样可以避免jdk在32位条件下的内存使用限制。

    2. 系统运行环境

    2.1. 应用系统环境

    应用系统环境是指具体部署的应用的一些优化配置措施:

    1、 检查proxool.xml配置

    属性名

    描述

    初始值

    最终值

    house-keeping-sleep-time

    保留线程处于睡眠状态的最长时间

    90000

    90000

    simultaneous-build-throttle

    可一次建立的最大连接数

    10

    200

    prototype-count

    连接池中可用的连接数量

    5

    5

    maximum-connection-count

    最大的数据库连接数

    30

    400

    minimum-connection-count

    最小的数据库连接数

    10

    10

    2、 禁用平台提供的日志记录功能

    3. tomcat应用服务器

    1、tomcat启动参数优化,检查是否设置java_opts,参数是否起作用

    2、对tomcat容器自身参数的优化,通过调整参数达到性能优化。

    属性名

    描述

    初始值

    最终值

    maxThread

    可创建的最大的线程数,每一个线程处理一个请求

     

     

    minSpareThreads

    最小备用线程数,tomcat启动时的初始化的线程数

     

     

    maxSpareThread

    最大备用线程数,一旦创建的线程超过这个值,Tomcat就会关闭不再需要的socket线程;

     

     

    acceptCount

     指定当所有可以使用的处理请求的线程数都被使用时,可以放到处理队列中的请求数,就是被排队的请求数,超过这个数的请求将拒绝连接

     

     

    disableUploadTimeout

    上传时是否使用超时机制

     

     

    enableLookup

    禁用反查域名,为了提高处理能力,应设置为false

     

     

    connnectionTimeout 

    网络连接超时,单位:毫秒。设置为0表示永不超时,这样设置有隐患的。通常可设置为30000毫秒

     

     

    keepAliveTimeout 

    长连接最大保持时间(毫秒)。此处为15秒

     

     

    maxKeepAliveRequests

    最大长连接个数(1表示禁用,-1表示不限制个数,默认100个。一般设置在100~200之间)

     

     

    参考配置如下:

    4. 前台代码优化

    该步骤未优化到温州项目上,可以作为备选方案。

    4.1. 压缩请求响应数据,节约网络带宽

    前面介绍的压缩是去除脚本的注释和换行,这只是初步的压缩。而现在的主流浏览器都支持GZIP压缩,通过设置GZIP压缩,可以减小HTTP响应页面数据的大小可以节省HTTP响应时间。从HTTP/1.1开始,大部分浏览器都默认支持HTTP请求中有Accept-Encoding文件头的压缩格式,如:Accept-Encoding: GZIP, DEFAULT。如果服务器在请求的文件头中检测到上面的Accept-Encoding: GZIP,,就会以客户端列出的方式压缩响应传输的内容。然后Web服务器把压缩方式通过响应文件头中的Content-Encoding来返回给浏览器。GZIP大概可以减少70%的响应数据大小。GZIP可以对多种格式的数据进行压缩。

    GZIP压缩的实现方式有多种,有些服务器支持GZIP压缩,可以通过简单的配置实现数据的压缩,也可以通过自己写一个过滤器,在web.xml注册,拦截响应的请求。

    Ø 在tomcat服务器的server.xml文件中配置GZIP压缩

      <Connector port="8080" protocol="HTTP/1.1" 

       connectionTimeout="20000" 

       redirectPort="8443" URIEncoding="UTF-8"

       compression="on"    

       compressionMinSize="2048"   

       noCompressionUserAgents="gozilla,traviata"      compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain,application/json" />

    Ø 下面简要介绍拦截器实现GZIP压缩,主要代码如下:

          /**

           * 判断浏览器是否支持GZIP

           * @param request

           * @return

           */

          private static boolean isGZipEncoding(HttpServletRequest request){

            boolean flag=false;

            String encoding=request.getHeader("Accept-Encoding");

            if(encoding!=null&&encoding.indexOf("gzip")!=-1){

              flag=true;

            }

            return flag;

          }

        /**

         * Gzip压缩过滤的实现方法

         */

        public void doFilter(ServletRequest request, ServletResponse response,

                FilterChain chain) throws IOException, ServletException {

            HttpServletResponse resp = (HttpServletResponse) response;

            HttpServletRequest req=(HttpServletRequest)request;

            //如果请求的浏览器支持压缩算法,则对response的数据进行压缩,否则不压缩

            if(isGZipEncoding(req)){

                Wrapper wrapper = new Wrapper(resp);

                chain.doFilter(request, wrapper);

    //压缩响应的数据

                byte[] gzipData = gzip(wrapper.getResponseData());

                resp.addHeader("Content-Encoding""gzip");

                resp.setContentLength(gzipData.length);

                ServletOutputStream output = response.getOutputStream();

                output.write(gzipData);

                output.flush();

            } else {

                chain.doFilter(request, response);

            }        

        }

    Web.xml配置如下:

    <filter>  

      <filter-name>ecsideExport</filter-name>  

      <filter-class>com.linewell.ucap.filter.GZipFilter</filter-class>  

        </filter>  

        <filter-mapping>  

            <filter-name>ecsideExport</filter-name>  

            <url-pattern>*.jsp</url-pattern>  

        </filter-mapping> 

        <filter-mapping>  

            <filter-name>ecsideExport</filter-name>  

            <url-pattern>*.js</url-pattern>  

        </filter-mapping>

        <filter-mapping>  

            <filter-name>ecsideExport</filter-name>  

            <url-pattern>*.css</url-pattern>  

        </filter-mapping>

    压缩的效果如下图:

    5. java代码优化

    5.1. 原理

    1) 使用PreparedStatement代替Statement

    Ø 推荐的写法:

    Ø 不推荐的写法:

    Ø 原因分析:

    第一种方法使用的是预编译语句,每一种数据库都会尽最大努力对预编译语句提供最大的性能优化。因为预编译语句有可能被重复调用,所以数据库本身会对使用频繁的预编译语句进行缓存,下次调用时只要传入参数,预编译语句就能执行,而不需重新编译。而第二种方法,每次都需要对sql语句重新编译,然后才能执行。相比之下,显然第一种方法的效率更高。

    ps:使用PreparedStatement还可以防止sql注入,提高应用程序的安全性。不过这不属于本次性能专题讨论的范畴,大家如果有兴趣可以自己深入学习。

    5.2. 优化内容

    1、 改造平台登录代码,把涉及的数据库查询操作修改为 PreparedStatement绑定变量的方式。

    2、 修改首页加载涉及的查询代码。

    3、 修改办件、事项、字典的常用查询语句。

    6. 数据库优化

    6.1. 概述

    本次数据库优化主要从oracle参数、建立表索引、优化sql这个3个方面入手,优化主要流程如下:

    1、 对应用进行压力测试

    2、 查看压力测试后的oracle性能报告。

    3、 根据性能报告调整优化基本参数,主要是sga,pga,process,session。

    4、 梳理出需要优化的功能列表,然后找出涉及的sql语句,对语句进行优化。

    5、 然后查找sql语句执行效率、占用cpu最差的语句、执行、读取磁盘和读取缓冲区的次数,进行优化。

    6、 检查系统基础功能(用户、部门、权限、字典等)的表是否有建立主键和索引。

    6.2. oracle基础

    6.2.1. 查询当前用户连接数据库游标使用情况

    select * from v$open_cursor t where t.USER_NAME in ('WZ_WAS','WZ_UCAP') -- and t.SQL_TEXT like 'SELECT * FROM UCAP_USER%'

    select * from v$sql_shared_cursor t where t.SQL_ID='3nf9j2t694dv0'
    select * from v$sql t where t.SQL_TEXT like 'SELECT * FROM UCAP_USER%'

     

    select sql_id,child_number,sql_text,parse_calls,plan_hash_value,loads from v$sql t where t.SQL_TEXT like 'SELECT * FROM UCAP_USER%'

     

    6.2.2. 检查占用CPU时间比较长的sql语句

    select sql_text,cpu_time from v$sql where cpu_time >1e7 order by cpu_time

    6.2.3. 查看sql语句执行、读取磁盘和读取缓冲区的次数

    Select  SQL_TEXT,EXECUTIONS,DISK_READS,COMMAND_TYPE,OPTIMIZER_MODE, SHARABLE_MEM,BUFFER_GETS  from v$sqlarea ;

    EXECUTIONS:执行次数 

    DISK_READS:读盘次数 

    COMMAND_TYPE:命令类型(3:select,2:insert;6:update;7delete;47:pl/sql程序单元) 

    OPTIMIZER_MODE:优化方式 

    SQL_TEXTSql语句 

    SHARABLE_MEM:占用shared pool的内存多少 

    BUFFER_GETS:读取缓冲区的次数

    http://klygit.iteye.com/blog/564098

    6.2.4. 查看process,session的使用情况

    SELECT   resource_name,
             current_utilization,
             max_utilization,
             LIMIT,
             ROUND (max_utilization / LIMIT * 100) || '%' rate
      FROM   (SELECT   resource_name,
                       current_utilization,
                       max_utilization,
                       TO_NUMBER (initial_allocation) LIMIT
                FROM   v$resource_limit
               WHERE   resource_name IN ('processes', 'sessions')
                       AND max_utilization > 0);

    6.2.5. 执行效率最差的10sql语句

    SELECT * FROM ( SELECT PARSING_USER_ID EXECUTIONS,SORTS, 

     COMMAND_TYPE, DISK_READS, sql_text FROM v$sqlarea 

     ORDER BY disk_reads DESC) WHERE ROWNUM<10 ;

    6.2.6. 重建表空间的索引

    create or replace procedure p_rebuild_all_index(tablespace_name in varchar2) as
      sqlt varchar(200);
    begin
      for idx in (select index_name, tablespace_name, status
                    from user_indexes
                   where tablespace_name = tablespace_name
                     and status = 'VALID'
                     and temporary = 'N') loop
        begin
          sqlt := 'alter index ' || idx.index_name || ' rebuild ';
          dbms_output.put_line(idx.index_name);
          dbms_output.put_line(sqlt);
          EXECUTE IMMEDIATE sqlt;
        EXCEPTION
          WHEN OTHERS THEN
            dbms_output.put_line(SQLERRM);
        end;
      end loop;
    end;

    declare

    tablespace_name varchar2(100);
    begin
    tablespace_name := 'was'; p_rebuild_all_index(tablespace_name);
    end;

    6.3. 优化内容

    6.3.1. 创建索引

    create index INDEX_ADVANCEINFO_RECEIVEDEPT on APAS_ADVANCEINFO (RECEIVE_DEPTUNID); 

    create index INDEX_APAS_INFO_DEPTID on APAS_INFO (DEPTID);

    create index INDEX_APAS_INFO_SERVICEID on APAS_INFO (SERVICEID);

     

    create index INDEX_ADVANCEINFO_DEPTNAME on APAS_ADVANCEINFO (RECEIVE_DEPTNAME);

     

    create index INDEX_APAS_INFO_RECEIVE_DEPTID on APAS_INFO (RECEIVE_DEPTID);

    create index INDEX_ADVANCEINFO_CREATEUSERID on APAS_ADVANCEINFO (CREATEUSERID);

    create index IDX_NODE_TRANS0 on UCAP_FW_FLOW_INSTANCE (INSTANCE_NODE_TRANSACTOR_0);

     

     

    6.3.2. 修改视图配置

    主要是在增加索引的列上,去除like的查询,如

    AND RECEIVE_DEPTID like '%${RECEIVE_DEPTID}%'修改为

    AND RECEIVE_DEPTID = '${RECEIVE_DEPTID}'  或者

    AND RECEIVE_DEPTID like '${RECEIVE_DEPTID}%'

    这样才能使用索引

    所以如果发现其他视图中,有存在索引列上有like语句,请参看如上修改

     

    对涉及的常用功能模块,检查视图配置。

    6.3.3. 修改oracle参数

    6.3.3.1. 调整 process,sessions参数

    通过如下语句可以查看当前设置值和系统曾经达到的最高指。

    SELECT   resource_name,
             current_utilization,
             max_utilization,
             LIMIT,
             ROUND (max_utilization / LIMIT * 100) || '%' rate
      FROM   (SELECT   resource_name,
                       current_utilization,
                       max_utilization,
                       TO_NUMBER (initial_allocation) LIMIT
                FROM   v$resource_limit
               WHERE   resource_name IN ('processes', 'sessions')
                       AND max_utilization > 0);

    Oraclesessionsprocesses的关系是

    sessions=1.1*processes + 5

     

    步骤

    alter system set processes=1000 scope = spfile;

     

    alter system set sessions=1105;

     

    重启数据库。

    6.3.3.2. 调整oraclesga,pga大小

    6.3.3.3. Sql优化

    通过查找sql执行效率最差、读取磁盘最多,占用cpu最长的sql进行优化;主要优化的放心是查找该语句是否使用索引。

  • 相关阅读:
    初认识AngularJS
    (imcomplete) UVa 10127 Ones
    UVa 10061 How many zero's and how many digits?
    UVa 11728 Alternate Task
    UVa 11490 Just Another Problem
    UVa 10673 Play with Floor and Ceil
    JSON对象和字符串的收发(JS客户端用typeof()进行判断非常重要)
    HTML.ActionLink 和 Url.Action 的区别
    EASYUI TREE得到当前节点数据的GETDATA方法
    jqueery easyui tree把已选中的节点数据拼成json或者数组(非常重要)
  • 原文地址:https://www.cnblogs.com/riasky/p/3459082.html
Copyright © 2011-2022 走看看