|
最近,我们的web服务老是自动的就死掉了,为此,头儿让我们几个轮流值班,时刻注视web服务,如果web服务死掉了,我们需要立刻启动它. 这个方法,又劳民又伤才.谁都不愿意值班,怎么办? 我想了一下,写个监控web服务的程序不就得了? 可以有多种监控方式: 1:传统桌面程序. 2:b/s的监控程序. 先试验一个传统桌面程序. 先做个试验:监控foxmail.exe是否运行,如果没有运行,就启动它. 在系统的进程列表中,foxmail.exe中的进程名称为foxmail.exe,如果有名称为foxmail.exe的进程,这进行任何动作,否则启动它. //--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include "Tlhelp32.h" #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { Timer1->Enabled = true; } //--------------------------------------------------------------------------- void __fastcall TForm1::Timer1Timer(TObject *Sender) { try{ HANDLE SnapShot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); if (SnapShot == INVALID_HANDLE_VALUE) return; PROCESSENTRY32 ProcessInfo; ProcessInfo.dwSize=sizeof(ProcessInfo); BOOL Status=Process32First(SnapShot,&ProcessInfo); BOOL flag = false; //是否有foxmail.exe进程 while(Status) { if(AnsiString(ProcessInfo.szExeFile).LowerCase() == "foxmail.exe") { flag = true; } Status=Process32Next(SnapShot,&ProcessInfo); } AnsiString tempTime = FormatDateTime("yyyy,mm,dd,hh:nn:ss", Now()); if(!flag){ AnsiString Exename = "D:\\Program Files\\Foxmail\\Foxmail.exe"; ShellExecute(Handle,"open",Exename.c_str(),"","", SW_SHOW ); Memo1->Lines->Add("restart this program at " + tempTime); } else{ Memo1->Lines->Add("running at " + tempTime); } CloseHandle (SnapShot); }catch(...){
} } //--------------------------------------------------------------------------- void __fastcall TForm1::Button2Click(TObject *Sender) { Timer1->Enabled = false; } //--------------------------------------------------------------------------- 这个程序可以成功监控foxmail.exe的运行,如果foxmail.exe停掉了,则自动启动它. 可是:我们的web服务程序在进程中为:java.exe,并且有两个.怎么办? 有一个近似的方法:如果进程中有两个java.exe,则认为web服务良好,如果java.exe少于两个,则认为web停了,需要重新启动. 所以修改后得到如下程序: void __fastcall TForm1::Button1Click(TObject *Sender) { i = StrToInt(Edit1->Text); //i为全局变量,记录应该有的java数目,这里为2. Timer1->Enabled = true; } //--------------------------------------------------------------------------- void __fastcall TForm1::Timer1Timer(TObject *Sender) { try{ HANDLE SnapShot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); if (SnapShot == INVALID_HANDLE_VALUE) return; PROCESSENTRY32 ProcessInfo; ProcessInfo.dwSize=sizeof(ProcessInfo); BOOL Status=Process32First(SnapShot,&ProcessInfo); int j = 0; //记录当前java.exe数目 while(Status) { if(AnsiString(ProcessInfo.szExeFile).LowerCase() == "java.exe") { j++; } Status=Process32Next(SnapShot,&ProcessInfo); } AnsiString tempTime = FormatDateTime("yyyy,mm,dd,hh:nn:ss", Now()); if(j<i){ AnsiString Exename = "C:\\bea\\user_projects\\domains\\HBEP\\autoStart.cmd"; ShellExecute(Handle,"open",Exename.c_str(),"","", SW_SHOW ); Memo1->Lines->Add("restart this program at " + tempTime); } else{ Memo1->Lines->Add("running at " + tempTime); } CloseHandle (SnapShot); }catch(...){ } } 似乎并不满意,因为任何一个java程序的运行,在系统的进程表中都叫java.exe.怎么办?(虽然我们的服务器上很干净,基本不运行其他的java程序). 采用另外的一个方法:xmlhttp技术: 我的想法是这样的: 我们的web服务器是weblogic,我在服务器上另外部署一个tomcat服务器,分别在两个web服务里面写一个servlet, 然后写一个html文件(不需要步署),采用xmlhttp技术访问weblogic的servlet(假定为A),如果A有响应,则表明weblogic服务在运行,如果连续5次无响应,则 认为weblogic服务死掉了,此时给tomcat的servlet(假定为B)发送一个xml命令,让servlet执行启动weblogic服务的操作: Runtime.getRuntime().exec( "cmd /c start C:\\bea\\user_projects\\domains\\HBEP\\autoStart.cmd"); html文件如下(采用xmlhttp给servlet发送xml命令): <BODY> <script language="javascript"> var XML="<root><test>ask</test></root>" //定义一个ask命令,发送给servlet var XMLrestart="<root><test>restart</test></root>" var xmlHttp = new ActiveXObject("Msxml2.XMLHTTP"); var xmlDoc=new ActiveXObject("Msxml2.DOMDocument"); function readxml(myXML){//客户端xml的解析 xmlDoc.loadXML(myXML); if(xmlDoc.parseError.line>0){ throw xmlDoc.parseError.reason; } var nodes= xmlDoc.selectNodes("/root/test"); for(var i=0;i<nodes.length;i++){ return(nodes.item(i).text); } }
function action(){//客户端和服务端的通讯 xmlHttp.open("post","http://127.0.0.1:7001/xmlhttpTest/UrlTestServlet",false); xmlHttp.setRequestHeader("context-type","text/xml;charset=utf-8"); xmlHttp.send(XML); var answerxml = xmlHttp.responseText; if(readxml(answerxml))!='ok'{ //没有接到servlet的响应,认为weblogic关闭,则向tomcat的servlet发送"restart"命令 xmlHttp.open("post","http://127.0.0.1:8888/xmlhttpTest/UrlTestServlet",false); xmlHttp.setRequestHeader("context-type","text/xml;charset=utf-8"); xmlHttp.send(XMLrestart); var answerxmlFromWeblogic = xmlHttp.responseText; } } </script> <button onclick="action();">朝服务器传送xml,并接收服务器回应</button> </BODY> 再在weblogic部署一个servlet,内容如下: package com.lcl; import javax.servlet.*; import javax.servlet.http.*; import java.io.*; import java.util.*; import org.dom4j.io.*; import org.dom4j.*; /** * @author lcl * * TODO 要更改此生成的类型注释的模板,请转至 * 窗口 - 首选项 - Java - 代码样式 - 代码模板 */
public class UrlTestServlet extends HttpServlet { private static final String CONTENT_TYPE = "text/xml;charset=utf-8"; //Initialize global variables public void init() throws ServletException { } //Process the HTTP Get request public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType(CONTENT_TYPE); request.setCharacterEncoding("utf-8"); PrintWriter out = response.getWriter(); InputStream is=request.getInputStream();
SAXReader reader=new SAXReader(); Document doc=null; try{ doc=reader.read(is); } catch(Exception ex){ System.out.println(ex); } String[] s= getElementTexts(doc,"test"); out.println("<root>"); out.println("<test>"); out.println("ok"); out.println("</test></root>"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request,response); } private String getElementText(Document doc,String name){ return doc.getRootElement().element(name).getText(); } private String[] getElementTexts(Document doc,String name){ List l=doc.getRootElement().elements(name); Iterator it=l.iterator(); List l1=new LinkedList(); while(it.hasNext()){ Element e=(Element)it.next(); l1.add(e.getText()); } return (String[])l1.toArray(new String[]{}); } //Clean up resources public void destroy() { } } weblogic的web.xml更改如下(加servlet映射): <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <display-name>Welcome to Tomcat</display-name> <description> Welcome to Tomcat </description> <!-- JSPC servlet mappings start -->
<servlet> <servlet-name>UrlTestServlet</servlet-name> <servlet-class>com.lcl.UrlTestServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>UrlTestServlet</servlet-name> <url-pattern>/UrlTestServlet</url-pattern> </servlet-mapping> <!-- JSPC servlet mappings end --> <welcome-file-list> <welcome-file>index.htm</welcome-file> </welcome-file-list> </web-app>
tomcat的servlet和weblogic的servlet类似,只是在收到restart命令后执行: Runtime.getRuntime().exec( "cmd /c start C:\\bea\\user_projects\\domains\\HBEP\\autoStart.cmd"); ok,搞定了,现在可以高枕无忧了. 甚至可以做到weblogic和tomcat的互启动. 现在不用值班了.呵呵 特此存档.
|