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. 总体流程图
  2. 前两项检查Web服务是否可用,就不具体展示了,可以参考下面的链接,我也是参考他的博客做的https://blog.csdn.net/a275838263/article/details/51302541
  3. lawCount初始化,执行sql是先清空内容表(我是全量更新),查询主表确定需要循环的次数,把lawCount复制到结果集
  4. 设定循环变量,lawCount来自前面的结果集,startIndex(从0开始),endIndex(从100开始)确定需要遍历的主键范围
    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,就进入循环,调用服务
  6. lawID初始化,根据startIndex,endIndex查询循环需要依赖的主键,复制到结果集
  7. 调用子job,在子job中循环访问webservice,得到数据
  8. 把上一步查到的记录存到变量中,设定小范围循环变量index,lawSize,以及参数lawID到变量
    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)就进入循环
  10. 具体的抽取ktr由于业务需求,附表字段包括主表部分字段,因此我走了两条查询,最后把记录关联插入;
    1. 生成记录:是为了初始化一个常量参数
    2. java代码中获取lawID,并配合生成的记录加密后,形成服务访问的验证字符串
    3. 具体的访问步骤
    4. 将out用json解析
    5. 去除out字段
    6. 关联两个结果集记录
    7. 插入表格
  11. 递增index,再次进入检验index
    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<lawSize){
        parent_job.setVariable("lawID",lawList[index]);
    }
    parent_job.setVariable("index",index);
    
    true;
    
  12. 递增lawID范围,一次小循环后,重置startIndex,endIndex的值
    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<lawCount){
        parent_job.setVariable("startIndex",endIndex);
    	parent_job.setVariable("endIndex",endIndex+100);
    }
    
    true;
    
  13. 重新检验startIndex的值,直到不通过,跳出循环,完成抽取

总结:

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

猜你喜欢

转载自blog.csdn.net/qq_26625383/article/details/84030236
今日推荐