手写tomcat监控工具---宕机重启 原

使用前提: 1、打成jar包,并在控制台运行:java -jar TomcatMonitorUtil.jar 2、需要配置tomcat环境变量 

#TOMCAT启动路径
startup.bat=E:/wwx/apache-tomcat-9.0.7/bin/startup.bat
#TOMCAT关闭路径
shutdown.bat=E:/wwx/apache-tomcat-9.0.7/bin/shutdown.bat





#测试连接总次数
testTotalCount=3
#测试连接间隔时间,单位为秒
testIntervalTime=3




#端口80 项目名zagame
zaGameHttp=http://127.0.0.1/zagame/userLoginByTel.json
#端口80 项目名zagame-server
zaGameServerHttp=http://127.0.0.1/games/startServer
stopZaGameServerHttp=http://127.0.0.1/games/stopServer




#日志文件目录
logDir=E:/wwx/data/eventlogs/games
#限制LOG文件大小防止溢出
logSize=10
import java.io.*;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.Socket;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * ProjectLaunchUtil
 *
 * @author weixiang.wu
 * @date 2018 -05-04 17:08
 */
public class TomcatMonitorUtil {
	private static String startupBat;
	private static String shutdownBat;
	private static int testIntervalTime;
	private static int testTotalCount;
	private static String zaGameHttp;
	private static String zaGameServerHttp;
	private static String logDir;
	private static Long logSize;
	private static String stopZaGameServerHttp;
	private static SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

