zoukankan      html  css  js  c++  java
  • spring +hibernate 启动优化【转】

    最近在负责一个大项目,项目组成员包括项目经理大概10个人左右。项目技术用struts+spring+hibernate实现。项目的规
    模相对来说是比较大的,总共有10大模块,每个大模块又分为有十几个、甚至几十个小模块。开发工具用eclipse,由于在
    开发阶段,项目开发成员需要频繁重启服务器。在启动服务器的时候,每次启动时间总是会超过1分钟。记得以前在做另外
    一个项目时,启动时间不到5秒钟,相差了10倍,而且项目规模是差不多的。

    从初步分析来说,应该是hibernate解释hbm.xml时花费时间,或者可能是spring容器启动并解释所有的bean配置文件 。诊
    断了一下,发现1分钟消耗的时间主要分布在hibernate解释hbm.xml花费5秒;spring容器从启动到解释bean配置文件竟然
    花了58秒,真是太嚣张了。当时非常怀疑spring的效率问题。企图从网上搜索相关资料,看看有什么优化措施。

    首先是找到了hibernate的启动优化 http://www.hibernate.org/194.html  里面的主要思想是通过将xml序列花到本地的
    文件里,每次读取的时候根据情况,从本地文件读取并反序列化,节省了hibernate xml的解析时间。按照这个方式测试了
    一下,发现hibernate的启动时间从5秒降低到3秒,但是这个优化对于整个启动过程是杯水车薪的,毫无用处。
    下面是hibernate的优化代码:

     1 public Configuration addCachableFile(String xmlFile) throws MappingException {        
     2         try {
     3             File file = new File(xmlFile);
     4             File lazyfile = new File(xmlFile + ".bin");
     5             org.dom4j.Document doc = null; 
     6             List errors = new ArrayList();
     7             if(file.exists() && lazyfile.exists() && file.lastModified()<lazyfile.lastModified()) {
     8                 log.info("Mapping lazy file: " + lazyfile.getPath());
     9                 ObjectInputStream oip = null;
    10                 oip = new ObjectInputStream(new FileInputStream(lazyfile));
    11                 doc = (org.dom4j.Document) oip.readObject();
    12                 oip.close(); 
    13             } else {
    14                 doc = xmlHelper.createSAXReader(xmlFile, errors, entityResolver).read( file );
    15                 log.info("Writing lazy file to " + lazyfile);
    16                 ObjectOutputStream oup = new ObjectOutputStream(new FileOutputStream(lazyfile));
    17                 oup.writeObject(doc);
    18                 oup.flush();
    19                 oup.close();
    20             }
    21             
    22             if ( errors.size()!=0 ) throw new MappingException( "invalid mapping", (Throwable) errors.get(0) );
    23             add(doc);
    24             return this;
    25         }
    26         catch (Exception e) {
    27             log.error("Could not configure datastore from file: " + xmlFile, e);
    28             throw new MappingException(e);
    29         }
    30     }

    没办法,又仔细查看了spring的资料,终于发现spring的容器是提供了lazy-load的,即默认的缺省设置是bean没有lazy- load,
    该属性处于false状态,这样导致spring在启动过程导致在启动时候,会默认加载整个对象实例图,从初始化ACTION配置、
    到 service配置到dao配置、乃至到数据库连接、事务等等。这么庞大的规模,难怪spring的启动时间要花将近1分钟。尝
    试了一下,把beans的 default-lazy-init改为true就,再次启动,速度从原来的55秒,降到8秒钟!!Great!虽然是非常
    小一个改动,但是影响确实非常大。一个项目组10个人,假若每个人一天平均需要在eclipse下启动测试服务器50次。那么
    一天项目组需要重启500次,每次节省50秒的话,就是 25000秒,将近几个小时,差不多一个工作日,多么可观的数字!

     
    不过在运行期间第一次点页面的时候,由于spring做了lazy-load,现在就需要启动一部分需要的beans,所以稍微慢2-3
     秒钟,但是明显比等几十秒要快很多,值得一鉴。

     以上是针对开发阶段的spring容器启动优化,在部署到实际环境中,倒是没必要设置为lazy-load。毕竟部署到实际环境
     中不是经常的事,每次启动1分钟倒不是大问题。

    我这里要提醒的是不是说有的beans都能设置default-lazy-init成为true.对于scheduler的bean不能用lazy-init

    < beans  default-lazy-init ="true" >   
         < bean  class ="org.springframework.scheduling.quartz.SchedulerFactoryBean" > 
             < property  name ="triggers" > 
                 < list > 
                     < ref  bean ="buildHtmlTrigger" /> 
                     < ref  bean ="askTrigger" /> 
                     < ref  bean ="mailSenderTrigger" /> 
                     < ref  bean ="topicDetailBuildTrigger" /> 
                     < ref  bean ="forumBuildTrigger" /> 
                     < ref  bean ="topicBuildTrigger" /> 
                 </ list > 
             </ property > 
         </ bean > 
    </ beans > 

    这样的话。所有的scheduler就都不管用了。所以请大家要注意。下面这样才是可以执行的

    < beans >  
         < bean  class ="org.springframework.scheduling.quartz.SchedulerFactoryBean" > 
             < property  name ="triggers" > 
                 < list > 
                     < ref  bean ="buildHtmlTrigger" /> 
                     < ref  bean ="askTrigger" /> 
                     < ref  bean ="mailSenderTrigger" /> 
                     < ref  bean ="topicDetailBuildTrigger" /> 
                     < ref  bean ="forumBuildTrigger" /> 
                     < ref  bean ="topicBuildTrigger" /> 
                 </ list > 
             </ property > 
         </ bean > 
    </ beans > 

     转载自:http://www.blogjava.net/baoyaer/articles/194713.html

     

  • 相关阅读:
    2.5 整数和算法
    斑马问题
    计算机硬件操作
    幸福是什么
    英译汉技巧
    指令
    计算机性能
    硬盘容量的计算方法
    Symmetric Tree
    Same Tree
  • 原文地址:https://www.cnblogs.com/mjorcen/p/3677560.html
Copyright © 2011-2022 走看看