1. 程式人生 > >關於kittle啟動中異常關閉的解決方案——批處理方式解決

關於kittle啟動中異常關閉的解決方案——批處理方式解決

問題場景:
在伺服器端用於資料抽取的kittle工具有時候可能出現各種問題,dos視窗異常關閉而導致資料抽取工作的異常,所以分析針對該問題研究了一點解決方案。

原因分析:
經過百度,很多都是kittle記憶體的問題,但是我們領導要的是記憶體是正常值,然後考慮它本身自啟動問題。

解決方案:
附上記憶體解決方案技術貼:http://blog.csdn.net/huangyanlong/article/details/42453831
從應用自啟動的方面考慮:
解決思路:
使用批處理指令碼監控kittle程序是否已經啟動,如果啟動,則該指令碼什麼都不做,自動結束。如果程序沒有啟動,則使用命令列方式啟動kittle。該監控任務使用windows系統自帶的定時任務去定期檢查它。
首先必須清楚使用命令列啟動kittle的指令:

kitchen /file:(kjb檔案全路徑) /level:basic>>(日誌檔案全路徑)

指令含義這裡不解釋。
從指令上來看,他是呼叫的本地kittle檔案裡面的一個kitchen.bat指令碼執行該任務的。
所以進kitchen.bat指令碼檢視:

    @echo off
    setlocal
    SET initialDir=%cd%
    pushd %~dp0
    SET STARTTITLE="Kitchen"
    SET SPOON_CONSOLE=1
    call Spoon.bat -main org.pentaho
.di.kitchen.Kitchen -initialDir "%initialDir%"\ %* popd

由指令碼內容可以看出,其實它的本質上還是呼叫的spoon.bat這個批處理程式。同樣的,我們進spoon.bat檢視:

    @echo off
    setlocal 

    cd /D %~dp0

    REM **************************************************
    REM ** Set console window properties                **
    REM **************************************************
    REM
TITLE Spoon console REM COLOR F0 :: ************************************************** :: ** Kettle home ** :: ************************************************** if "%KETTLE_DIR%"=="" set KETTLE_DIR=%~dp0 if %KETTLE_DIR:~-1%==\ set KETTLE_DIR=%KETTLE_DIR:~0,-1% cd %KETTLE_DIR% REM Special console/debug options when called from SpoonConsole.bat or SpoonDebug.bat if "%SPOON_CONSOLE%"=="1" set PENTAHO_JAVA=java.exe if not "%SPOON_CONSOLE%"=="1" set PENTAHO_JAVA=javaw.exe set IS64BITJAVA=0 call "%~dp0set-pentaho-env.bat" REM ************************************************** REM Platform Specific SWT ** REM ************************************************** REM The following line is predicated on the 64-bit Sun REM java output from -version which REM looks like this (at the time of this writing): REM REM java version "1.6.0_17" REM Java(TM) SE Runtime Environment (build 1.6.0_17-b04) REM Java HotSpot(TM) 64-Bit Server VM (build 14.3-b01, mixed mode) REM REM Below is a logic to find the directory where java can found. We will REM temporarily change the directory to that folder where we can run java there pushd "%_PENTAHO_JAVA_HOME%" if exist java.exe goto USEJAVAFROMPENTAHOJAVAHOME cd bin if exist java.exe goto USEJAVAFROMPENTAHOJAVAHOME popd pushd "%_PENTAHO_JAVA_HOME%\jre\bin" if exist java.exe goto USEJAVAFROMPATH goto USEJAVAFROMPATH :USEJAVAFROMPENTAHOJAVAHOME FOR /F %%a IN ('.\java.exe -version 2^>^&1^|%windir%\system32\find /C "64-Bit"') DO (SET /a IS64BITJAVA=%%a) GOTO CHECK32VS64BITJAVA :USEJAVAFROMPATH FOR /F %%a IN ('java -version 2^>^&1^|%windir%\system32\find /C "64-Bit"') DO (SET /a IS64BITJAVA=%%a) GOTO CHECK32VS64BITJAVA :CHECK32VS64BITJAVA IF %IS64BITJAVA% == 1 GOTO :USE64 :USE32 REM =========================================== REM Using 32bit Java, so include 32bit SWT Jar REM =========================================== set LIBSPATH=libswt\win32 GOTO :CONTINUE :USE64 REM =========================================== REM Using 64bit java, so include 64bit SWT Jar REM =========================================== set LIBSPATH=libswt\win64 set SWTJAR=..\libswt\win64 :CONTINUE popd REM ********************** REM Collect arguments REM ********************** set _cmdline= :TopArg if %1!==! goto EndArg set _cmdline=%_cmdline% %1 shift goto TopArg :EndArg REM ****************************************************************** REM ** Set java runtime options ** REM ** Change 2048m to higher values in case you run out of memory ** REM ** or set the PENTAHO_DI_JAVA_OPTIONS environment variable ** REM ****************************************************************** if "%PENTAHO_DI_JAVA_OPTIONS%"=="" set PENTAHO_DI_JAVA_OPTIONS="-Xms512m" "-Xmx512m" "-XX:MaxPermSize=256m" set OPT=%OPT% %PENTAHO_DI_JAVA_OPTIONS% "-Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2" "-Djava.library.path=%LIBSPATH%" "-DKETTLE_HOME=%KETTLE_HOME%" "-DKETTLE_REPOSITORY=%KETTLE_REPOSITORY%" "-DKETTLE_USER=%KETTLE_USER%" "-DKETTLE_PASSWORD=%KETTLE_PASSWORD%" "-DKETTLE_PLUGIN_PACKAGES=%KETTLE_PLUGIN_PACKAGES%" "-DKETTLE_LOG_SIZE_LIMIT=%KETTLE_LOG_SIZE_LIMIT%" "-DKETTLE_JNDI_ROOT=%KETTLE_JNDI_ROOT%" REM *************** REM ** Run... ** REM *************** if %STARTTITLE%!==! SET STARTTITLE="Spoon" REM Eventually call java instead of javaw and do not run in a separate window if not "%SPOON_CONSOLE%"=="1" set SPOON_START_OPTION=start %STARTTITLE% @echo on %SPOON_START_OPTION% "%_PENTAHO_JAVA%" %OPT% -jar launcher\pentaho-application-launcher-7.0.0.0-25.jar -lib ..\%LIBSPATH% %_cmdline% @echo off if "%SPOON_PAUSE%"=="1" pause

