一、设计目的:当调用某个方法或者请求时,想忽略个别调用失败而抛出的异常。
二、设计代码
package com.jupiter.log4j2.test;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author Jupiter
* @description 异常频控判断类
* @date 2018年12月7日
*/
public class ExceptionCheck {
// 五分钟内
private static final int timeSpan = 300;
// 一个方法发生异常的次数限制
private static final int countLimit = 5;
private static ConcurrentHashMap<String, Integer> exceptionMap = new ConcurrentHashMap<String, Integer>();
/**
* @description 在要处理的方法中调ExceptionCheck.exceptionCheck()判断是否需要打印错误日志
* @date 2018年12月7日
* @return boolean 即打不打出异常日志
*/
public static synchronized boolean exceptionCheck() {
// 获取当前时间
Date currentDate = new Date();
int count = 0;
String searchKey = dateTimeToStr(currentDate, "yyyyMMddHHmm");
if(exceptionMap.containsKey(searchKey)) {
//同一分钟内,捕捉到异常,异常发生频率计数+1
exceptionMap.put(searchKey, exceptionMap.get(searchKey) + 1);
} else {
exceptionMap.put(searchKey, 1);
}
// 删除5分钟之前的异常发生频率监控计数
for (String key : exceptionMap.keySet()) {
if(strToDateTime(searchKey, "yyyyMMddHHmm").getTime() - strToDateTime(key, "yyyyMMddHHmm").getTime() >= timeSpan * 1000) {
exceptionMap.remove(key);
} else {
count += exceptionMap.get(key);
}
}
return count >= countLimit;
}
/**
* @description 时间字符串转时间
* @date 2018年12月7日
*/
private static Date strToDateTime(String searchKey, String pattern) {
LocalDateTime date = LocalDateTime.parse(searchKey, DateTimeFormatter.ofPattern(pattern));
ZonedDateTime zdt = date.atZone(ZoneId.systemDefault());
return Date.from(zdt.toInstant());
}
/**
* @description 时间转时间字符串
* @date 2018年12月7日
*/
private static String dateTimeToStr(Date date, String pattern) {
Instant instant = date.toInstant();
ZoneId zoneId = ZoneId.systemDefault();
LocalDateTime localDateTime = instant.atZone(zoneId).toLocalDateTime();
return localDateTime.format(DateTimeFormatter.ofPattern(pattern));
}
}
测试片段:
try{
...
}catch (Exception e){
boolean ifPrint = ExceptionChecker.exceptionCheck();
if(ifPrint) {
log.error("多次发送post请求失败,url:[{}],请求内容:[{}],异常:[{}]",url,json,e);
}
}