2019独角兽企业重金招聘Python工程师标准>>>
背景:春节期间,服务器老是忽然断开数据库链接,总是要手工去重启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关闭应用即可,接着重启,这样的写法基本上可以满足各种需求了