以上可以看出:
1、其實該檔案就是kittle軟體的啟動入口,通過上一步的引數判斷,判斷是直接啟動還是從kitchen.bat啟動的,如果是從kitchen.bat開始啟動,則使用java.exe方式啟動該軟體;如果是直接雙擊啟動,就沒有讀取到kitchen.bat裡面傳遞過來的引數,所以使用javax.exe方式啟動(總所周知javax.exe是啟動java介面的程式)。
2、命令列啟動的呼叫鏈:命令列輸入指令>>kitchen.bat>>spoon.bat>>java.exe

分析呼叫鏈:
1、命令列指定呼叫kitchen.bat指令碼,該指令碼定義了一個引數:SPOON_CONSOLE,並賦值為1。
2、kitchen.bat呼叫spoon.bat,在spoon.bat中,通過讀取上一步給定的引數來指定執行程式java.exe。

使用過tomcat的同學可能知道,tomcat啟動的本質也是呼叫java.exe該程序,為了防止衝突,所以必須改變我們監控的物件java.exe,那麼,問題來了:如何才能改變我們所需要的監控物件的程序名稱?由此,百度到一個可以建立屬於自己的程序方法:http://blog.csdn.net/fangdengfu123/article/details/70051498

由此我們通過逆向思維可以分析出,必須在spoon中改變原有指向的執行程式,但是又不能改變kittle的正常使用,所以這裡又兩種方案:
1、建立spoon.bat副本,在該副本中改變PENTAHO_JAVA的值(也就是將執行程式指向我們自己的啟動程式);
2、建立kitchen.bat副本,在該副本中還是呼叫spoon.bat,但是修改SPOON_CONSOLE的引數值,然後在spoon.bat中對該引數進行判斷,如果等於我們設定的值,則將PENTAHO_JAVA的值指向我們的程式入口。

那麼本質上我們只要對java.exe進行監控,由此誕生了我們自己寫的表層的批處理指令碼:

@echo off

:after
:check javaKittleProHuizong.exe 
tasklist >list.txt 
find /i "javaKittleProHuizong.exe" list.txt 

if "%errorlevel%"=="1" (goto before) else (goto over) 

:before
cd e:\data-integration
start kittlePreHuizong.bat

echo "use ping to delay"
set SLEEP=ping 127.0.0.1 /n
echo %time%
%SLEEP% 30 > nul
echo %time%
:over
end

該指令碼主要任務就是檢查指定的javaKittleProHuizong.exe是否存在,如果存在,則直接跳到程式結束位置;如果不存在,呼叫我們建立的kittlePreHuizong.bat副本。

kittlePreHuizong.bat中就是一條啟動kittle的指令。

然後建立我們的kittlePreHuizong.bat批處理程式:

@echo off
setlocal
SET initialDir=%cd%
pushd %~dp0
SET STARTTITLE="KitchenPreHuizong"
SET SPOON_CONSOLE=1
call SpoonPreHuizong.bat -main org.pentaho.di.kitchen.Kitchen -initialDir "%initialDir%"\ %*
popd

該指令碼呼叫我們複製的spoon.bat副本:
SpoonPreHuizong.bat
在該副本中,我們只修改了變數的引用地址。
if “%SPOON_CONSOLE%”==”1” set PENTAHO_JAVA=javaKittleProHuizong.exe

然後在windows的定時任務裡面建立定時任務定時呼叫該監控指令碼即可。

雖然可以讓該監控dos一直開著進行定時延遲然後檢查程序,但是保不準負責監控的dos異常關閉,所以還是定時任務穩妥些。