批量URL测试工具(访问异常会发送邮件,并注册成window服务后台自动运行)

背景:因手上有大量项目需要维护,而一些旧项目经常有因为excel导出未限制导致内存溢出等等各种原因宕机问题未即时发现,因旧项目大多特别庞大且修改项目需要层层汇报审批评估工时安排计划等各种麻烦原因,因此临时添加一个定时测试系统url是否能访问,有访问异常网站第一时间发邮件通知我的工具

测试实现功能: 从json文件中读取站点名字以及url 的json字符串转map之后循环遍历进行测试url是否能访问,如果全都访问正常那么控制台直接输出结果,如果访问异常将发送邮件通知(收件人也需要在json文件中配置),因这个工具不只是我需要使用一些同事也想使用,且我是希望打包成jar之后直接运行java -jar命令就可用运行,但打包成jar后又要方便可以自定义修改网站名字以及url链接,因此项目中直接读取jar包同级目录下的文件(json文件名固定写死 url.json)

以下是源码:

package main;

import java.io.*;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;
import cn.hutool.extra.mail.Mail;
import cn.hutool.extra.mail.MailAccount;

/**
 * 1. 首先去url.json文件中读取信息 :
 * 		json文件中变量名为 “定时运行设置(1000等于1秒)” 的值设置定时的时间 ,例如: "定时运行设置(1000等于1秒)":  "600000", 
 * 		json文件中变量名为 “收件人” 的值设置收件人, 例如:   "收件人":  "97014247@qq.com"
 * 		其他则全是检查的站点名与URL
 * 
 * 	2. 如果检查完毕会生成检查结果,如果有异常会发送检查结果至邮件 ,
 * 
 * 	3. 因操作系统可能是英文版的原因,保存的文件格式为UTF-8, 不喜欢看英文的原因,cmd中运行命令打印有中文也有拼音,当中文乱码时看拼音就好了
 * 
 * */

public class TestUrl{
	public static String sendTo = "97014247@qq.com";//提供默认接收人
	public static int err = 0;
	public static StringBuilder htmlResult = new StringBuilder();
	public static int time = 0;
	public static Map<String, String> jsonMap = new HashMap<>();
	
	public static void main(String[] args) {
		try {
			getSendToAndTime();
			timer1();
		} catch (Exception e) {
			System.err.println("url.json外置文件读取失败。"+ e.getMessage());//同文件路径读取失败
			System.err.println("(url.json) Wài zhì wénjiàn du qǔ shībài。"+ e.getMessage());//同文件路径读取失败
		}
	}

	public static void timer1() {
		
		Timer nTimer = new Timer();
		nTimer.schedule(new TimerTask() {
			@SuppressWarnings("unused")
			public void run() {
				URL url;
				
				//每次运行都需要把以下三个初始化
				err = 0;
				htmlResult = new StringBuilder();//每次调用之后都需要初始化,否则内容累计 
				htmlResult.append("<H2>"+LocalDateTime.now()+"</H2><table><tr><th>站点名</th><th>URL</th><th>检查结果</th></tr>");
				System.out.println("\n--------------Url jiancha Kāishǐ  ---------------\n");
				System.out.println("\n--------------Url 检查开始  ---------------\n");
				for (String name : jsonMap.keySet()) {
					String var = jsonMap.get(name);
					if(name.equals("收件人") || name.equals("定时运行设置(1000等于1秒)"))continue; //因收件人、定时运行设置与链接放一块,因此如果是收件人就不进入判断
					try {
						url = new URL(var);
						//检查链接是否能正常访问
						InputStream in = url.openStream();	//openStream 输出数据,InputStream 从流中读取数据
						htmlResult.append("<tr><td>"+name+"</td><td><a href='"+var+"'>"+var+"</a></td><td>OK</td></tr>");
					} catch (Exception e1) {
						htmlResult.append("<tr><td>"+name+"</td><td><a href='"+var+"'>"+var+"</a></td><td style='color:red'>连接异常</td></tr>");
						err++;
						url = null;
					}
				}
				htmlResult.append("</table>");
				File file = new TestUrl().saveLog(htmlResult.toString());//必须new再调用,不能直接定义成静态方法,否则静态方法内的时间会一直保持不变,无论调用多少次都是相同的时间
				if(err>0) {
					huToolsendEmail("以下为链接检查异常记录:<br>"+ htmlResult.toString()+"<br>系统异常数:" + err
							+ "<br>请及时修复<strong style='color:red'>(修复方法:直接远程问题系统对应IP的服务器,重启即可)<strong>" , null);
					//huToolsendEmail("以下为链接检查异常记录,详情查看附件(附件建议使用浏览器打开):<br>"+ htmlResult.toString()+"<br>系统异常数:" + err+"请及时修复" , file); 不再发送文件
				}else {
					System.out.println("\n------Url cèshì jiéshù, jiancha yìcháng,Xiángqíng qǐng chákàn xìtǒng shēngchéng de HTML rìzhì (jiànyì shǐyòng liúlǎn qì dǎkāi)------"); //因为邮件中能识别br而输出到控制台只能使用\n换行
					System.out.println("\n------Url检查结束,检查异常,检查结果请查看邮件或系统生成的HTML日志(建议使用浏览器打开)!-----");
				}
			}
			
		},0, time);  // 0代表立即执行一次task,然后每隔time的毫秒数再执行一次task
	}

