許麗光 翁花群 曾福山
摘要:設計一個基于Delphi編譯環境的定時重啟特定服務的程序,并經實際應用環境反復實驗測試,證實能夠很好地解決由于Tomcat運行環境異常錯誤大量累積后,造成內存致命錯誤,無法提供正常訪問服務等諸如此類問題。
關鍵詞:Delphi編譯;Apache服務;Tomcat;內存溢出錯誤;批處理命令
中圖分類號:TP319 文獻標識碼:A
文章編號:1009-3044(2019)12-0284-03
開放科學(資源服務)標識碼(OSID):
Delphi-based Design and Implementation of Scheduled Service-Restarting Program
XU Li-guang, WENG Hua-qun, ZENG Fu-shan
(Informatization Construction and Management Center, Putian University, Putian 351100, China)
Abstract: A Delphi-based scheduled service-restarting program has been designed and repeatedly tested in the actual application environment, which proves that it can solve such problems as failure to get access to services due to fatal memory error resulting from large accumulation of abnormal errors in the Tomcat runtime environment.
Key words: Delphi compilation; Apache service; Tomcat; Out-Of-Memory Error; batch command
1 背景
在日常信息化運維工作中經常遇到某個程序在運行一段時間后出現異常,需要重啟服務。例如Tomcat運行環境在運行一段時間后,由于大量用戶同時訪問Apache服務器而對服務器內存的影響,異常錯誤大量累積后,造成內存致命錯誤,出現“OutOfMemoryError”提示,導致Apache服務異常,無法提供正常訪問服務。此時,往往需要重啟Apache服務,重新初始化Tomcat運行環境,以使Apache服務恢復正常。在這種情況下,如果手動進行相關服務重啟操作,對于信息化運維工作人員而言,常常不勝其煩,很大程度上增加了信息化日常運維工作量;而且由于異常情況的出現無法提前預知,錯誤總是不定期出現,運維人員很難都做到及時處理,影響了工作效率和成效,如此反復,給所服務的對象用戶帶來極差的服務體驗。為了有效解決上述問題,本文設計了一個基于Delphi編譯環境的定時重啟該特定服務的程序,經實際應用環境多次實驗測試,該程序能夠很好地解決此類問題。
2 重啟Tomcat運行環境的初始化批處理代碼解析
實現初始化Tomcat運行環境過程的批處理(startup.bat)部分內容解析如下:
@echo off
if "%OS%" == "Windows_NT" setlocal //檢測操作系統環境變量。
……
:okExec
set CMD_LINE_ARGS= //清除CMD_LINE_ARGS環境變量原值。
:setArgs
if ""%1""=="""" goto doneSetArgs //若參數%1為空則執行doneSetArgs段,表示已接傳入的參數。
set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1 //給 CMD_LINE_ARGS 添加參數%1,以空格分隔。
Shift //截除原參數,使參數%1成為原參數。
// 上述代碼是將所有參數用空格分隔開,并給CMD_LINE_ARGS賦值。
goto setArgs
:doneSetArgs
call "%EXECUTABLE%" start %CMD_LINE_ARGS%
//運行新窗口,重啟執行 EXECUTABLE 環境變量所示的catalina.bat 程序及 CMD_LINE_ARGS 所含的參數。
:end //初始化結束。[1]
3 程序設計思路
利用可視化編程開發工具Delphi 2010的Timer時間組件每隔1秒通過API函數獲取系統時間,并把時間字符串與所設定的定時啟動時間比對,滿足條件即調用API函數ShellExecute執行特定服務或程序,本文實際應用于重啟上述初始化Tomcat運行環境的批處理程序(startup.bat)。
關鍵函數ShellExecute原型如下[2](須引用ShellAPI .pas單元,即uses ShellAPI;):
function ShellExecute(hWnd: HWND; Operation, FileName, Parameters,Directory: PChar; ShowCmd: Integer): HINST;
若ShellExecute函數執行成功,則返回被執行程序的實例句柄。若返回值低于32,則表示執行存在錯誤。
4 程序流程圖(如圖1)
程序流程:啟動運行程序后,待用戶在時間輸入框中按照提示的時間格式設定好定時啟動運行的時間規則內容,以及在程序輸入框中瀏覽或指定需執行的程序的完整路徑和文件名,然后點擊啟動按鈕,啟動按鈕切換為停止按鈕,定時器開始持續獲取系統時間,每秒比對系統時鐘是否滿足設定好的啟動時間,滿足條件則立即執行指定程序,否則定時器繼續獲取系統時間,進行下一秒比對,當用戶點擊停止按鈕,則程序停止運行,關閉后結束運行。
5 程序實現(主要模塊代碼)
5.1 初始化運行界面模塊
本模塊代碼用于實現程序運行界面窗體內容初始化顯示,提示定時時間設定的格式規則,并提取時間輸入范例,方便用戶直接進行修改。
procedure TForm_Exe.FormShow(Sender: TObject);
begin
Label_Time.Caption:='執行時刻設定(格式:'+DateTimeToStr(Now)+')'; [3]
Edit_SetTime.Text:=Copy(DateTimeToStr(Now),Length(DateTimeToStr(Now))-7);
Edit_SetTime.SetFocus;
end;
5.2 “啟動”按鈕和“停止”按鈕切換模塊
本模塊代碼用于實現程序 “啟動”功能按鈕和“停止”功能按鈕交替切換,達到程序交互界面簡潔友好的目的。
procedure TForm_Exe.Button_ExecuteClick(Sender: TObject);
begin
if Button_Execute.Caption='啟動' then
begin
Timer_Now.Enabled:=True;
Edit_SetTime.ReadOnly:=True;
Button_Execute.Caption:='停止';
end
else
begin
Timer_Now.Enabled:=False;
Edit_SetTime.ReadOnly:=False;
Button_Execute.Caption:='啟動';
Label_Time.Caption:='執行時刻設定(格式:'+DateTimeToStr(Now)+')';
end
end;
5.3 瀏覽并提取指定程序的完整路徑和文件名模塊
本模塊代碼用于實現“瀏覽”按鈕功能,獲得所指定執行程序完整的路徑和文件名。
procedure TForm_Exe.Button_LoadClick(Sender: TObject);
begin
if OpenDialog_ExeFile.Execute then Edit_ExeFileName.Text:=(OpenDialog_ExeFile.FileName); [4]
end;
5.4 Timer組件主程序模塊
本模塊代碼用于實現由Timer定時器每秒獲取系統時鐘,判斷系統時鐘是否包含設定好的啟動時間,滿足條件則繼續執行并打開指定程序,若所指定的執行文件不存在,則給出確認文件是否存在的提示信息。
procedure TForm_Exe.Timer_NowTimer(Sender: TObject);
begin
Label_Time.Caption:='現在時刻:'+DateTimeToStr(Now);
if Pos(Edit_SetTime.Text,Label_Time.Caption)<=0 then Exit;
ExeFile:=Edit_ExeFileName.Text;
if (FileExists(ExeFile)) then
ShellExecute(Handle,nil,PWideChar(ExeFile),nil,nil,SW_NORMAL)
else
messagebox(0,PWideChar(' 請確認文件 ('+ExeFile+') 是否存在! '),'請確認...',MB_OK);
end;
6 程序運行界面設計[5](如圖2)
程序運行界面設計遵循了界面友好的重要原則,兼顧簡潔和美觀,窗口標題欄和界面標題體現程序所實現的功能,交互輸入框內容格式提示和功能按鈕含義清晰明了,能夠直觀地引導用戶上手使用。
7 程序運行效果
如上例圖2所示,假設程序重啟時間設定為3:59:59,當系統時鐘滿足所設定的時間字符串,則立即執行所指定的Tomcat運行環境的初始化批處理程序startup.bat。由于系統時鐘為24小時格式,故每天滿足所設定的時間共有三次,分別為03:59:59、13:59:59、23:59:59,如此可以自動在Tomcat運行環境出現異常前定時恢復初始化環境狀態,保持Apache服務處于良好運行狀態。
8 結束語
定時重啟特定服務的程序不僅可以使需重啟的服務每天有多個時段進行重新執行,還可以指定某天某個時刻執行特定程序或服務,能夠有效滿足程序自動運行的需求,使各類服務保持良好運行狀態。
定時重啟特定服務的程序后續有待從多個方面對程序代碼進一步改良和完善,以滿足不同的需求。如根據需要對設定的時間按日期設定遞增值,并可設定日期遞增的間隔長度;此外,考慮在程序實現中調用進程結束命令,以便使得特定服務重啟前先結束內存中的進程運行,釋放內存空間,避免程序重復運行,占用多余的內存,使用taskkill結束進程的命令是一個可行的方法之一。taskkill /f /im explorer.exe范例釋義:taskkill是批處理中常用的結束進程的命令,/f和/im都是參數,前者表示強制結束,后者表示結束進程用程序名顯示,如explorer.exe。[6]
參考文獻:
[1] 解讀tomcat 的startup.bat內容[EB/OL]. [2013-07-24]. https://zhidao.baidu.com/question/573218387.html.
[2] Delphi中ShellExecute使用詳解[EB/OL]. [2017-04-19]. https://www.cnblogs.com/bestlove/p/6734973.html.
[3] 陳燦煌. Delphi 6徹底研究[M]. 北京: 中國鐵道出版社, 2002.
[4] 明日科技. Delphi開發技術大全[M]. 北京: 人民郵電出版社, 2007.
[5] 求實科技. Delphi 7程序設計與開發技術大全[M]. 北京: 人民郵電出版社, 2004.
[6] 自動結束某個指定進程[EB/OL]. [2017-06-22]. https://zhidao.baidu.com/question/2271658977384051068.html.
【通聯編輯:謝媛媛】