kettle呼叫webservice服務Java:java.lang.OutOfMemoryError: GC overhead limit exceeded
阿新 • • 發佈:2018-12-15
說明:
- 背景說明:需要定時同步別的業務系統基於webservice釋出的資料(主表、附表)
- 問題緣由:service提供方,主表支援批量查詢,一次可以查詢100條,但是附表只能根據主表的主鍵一條一條的查詢。因此我如果要獲取所有的附表內容就要迴圈訪問服務(約1萬多次)因此會出現Java:java.lang.OutOfMemoryError: GC overhead limit exceeded
解決方法:
總體思路:出現記憶體溢位主要是因為我在一個總job中迴圈了1萬多次webservice,在大job中迴圈呼叫小job(100次訪問)解決問題。
- 總體流程圖
- 前兩項檢查Web服務是否可用,就不具體展示了,可以參考下面的連結,我也是參考他的部落格做的
- lawCount初始化,執行sql是先清空內容表(我是全量更新),查詢主表確定需要迴圈的次數,把lawCount複製到結果集
- 設定迴圈變數,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; }
- 檢驗startIndex的值,只要startIndex的值<=lawCount,就進入迴圈,呼叫服務
- lawID初始化,根據startIndex,endIndex查詢迴圈需要依賴的主鍵,複製到結果集
- 呼叫子job,在子job中迴圈訪問webservice,得到資料
- 把上一步查到的記錄存到變數中,設定小範圍迴圈變數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; }
- 檢驗小迴圈(100個迴圈)index的值(從0開始),index小於lawSize(100個lawID)就進入迴圈
- 具體的抽取ktr由於業務需求,附表欄位包括主表部分欄位,因此我走了兩條查詢,最後把記錄關聯插入;
- 生成記錄:是為了初始化一個常量引數
- java程式碼中獲取lawID,並配合生成的記錄加密後,形成服務訪問的驗證字串
- 具體的訪問步驟
- 將out用json解析
- 去除out欄位
- 關聯兩個結果集記錄
- 插入表格
- 遞增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;
- 遞增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;
- 重新檢驗startIndex的值,直到不通過,跳出迴圈,完成抽取
總結:
- 提供方改不動,沒辦法只能迴圈呼叫
- 只是自己琢磨的kettle處理方式,我相信一定有更好的處理方式
- job應該是相對獨立的模組,結束後就會釋放記憶體??所以不會出現溢位??希望大神解答