	static {
		InputStream in = TomcatMonitorUtil.class.getResourceAsStream("config.properties");
		Properties p = new Properties();
		try {
			p.load(in);
			startupBat = p.getProperty("startup.bat");
			shutdownBat = p.getProperty("shutdown.bat");
			testIntervalTime = Integer.parseInt(p.getProperty("testIntervalTime"));
			testTotalCount = Integer.parseInt(p.getProperty("testTotalCount"));
			zaGameHttp = p.getProperty("zaGameHttp");
			zaGameServerHttp = p.getProperty("zaGameServerHttp");
			logDir = p.getProperty("logDir");
			stopZaGameServerHttp = p.getProperty("stopZaGameServerHttp");
			logSize = Long.valueOf(p.getProperty("logSize"));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private TomcatMonitorUtil() {
		Timer timer = new Timer();
		timer.scheduleAtFixedRate(new TimerTask() {
			@Override
			public void run() {
				ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
				fixedThreadPool.execute(new Runnable() {

					@Override
					public void run() {
						System.err.println("正在监控中...");
						while (true) {
							int testCount = 0;
							// 测试tomcat是否需要重新启动
							boolean isRun = ping();
							while (!isRun) {
								testCount++;
								System.err.println("尝试连接第 [" + testCount + "] 次失败");
								if (testCount >= testTotalCount) {
									break;
								}
								isRun = ping();
							}

							if (!isRun) {
								try {
									//关闭tomcat服务
									Runtime.getRuntime().exec(shutdownBat);

									System.out.println(df.format(new Date()) + ":关闭tomcat服务,稍等5秒钟");
									Thread.sleep(5000);
									//启动tomcat服务
									System.out.println(df.format(new Date()) + ":测试连接失败,正在重启tomcat");
									Process process = Runtime.getRuntime().exec(startupBat);
									final InputStream in = process.getInputStream();
									BufferedReader br = new BufferedReader(new InputStreamReader(in));
									StringBuilder buf = new StringBuilder();
									String line = null;
									while ((line = br.readLine()) != null) {
										buf.append(line);
									}
									System.out.println("输出结果为:" + buf);
									System.out.println(df.format(new Date()) + ":重启tomcat成功");
									String stop = pingHttpGet(stopZaGameServerHttp, "POST");
									if (stop == null || pingHttpGet(stopZaGameServerHttp, "POST").contains("关闭")) {
										System.out.println(df.format(new Date()) + ":关闭SOCKET成功");
									}
									String start = pingHttpGet(zaGameServerHttp, "GET");
									if (start!=null||start.contains("成功")) {
										System.out.println(df.format(new Date()) + ":重启SOCKET成功");
									}else {
										System.out.println(df.format(new Date()) + ":重启SOCKET发生异常");
									}
								} catch (Exception e) {
									System.out.println("重启tomcat异常,请查看错误信息。。。。。");
									System.out.println(e);

								}
							}

							try {
								System.err.println(df.format(new Date()) + "\t通讯正常");
								Thread.sleep(testIntervalTime * 1000);
							} catch (InterruptedException e) {
								e.printStackTrace();
							}
						}
					}
				});
			}
			// 执行任务前的延迟时间    执行周期
		}, 1000, Integer.MAX_VALUE);
	}

	private boolean ping() {
		/* 测试games项目是否连接正常 */
		String zaserver = pingHttpGet(zaGameServerHttp, "GET");
		if (zaserver == null || !"成功".contains(zaserver)) {
			return Boolean.FALSE;
		}
		System.err.println("一、测试games.zhuoan.servers.ui项目连接正常");

		/* 测试zagame项目是否连接正常 */
		String zagameMes = pingHttpGet(zaGameHttp, "GET");
		if (zagameMes == null) {
			return Boolean.FALSE;
		}
		System.err.println("二、测试zagame项目连接正常");

		// 扫描日志目录大小,并再一次限制文件总大小
		System.err.println("三、扫描日志目录大小,并再一次限制文件总大小");
		readfiles(logDir);

		return Boolean.TRUE;
	}

	private void readfiles(String logDir) {
		File directory = new File(logDir);
		File[] files = directory.listFiles();
		if (files == null) {
			return;
		}
		Long totalSize = 0L;
		// 如果日志文件大小总和 > 11G
		boolean flag = getLongSize(files, totalSize);
		if (flag) {
			for (int i = files.length; i > 0; i--) {
				if (files[i].getName().contains("application")) {
					//删除application文件
					boolean delete = files[i].delete();
					if (!delete) {
						continue;
					}
					flag = getLongSize(files, totalSize);
					if (!flag) {
						return;
					}
				}
			}
		}
	}

	private boolean getLongSize(File[] files, Long totalSize) {
		for (int i = 0; i < files.length; i++) {
			if (files[i].getName().contains("application")) {
				totalSize += files[i].length();
			}
		}
		Long size = totalSize / (1024 * 1024 * 1024);
		System.err.println("\tapplication日志共" + size + "Gib");
		return size > logSize;
	}

	private String pingHttpGet(String httpURL, String method) {
		HttpURLConnection connection = null;
		InputStream is;
		BufferedReader br;
		// 返回结果字符串
		String result = null;
		try {
			// 创建远程url连接对象
			URL url = new URL(httpURL);
			// 通过远程url连接对象打开一个连接,强转成httpURLConnection类
			connection = (HttpURLConnection) url.openConnection();
			// 设置连接方式:get
			connection.setRequestMethod(method);
			// 设置连接主机服务器的超时时间:15000毫秒
			connection.setConnectTimeout(15000);
			// 设置读取远程返回的数据时间:60000毫秒
			connection.setReadTimeout(60000);
			// 发送请求
			connection.connect();
			// 通过connection连接,获取输入流
			if (connection.getResponseCode() == 200) {
				is = connection.getInputStream();
				// 封装输入流is,并指定字符集
				br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
				// 存放数据
				StringBuffer sbf = new StringBuffer();
				String temp;
				while ((temp = br.readLine()) != null) {
					sbf.append(temp);
					sbf.append("\r\n");
				}
				result = sbf.toString();
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			assert connection != null;
			connection.disconnect();// 关闭远程连接
		}
		return result;
	}


	/**
	 * The entry point of application.
	 *
	 * @param args the input arguments
	 */
	public static void main(String[] args) throws FileNotFoundException {
		File file = new File(logDir);
		if (!file.exists() && !file.isDirectory()) {
			System.err.println("请确保项目先启动,即文件目录生成");
		}
		PrintStream out = new PrintStream(logDir + "/TomcatMonitor.log");
		System.setOut(out);
		/* 通过args搞事 */
		if (doSomthing(args)) {
			return;
		}
		/* 启动TOMCAT监控 */
		new TomcatMonitorUtil();
	}

	private static boolean doSomthing(String[] args) {
		try {
			switch (args[0]) {
				/* 关闭tomcat的参数 */
				case "close":
					Runtime.getRuntime().exec(shutdownBat);
					System.out.println(df.format(new Date()) + ": 手动关闭Tomcat");
					break;
				default:
					break;
			}
			return Boolean.TRUE;
		} catch (Exception e) {
			System.err.println("您可以通过发送参数来进行某些操作");
		}
		return Boolean.FALSE;
	}
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏陈树义

简单笔记

1、类的表面类型和实际类型 实例对象有两个类型:表面类型(Apparent Type)和实际类型(ActualType),表面类型是声明时的类型,实际类型是对象...

2595
来自专栏技术博文

PHP编程风格规范

本规范由 EasyChen 借鉴 SINA网络应用开发部《C++开发规范》和互动技术部《PHP4开发规范》,以及phpDocument规范 整理出的开发规范。我...

3647
来自专栏Danny的专栏

【SpringDataJPA】——SpringDataJPA入门实例

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huyuyang6688/article/...

1272
来自专栏小勇DW3

自己手动写代码实现数据库连接池

池:一个高级的集合体(集合存储元素 + 管理方式–>提高效率),是对外提供同一种类型对象的集合,如(线程池、数据库连接池)  特性:复用性(每条连接可重复使用)...

1503
来自专栏李航的专栏

Shell 主要逻辑源码级分析:SHELL 运行流程 (1)

分享一下在学校的时候分析shell源码的一些收获,帮助大家了解shell的一个工作流程,从软件设计的角度,看看shell这样一个历史悠久的软件的一些设计优点和缺...

2.1K0
来自专栏杂烩

大话HelloWord是如何出现在面前的-浅谈虚拟机运行流程

    初学Java,大都会用记事本写个Hello Word,然后用CMD编译出class文件,最后执行一下。当控制台输出Hello Word的时候,一个简单的...

1522
来自专栏好好学java的技术栈

并发基础篇(二):Thread类的API总结

1174
来自专栏Java编程技术

结合JVM源码谈Java类加载器

之前文章 Java 类加载器揭秘 从Java层面讲解了Java类加载器的原理,这里我们结合JVM源码在稍微深入讲解下。

1021
来自专栏ImportSource

来自JVM的一封ClassFile介绍信

我是一个class文件。我的内部是由一个被叫做ClassFile的structure组成。 我在jvm中占有很重要的地位,你可去看看jvm规范中我占了多少篇幅...

3768
来自专栏Albert陈凯

2018-04-06 JDK 新特性总览

JDK5新特性 自动装箱与拆箱 枚举 静态导入 可变参数(Varargs) 内省(introspector) 泛型(Generic) For-Eac...

3254

扫码关注云+社区

领取腾讯云代金券