Windows环境下Java、Python自动监测tomcat并重启和关闭tomcat

背景:春节期间,服务器老是忽然断开数据库链接,总是要手工去重启tomcat,这实在是件苦差事,这数据库上的问题我也没法解决,干脆写个什么东西来做定时的检测的重启工作。

服务器环境:Windows2003 service

tomcat版本:tomcat6

Java版本:jdk6

  最初想用Java来做这个工作,思路是,定时链接url,如果返回的不是200,那么就关闭tocmat并重启他

  代码如下:

import java.io.File;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 用户 :LX
 * 创建时间: 2018/2/23. 14:57
 * 地点:广州
 * 目的: 定时检查系统是否挂掉
 * 结果:
 */
public class TaskCheck {

    /**
     * 访问的URL地址
     */
    private static final String URLVISIT = "要检查的url地址";


    public static void main(String[] args) {
        TaskCheck taskCheck = new TaskCheck();

        while (1 == 1){

            System.out.println(taskCheck.getDate() + "=====================开始检测系统状态====================================");
            if (!taskCheck.checkGSSurvival()){
                taskCheck.stopTomcat();
                try {
                    System.out.println("关闭tomcat·············");
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                //重启tomcat
                System.out.println("正在重启tomcat·············");
                taskCheck.startTomcat();

            }  else {

            }
            System.out.println(taskCheck.getDate() + "==============================系统检测结束==============================");

            try {
                Thread.sleep(1000 * 60 * 5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }


    /**
     * 启动tomcat
     */
    public void startTomcat(){
        Runtime run = Runtime.getRuntime();
        String[] envp = { //环境变量设置
                "JAVA_HOME=C:\\Java\\jdk1.6.0_45", //Ant
                "CATALINA_HOME=E:\\apache-tomcat-7.0.47" //Tomcat
        };
        try {
            // 启动另一个进程来执行命令
            Process p = run.exec("E:\\apache-tomcat-7.0.47\\bin\\startup.bat", envp, new File("E:\\apache-tomcat-7.0.47"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 停止tomcat
     */
    public void stopTomcat() {
        Runtime run = Runtime.getRuntime();
        String[] envp = { //环境变量设置
                "JAVA_HOME=C:\\Java\\jdk1.6.0_45", //Ant
                "CATALINA_HOME=E:\\apache-tomcat-7.0.47" //Tomcat
        };
        try {
            // 启动另一个进程来执行命令
            Process p = run.exec("E:\\apache-tomcat-7.0.47\\bin\\shutdown.bat", envp, new File("E:\\apache-tomcat-7.0.47"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 检查系统是否还存活
     * @return true 还存活, false 已经关闭
     */
    public boolean checkGSSurvival(){

        boolean result = true;

        for (int i = 0; i < 3; i ++){
            try {
                URL url = new URL(URLVISIT);
                HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                // 设定传送的内容类型是可序列化的java对象
                // (如果不设此项,在传送序列化对象时,当WEB服务默认的不是这种类型时可能抛java.io.EOFException)
                httpURLConnection.setRequestProperty("Content-type", "application/x-java-serialized-object");
                //setConnectTimeout:设置连接主机超时(单位:毫秒)
                httpURLConnection.setConnectTimeout(20000);
                //setReadTimeout:设置从主机读取数据超时(单位:毫秒)
                httpURLConnection.setReadTimeout(20000);
                httpURLConnection.connect();

                //可以获取状态码
                System.out.println(httpURLConnection.getResponseCode());
                if (200 == (httpURLConnection.getResponseCode())){
                    System.out.println("系统运行正常!");
                    return true;
                } else {
                    System.out.println("异常!" + getDate());
                    result =  false;
                }

                //休眠10秒
                Thread.sleep(10000);


            } catch (MalformedURLException e) {
                e.printStackTrace();
                System.err.println("打开系统失败================================================" + getDate());
                result =  false;
            } catch (IOException e) {
                e.printStackTrace();
                System.err.println("访问系统打开失败================================================" + getDate());
                result =  false;
            } catch (InterruptedException e) {
                e.printStackTrace();
                result =  false;
            }
        }
        return result;
    }


    /**
     * 获取时间
     * @return
     */
    public String getDate(){
        Date date = new Date();
        SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd :hh:mm:ss");
        return dateFormat.format(date);
    }





}

网上找的基本是在Linux系统上的,并且写法都有些不同,上面的这个Java是基于Windows服务器的,在本地测试是没问题,主要是关键点在于,第一:代码中要将环境变量传进去,否则可能导致启动不了tomcat,第二,要设置好环境变量,tomcat的和Java的

以上代码在本地测试是没有问题的,但是跑的正式环境却调用了关闭tomcat的命令却关闭不了,不知道到底是什么原因,实在不想去看这Java这里相关的代码,太不友好了,转而去看了下Python的,Python简单方便,就用Python了,代码如下:

import webbrowser
import requests
import datetime
import time

# tomcat的启动路径
tomcatStart = "E:\\apache-tomcat-7.0.47\\bin\\startup.bat"
# tomcat的关闭路径
tomcatStop = "E:\\apache-tomcat-7.0.47\\bin\\shutdown.bat"
# 要检查的url
url = "要检查的url"

# 启动tomcat
def startTomcat():
    webbrowser.open("file:///" + tomcatStart)

# 关闭tomcat
def stopTomcat():
    webbrowser.open("file:///" + tomcatStop)
    # 终止tomcat进程,如果系统只有一个tomcat在运行,没其他的Java程序在跑的话,用这个可以快速关掉进程,该方式是在上面这种情况还关闭不了的情况下使用的
    # os.system("taskkill /F /IM java.exe")

 # 检查系统是否还存活 true 还存活, false 已经关闭
def checkWeb():
    i = 0
    for i in range(3):
        try:
            i = i + 1
            result = True
            headers = {
                'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36 SE 2.X MetaSr 1.0'}
            response = requests.get(url, timeout = 10) #请求超时时间为10秒
            # encode = response.encoding #从http header 中猜测的相应内容编码方式
            code = response.status_code #http请求的返回状态,若为200则表示请求成功,返回的状态码是 int类型
            print(str(getDate()) + "  检测到状态编码:" + str(code))
            if code == 200:
                result = True
            else:
                result = False
            time.sleep(5) #休眠5秒
        except:
            result = False
    return result

# 获取时间
def getDate():
    today = datetime.date.today()
    return today


def mainApp():
    while True:
        print(str(getDate()) + " =========开始检测系统状态=============")
        if checkWeb() == False:
            print(str(getDate()) + "  系统异常中·············")
            print("=====开始停止tomcat,等待75秒··====")
            stopTomcat()
            time.sleep(75)  # 休眠75秒来关闭应用,系统应用在服务器上关闭有点慢
            print("=====正在重启tomcat====")
            startTomcat()
        else:
            print(str(getDate()) + "  ***系统正常***")


        print(str(getDate()) + "  =========结束检测系统状态=============")
        time.sleep(60 * 3)  # 休眠3分钟

mainApp()

代码就上面这么简单,放到服务器上可能不想安装Python环境,干脆打成exe包

pip安装好模块 pyinstaller ,直接运行 python pyinstaller.py -F 包名.py,

exe文件出来了

放到服务器上运行即可,效果如下

注意:如果还是有无法关闭tomcat进程的情况,可以使用直接干掉进程的方式,该方式只适合只有一个tomcat在运行,且无其他的Java程序运行的时候,使用时将代码注释放开并注释上面的调用tocmat自动关闭那里的代码即可。

update:2018.2.27 =========================================

这两天正好有时间看了看Python,感觉上面的代码还可以再优化下,适用于多个tomcat的情况也能自动重启关闭,

代码如下:

import os

"""
根据端口获取PID
    返回获取的PID
"""
def getPID(port):
    try:
        # 根据命令获取到指定端口的信息 TCP    0.0.0.0:8080(端口)           0.0.0.0:0              LISTENING       6856(PID)
        ret = os.popen("netstat -nao | findstr " + port)
        str_list = ret.read()
        print(str_list)
        # 字符串按空格分成列表split()
        ret_list = str_list.split()
        # 截取出pid
        pid = ret_list[4][:6]
        print(type(pid))
        return pid
    except:
        print("根据端口找不到该对应应用")
        return "0"

"""
# 根据PID杀死进程
"""
def kill(pid):
    try:
        os.popen('taskkill.exe /pid:' + str(pid))
        print("已经杀死PID为 " + pid + " 的进程")
    except OSError:
        print('没有如此进程!!!')
        errorStr = OSError.errno
        print("错误信息" + errorStr)

if __name__ == '__main__':
    pid = getPID("8080")
    print(pid)
    if pid == "0":
        print("没有需要删除的进程")
    else:
        kill(pid)

这里只给出关键代码,其他的东西基本上自己拼下即可,思路如下:

  一直监听网站是否正常,一旦不正常,那么去获取指定的端口下的PID,这样就拿到了tomcat的进程的PID,然后根据PID关闭应用即可,接着重启,这样的写法基本上可以满足各种需求了

猜你喜欢

转载自my.oschina.net/sprouting/blog/1624053