kettle调用webservice服务Java:java.lang.OutOfMemoryError: GC overhead limit exceeded

说明:

  1. 背景说明:需要定时同步别的业务系统基于webservice发布的数据(主表、附表)
  2. 问题缘由:service提供方,主表支持批量查询,一次可以查询100条,但是附表只能根据主表的主键一条一条的查询。因此我如果要获取所有的附表内容就要循环访问服务(约1万多次)因此会出现Java:java.lang.OutOfMemoryError: GC overhead limit exceeded

解决方法:

总体思路:出现内存溢出主要是因为我在一个总job中循环了1万多次webservice,在大job中循环调用小job(100次访问)解决问题。

  1. 总体流程图kettle调用webservice服务Java:java.lang.OutOfMemoryError: GC overhead limit exceeded_第1张图片
  2. 前两项检查Web服务是否可用,就不具体展示了,可以参考下面的链接,我也是参考他的博客做的https://blog.csdn.net/a275838263/article/details/51302541
  3. lawCount初始化,执行sql是先清空内容表(我是全量更新),查询主表确定需要循环的次数,把lawCount复制到结果集kettle调用webservice服务Java:java.lang.OutOfMemoryError: GC overhead limit exceeded_第2张图片
  4. 设定循环变量,lawCount来自前面的结果集,startIndex(从0开始),endIndex(从100开始)确定需要遍历的主键范围kettle调用webservice服务Java:java.lang.OutOfMemoryError: GC overhead limit exceeded_第3张图片
    var lawCount=previous_result.getRows();//获取上一个传递的结果
    if (lawCount == null && (lawCount.size()) == 0)
    {
        false;
    }else{
        parent_job.setVariable("lawCount", lawCount.get(0).getNumber("lawCount",0));
    	parent_job.setVariable("startIndex", 0);
        parent_job.setVariable("endIndex", 100);
        true;
    }
    

     

  5. 检验startIndex的值,只要startIndex的值<=lawCount,就进入循环,调用服务kettle调用webservice服务Java:java.lang.OutOfMemoryError: GC overhead limit exceeded_第4张图片
  6. lawID初始化,根据startIndex,endIndex查询循环需要依赖的主键,复制到结果集kettle调用webservice服务Java:java.lang.OutOfMemoryError: GC overhead limit exceeded_第5张图片kettle调用webservice服务Java:java.lang.OutOfMemoryError: GC overhead limit exceeded_第6张图片
  7. 调用子job,在子job中循环访问webservice,得到数据kettle调用webservice服务Java:java.lang.OutOfMemoryError: GC overhead limit exceeded_第7张图片
  8. 把上一步查到的记录存到变量中,设定小范围循环变量index,lawSize,以及参数lawID到变量kettle调用webservice服务Java:java.lang.OutOfMemoryError: GC overhead limit exceeded_第8张图片
    var lawList=previous_result.getRows();//获取上一个传递的结果
    debugger;
    if (lawList == null &&(lawList.size()==0))
    {
        false;
    
    }else{
        parent_job.setVariable("lawList", lawList);//ArrayList存储法律法规记录变量,以数组形式保存入law1,law2
    
        parent_job.setVariable("lawSize", lawList.size());//存储法律法规的总数量
        parent_job.setVariable("index", 0);//循环控制变量
        parent_job.setVariable("lawID",lawList.get(0).getString("LAWID","LAWID"));
        true;
    }
    

     

  9. 检验小循环(100个循环)index的值(从0开始),index小于lawSize(100个lawID)就进入循环kettle调用webservice服务Java:java.lang.OutOfMemoryError: GC overhead limit exceeded_第9张图片
  10. 具体的抽取ktrkettle调用webservice服务Java:java.lang.OutOfMemoryError: GC overhead limit exceeded_第10张图片由于业务需求,附表字段包括主表部分字段,因此我走了两条查询,最后把记录关联插入;
    1. 生成记录:是为了初始化一个常量参数
    2. java代码中获取lawID,并配合生成的记录加密后,形成服务访问的验证字符串
    3. 具体的访问步骤kettle调用webservice服务Java:java.lang.OutOfMemoryError: GC overhead limit exceeded_第11张图片kettle调用webservice服务Java:java.lang.OutOfMemoryError: GC overhead limit exceeded_第12张图片kettle调用webservice服务Java:java.lang.OutOfMemoryError: GC overhead limit exceeded_第13张图片
    4. 将out用json解析kettle调用webservice服务Java:java.lang.OutOfMemoryError: GC overhead limit exceeded_第14张图片
    5. 去除out字段
    6. 关联两个结果集记录kettle调用webservice服务Java:java.lang.OutOfMemoryError: GC overhead limit exceeded_第15张图片
    7. 插入表格
  11. 递增index,再次进入检验indexkettle调用webservice服务Java:java.lang.OutOfMemoryError: GC overhead limit exceeded_第16张图片
    var lawList = parent_job.getVariable("lawList").replace("[","").replace("]","").split(",");
    var lawSize = new Number(parent_job.getVariable("lawSize"));
    var index   = new Number(parent_job.getVariable("index"))+1;
    
    if(index

     

  12. 递增lawID范围,一次小循环后,重置startIndex,endIndex的值kettle调用webservice服务Java:java.lang.OutOfMemoryError: GC overhead limit exceeded_第17张图片
    var lawCount 	 = new Number(parent_job.getVariable("lawCount"));
    var startIndex   = new Number(parent_job.getVariable("startIndex"));
    var endIndex   = new Number(parent_job.getVariable("endIndex"));
    
    if(endIndex

     

  13. 重新检验startIndex的值,直到不通过,跳出循环,完成抽取

总结:

  1. 提供方改不动,没办法只能循环调用
  2. 只是自己琢磨的kettle处理方式,我相信一定有更好的处理方式
  3. job应该是相对独立的模块,结束后就会释放内存??所以不会出现溢出??希望大神解答

 

 

 

 

你可能感兴趣的:(ETL)