	// 需要hutool-all.jar  +  javax.mail.jar 否则会报错
	public static void huToolsendEmail(String text, File file) {
		try {
			System.setProperty("mail.mime.splitlongparameters", "false");//1.设置系统值 ---处理文件名乱码
			MailAccount account = new MailAccount();
			account.setHost("mx.apo.xxx.net"); //需自己改
			account.setPort(25);
			account.setFrom("xxxxx.com.hk");//需自己改
			Mail mail = Mail.create(account);
//			mail.setFiles(file);  不发送附件,否则附件太大时很慢,
			mail.setTos(sendTo); 
			mail.setTitle("系统运行监查异常邮件!");
			mail.setContent(text);
			mail.setHtml(true);
			mail.send();
			System.out.println("\n------Url检查结束,检查异常,检查结果请查看邮件或系统生成的HTML日志(建议使用浏览器打开)!-----");
			System.out.println("\n------Url cèshì jiéshù, jiancha yìcháng,Xiángqíng qǐng chákàn xìtǒng shēngchéng de HTML rìzhì (jiànyì shǐyòng liúlǎn qì dǎkāi)------");
		}catch (Exception e){
			System.out.println("\n邮件服务器连接失败" + e);
			System.out.println("\n------Yóujiàn fúwùqì liánjiē shībài------");
		}
	}
	
	public static void getSendToAndTime() throws Exception {
		String jsonStr = readJsonFile(System.getProperty("user.dir") + File.separator 	+ "url.json");
		jsonMap =  JSON.parseObject(jsonStr, new TypeReference<HashMap<String, String>>() {});
		if(!jsonMap.containsKey("收件人") || !jsonMap.containsKey("定时运行设置(1000等于1秒)")) {
			throw new Exception("请注意,收件人与定时运行设置不能为空---程序终止运行!(Qǐng zhùyì, shōu jiàn rén yǔ dìngshí yùnxíng shèzhì bùnéng wéi kōng---chéngxù zhōngzhǐ yùnxíng!)");
			
		}
		if(isBlank(jsonMap.get("收件人")) || isBlank(jsonMap.get("定时运行设置(1000等于1秒)"))) {
			throw new Exception("请注意,收件人与定时运行设置不能为空---程序终止运行!(Qǐng zhùyì, shōu jiàn rén yǔ dìngshí yùnxíng shèzhì bùnéng wéi kōng---chéngxù zhōngzhǐ yùnxíng!)");
		}
		
		for (String name : jsonMap.keySet()) {
			String var = jsonMap.get(name);
			if(name.equals("收件人")) {//因收件人与链接放一块,因此如果是收件人就不进入判断
				sendTo = var;
				continue;
			}
			if(name.equals("定时运行设置(1000等于1秒)")) {//因定时运行设置与链接放一块,因此如果是定时运行设置就不进入判断
				time = Integer.parseInt(var);
				if(time <1001) {
					throw new Exception("请注意,定时运行不能设置1000以下可能造成系统瘫痪---程序终止运行!(Qǐng zhùyì, dìngshí yùnxíng bùnéng shèzhì 1000 yǐxià kěnéng zàochéng xìtǒng tānhuàn---chéngxù zhōngzhǐ yùnxíng!)");
				}
				continue;
			}
		}
	}

