關於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異常關閉,所以還是定時任務穩妥些。