	//读取json文件
	public static String readJsonFile(String fileName) throws Exception {
		String jsonStr = "";
		try {
			File jsonFile = new File(fileName);
			FileReader fileReader = new FileReader(jsonFile);
			Reader reader = new InputStreamReader(new FileInputStream(jsonFile), StandardCharsets.UTF_8);
			int ch;
			StringBuilder sb = new StringBuilder();
			while ((ch = reader.read()) != -1) {
				sb.append((char) ch);
			}
			fileReader.close();
			reader.close();
			jsonStr = sb.toString();
			return jsonStr;
		} catch (Exception e) {
			throw new Exception("json文件读取失败!---程序终止运行!");
		}
	}

	public File saveLog(String content) {
		String appPath = System.getProperty("user.dir") + File.separator+ "TestUrl" + LocalDate.now()+".html";//为了方便找到日志, 直接写入当前文件夹下
		 File file = new File(appPath );
	      try {
	         
	          if (!file.exists()) {
	              file.createNewFile();
	          }
//	          BufferedWriter br = new BufferedWriter(new FileWriter(file, true));
	          
	          OutputStreamWriter write = new OutputStreamWriter(new FileOutputStream(file), "UTF-8"); // 带格式,否则中文保存会乱码
			  BufferedWriter br = new BufferedWriter(write);
	          
	          br.write(content);
	          br.newLine();
	          br.flush();
	          br.close();
	          return file;
	      } catch (Exception e) {
	          e.printStackTrace();
	      }
		return file;
	}
	
    public static boolean isBlank(CharSequence cs) {
        int strLen;
        if (cs != null && (strLen = cs.length()) != 0) {
            for(int i = 0; i < strLen; ++i) {
                if (!Character.isWhitespace(cs.charAt(i))) {
                    return false;
                }
            }

            return true;
        } else {
            return true;
        }
    }

}

url.json内容(简单的{key: value}格式):

{
  "xxx-Nginx":"http://xxxxx/xxx",
  "xxx-8080":"http://xxx:8080/xxx",
  "xxx-8081":"http://xxx:8081/xxx",
 "xxx熔断器": "http://xxx:8101/hystrix",
 "xxx-Jenkins": "http://xxx:8080/login",
"xxxEureka服务发现": "http://xxx:8761/",

   "收件人":  "He.Wen.Jun@esl.epson.com.hk"
}

下图是我的项目结构:

相关jar包下载请点击

以下是注册成服务:

1.首先使用我一贯使用的一键注册:

以上命令保存后在nssm同目录下双击运行,的确是预料般的正常注册,但是启动报错,报错信息如下:


Windows could not start the TestUrl service on Local Computer.
The service did not return an error.  This could be an internal Windows error or an internal service error.
If the problem persists, contact your system administrator.

 解决办法:

        输入命令nssm remove TestUrl删除服务,重新注册,不能简单的一键注册,手动注册,步骤如下:

不再把命令行写到注册里面去,先把上图文件保存到nssm同路径下,然后双击运行,在cmd运行时会弹窗如下:

 选择需要注册成服务的文件(运行jar命令的bat),然后 输入描述,点击Install service即可

 之后在服务列表再次双击刚刚注册的 TestUrl,运行成功,再也没有报错信息了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

往事不堪回首..

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值