一.实现数据库连接监控
描述:通过定时对数据库进行连接操作实现监控数据库的目的,当数据库连接失败时进行预警通知.
第一步: 配置数据库信息并测试连接
class MysqlListenerUtil{
public boolean mysqlMonitor() {
//数据库加载器
String driverName="com.mysql.cj.jdbc.Driver";
//端口号以及数据库名称
String url="jdbc:mysql://localhost:3306/xxxxx?useUnicode=true&characterEncoding=UTF-8&useSSL=false";
//用户名
String userName="root";
//用户密码
String userPwd="root";
//数据库连接成功
boolean isSuccess = false;
try {
Class.forName(driverName);
Connection dbConn = DriverManager.getConnection(url,userName,userPwd);
isSuccess = true;
System.out.println("连接数据库成功"+dbConn);
}catch (Exception e) {
if(e.toString().contains("Too many connections")){
String msg = "Too many connections";
System.out.println("数据库连接失败:"+msg);
}
}
return isSuccess;
}
}
返回结果:
连接成功时返回:
连接失败时返回:
第二步:配置redis数据库
redis学习请参考:Java使用redis
封装redis工具类:
public class RedisConnectionUtil {
private static Jedis jedis;
static {
jedis = new Jedis("localhost");
//jedis.auth("password");//若配置了权限密码,则添加此行进行设置
}
/**
* 关闭jedis
*/
public void close(){
jedis.close();
}
/**
* 清空数据
*/
public String flushDB(){
return jedis.flushDB();
}
/**
* 查询某个键是否存在
* @param fieldName 键名
* @return
*/
public boolean isExist(String fieldName){
return jedis.exists(fieldName);
}
/**
* 新增键值对
* @param key
* @param value
* @return
*/
public String setKV(String key,String value){
return jedis.set(key, value);
}
/**
* 查询值
* @param key
* @return
*/
public String getKV(String key){
return jedis.get(key);
}
/**
* 获取原值,更新为新值
* @param key
* @param value
* @return
*/
public String getsetKV(String key,String value){
return jedis.getSet(key, value);
}
/**
* 查询系统中所有的键
* @return
*/
public Set<String> selectAllKeys(){
return jedis.keys("*");
}
/**
* 删除键
* @param key
* @return
*/
public Long delKey(String key){
return jedis.del(key);
}
/***
* 散列
* @return
*/
public String setHMap(String key, Map<String,String> map){
return jedis.hmset(key, map);
}
/**
* 往散列中添加数据
* @param key
* @param field
* @param value
* @return
*/
public Long sethValue(String key, String field, String value){
return jedis.hset(key,field,value);
}
/**
* 获取散列中所有的键值对
* @param key
* @return
*/
public Map<String,String> hgetAllKV(String key){
return jedis.hgetAll(key);
}
/**
* 获取散列中所有的键
* @param key
* @return
*/
public Set<String> getHKey(String key){
return jedis.hkeys(key);
}
/**
* 获取散列中所有的值
* @param key
* @return
*/
public List<String> gethval(String key){
return jedis.hvals(key);
}
/**
* 将field保存的值加上一个整数,如果field不存在则添加field:
* @param key
* @param field
* @param value
* @return
*/
public Long hincrBy(String key,String field,int value){
return jedis.hincrBy(key,field,value);
}
/**
* 获取散列中的值
* @param key
* @param field
* @return
*/
public List<String> hmGet(String key, String... field){
List<String> list = new ArrayList<>();
for (String s:field) {
list = jedis.hmget(key, s);
}
return list;
}
/**
* 数字减一
* @param key
*/
public void decr(String key) {
jedis.decr(key);
}
}
第三步:当数据库连接失败时发送预警信息
/**
* 当数据库连接失败时发送数据库预警信息
*/
public void sendMysqlEarlyWarning() throws Exception {
//邮件发送服务
//SendMailServiceImpl sendMailService = new SendMailServiceImpl();
//数据库名
String devName = "数据库";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//发送日期
String submitTime = simpleDateFormat.format(new Date());
if (Integer.parseInt(jedis.getKV("mysql_earlywarning_times")) != 0){
List<String> list = jedis.hmGet("contact", "contact_count");
int contactCount = 0;
for (String i:list) {
contactCount = Integer.parseInt(i);
}
for (int i = 1; i <= contactCount; i++) {
List<String> MethodList = jedis.hmGet("contact", "contact_method"+i+"");
for (String index: MethodList) {
if (index.equals("contact_e_mail")){
List<String> eMailList = jedis.hmGet("contact", "" + index+""+i+"");
String eMail = eMailList.get(0);
//邮件通知
sendMailService.sendSimpleTextMailActual("设备" + devName + "掉线通知", "您的" + devName + "于" + submitTime + "掉线,请关注", new String[]{"" + eMail + ""});
}else if (index.equals("contact_phone")){
List<String> phoneList = jedis.hmGet("contact", "" + index+""+i+"");
String phone = phoneList.get(0);
//短信通知
SMSsendUtil.SMSsend(devName,submitTime,phone);
}
}
}
jedis.decr("mysql_earlywarning_times");
System.out.println("mysql_earlywarning_times"+jedis.getKV("mysql_earlywarning_times"));
TimeUnit.MINUTES.sleep(1);
}else if (Integer.parseInt(jedis.getKV("mysql_earlywarning_times")) == 0){
System.out.println("mysql_earlywarning_times为0,不再发送预警信息");
jedis.close();
}
}
第四步:循环监听
@Override
public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
//连接本地的 Redis 服务
jedis.setKV("mysql_earlywarning_times", "5");
System.out.println("mysql_earlywarning_times"+jedis.getKV("mysql_earlywarning_times"));
EarlyWarningContacts contacts = new EarlyWarningContacts();
ScheduledExecutorService scheduler = new ScheduledThreadPoolExecutor(1);
scheduler.scheduleAtFixedRate(() -> {
try {
System.out.println("----------------Mysql监听系统---------------");
//启动数据库连接监听
boolean res = new MysqlListenerUtil().mysqlMonitor();
if (!res){
sendMysqlEarlyWarning();
}else {
System.out.println("数据库连接成功,请等待预警系统启动");
jedis.close();
}
} catch (Exception e) {
e.printStackTrace();
}
//启动时延迟20s,周期1分钟执行一次=====>若周期时间小于线程休眠时间,则会出现定时器创建新线程导致预警多发的错误!
}, 20, 60, TimeUnit.SECONDS);
}
二.短信预警
此处使用的时阿里云的短信服务,可以查看阿里云官方文档了解调用方法:阿里云短信服务调试
实现代码:
public class SMSsendUtil {
/**
* 使用AK&SK初始化账号Client
* @param accessKeyId
* @param accessKeySecret
* @return Client
* @throws Exception
*/
public static com.aliyun.dysmsapi20170525.Client createClient(String accessKeyId, String accessKeySecret) throws Exception {
Config config = new Config()
// 您的AccessKey ID
.setAccessKeyId(accessKeyId)
// 您的AccessKey Secret
.setAccessKeySecret(accessKeySecret);
// 访问的域名
config.endpoint = "dysmsapi.aliyuncs.com";
return new com.aliyun.dysmsapi20170525.Client(config);
}
//参数根据模板需求进行添加
public static void SMSsend(String mtname,String submittime,String phone) throws Exception {
com.aliyun.dysmsapi20170525.Client client = SMSsendUtil.createClient("accessKeyId", "accessKeySecret");
SendSmsRequest sendSmsRequest = new SendSmsRequest()
.setPhoneNumbers(""+phone+"")
.setSignName("短信签名名称")
.setTemplateCode("短信模板ID")
.setTemplateParam("{\"mtname\":\""+mtname+"\", \"submittime\":\""+submittime+"\"}");
// 复制代码运行请自行打印 API 的返回值
SendSmsResponse sendSmsResponse = client.sendSms(sendSmsRequest);
//错误代码
System.out.println(sendSmsResponse.body.code);
}
}
三.邮件通知
具体代码实现:
@Service
@Slf4j
public class SendMailServiceImpl implements SendMailService {
//本身邮件的发送者,来自邮件配置
@Value("${spring.mail.username}")
private String userName;
@Autowired(required = false)
private JavaMailSender mailSender;
/**
* 发送邮件功能具体实现类
* @package_name :com.kkzh.earlywarning.service.impl
* @date: 2021-06-1512:23
* @name: SendMailServiceImpl
* @user:cc
*/
@Override
public void sendSimpleTextMailActual(String subject, String content, String[] toWho) {
//检验参数:邮件主题、收件人、邮件内容必须不为空才能够保证基本的逻辑执行
if(subject == null||toWho == null||toWho.length == 0||content == null){
log.error("邮件-> {} 无法继续执行,因为缺少基本的参数:邮件主题、收件人、邮件内容",subject);
throw new RuntimeException("模板邮件无法继续发送,因为缺少必要的参数!");
}
log.info("开始发送简单文本邮件:主题->{},收件人->{}",subject,toWho);
//创建一个简单邮件信息对象
SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
//设置邮件的基本信息
handleBasicInfo(simpleMailMessage,subject,content,toWho);
//发送邮件
mailSender.send(simpleMailMessage);
log.info("发送邮件成功: 主题->{}",subject,toWho);
}
@Override
public void handleBasicInfo(SimpleMailMessage simpleMailMessage, String subject, String content, String[] toWho) {
//设置发件人
simpleMailMessage.setFrom(userName);
//设置邮件的主题
simpleMailMessage.setSubject(subject);
//设置邮件的内容
simpleMailMessage.setText(content);
//设置邮件的收件人
simpleMailMessage.setTo(toWho);
}
}
注: 邮件通知服务需要在配置文件中进行配置,否则就无法发送短信通知
mail:
#邮箱服务器地址,各大运营商不同(此处发送方邮箱以QQ为例)
host: smtp.qq.com
#用户名
username: xxxxxxxxx@qq.com #该qq邮箱是发送方的邮箱
#密码,如果是qq的,可以申请临时授权码,临时授权码在QQ邮箱中申请
password: 临时授权码
default-encoding: UTF-8
#以谁来发送邮件
fromMail.addr: xxxxxxx@qq.com
#加下面这两个配置才能通过qq给qq及其他邮箱(如163等)发邮件
protocol: smtp #邮件协议
properties.mail.smtp.ssl.enable: true
四.数据库中数据表新增数据监控
1.描述: 对数据库的某一个表进行监控,当该表中最新的一条数据小于设定的时间时进行设备掉线提醒.
2.具体实现:
- 获取监控表中所有信息
- 根据表中的监控表名获取最新的数据的创建时间
- 根据监控信息中的预警时间与获取到的创建时间比较,若创建时间小于预警时间,则报警
- 根据监控信息中的联系人id获取预警的方式 邮箱|短信
- 发送预警通知并创建预警信息以存储 预警规定五次,每一分钟执行一次查询,并决定是否发送通知
3.具体代码:
public Map<String, Object> earlyWarning(EarlyWarningMonitor monitor) throws Exception {
//1.获取监控表中所有信息
List<EarlyWarningMonitor> monitorList = monitorService.queryList(monitor);
//用于存储监控信息中的数据表名
List<String> list = new ArrayList<>();
//存储(tablename,create_time)键值对,便于后期匹配
Map<String, String> monitor_map = monitorList.stream().collect(
Collectors.toMap(EarlyWarningMonitor::getMonitor_table_name,
EarlyWarningMonitor::getEarlywarning_time));
//2.根据表中的监控表名获取最新的数据的创建时间
for (EarlyWarningMonitor monitors : monitorList) {
//切割字符串的时候,如果没有符合的就会把他处理空间为一的数组
list.add(monitors.getMonitor_table_name());
}
list.remove("");
//保存发布邮箱的数据
Map<String, Map<String, Object>> mapMap = new HashMap<>();
//2.1、查询数据库对应数据表最新一条数据,获取其创建时间
for (String tablename : list) {
if (monitor_map.containsKey(tablename)) {
//2.2、将获取到的时间转换为时间戳
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String maxTime = simpleDateFormat.format(tableNamesService.selectMaxTime(tablename));
long createTime = StringToTimeUtil.StringToTime(maxTime);
//2.3、根据表名匹配监控信息中的预警时间
String EarlyWarningTime = monitor_map.get(tablename);
long earlywarningTime = StringToTimeUtil.StringToTime(EarlyWarningTime);
long now_time = System.currentTimeMillis();
//3.根据监控信息中的预警时间与获取到的创建时间比较,若创建时间小于预警时间,则报警
if (earlywarningTime > createTime && now_time >= earlywarningTime) {
//3.1、再次遍历list,通过表名与预警时间匹配对应监控数据中的联系人id,从而获取到联系人信息
for (EarlyWarningMonitor contact_monitor : monitorList) {
if (contact_monitor.getMonitor_table_name().equals(tablename) && contact_monitor.getEarlywarning_time().equals(EarlyWarningTime)) {
//4.根据监控信息中的联系人id获取预警的方式 邮箱|短信
//预警信息中设备名称 mtname
String mtname = contact_monitor.getDevice_name();
//联系人id
int contact_id = contact_monitor.getContact_id();
//监控信息表id
int monitor_id = contact_monitor.getEarlywarning_monitor_id();
EarlyWarningContacts earlyWarningContacts = contactsService.detailquery(contact_id);
//联系人邮箱
final String contact_e_mail = earlyWarningContacts.getContact_e_mail();
//联系人手机
final String contact_phone = earlyWarningContacts.getContact_phone();
//4.1、查询联系人联系方式 邮件或者短信预警
//邮箱发送
if (contact_e_mail != null && !"".equals(contact_e_mail)) {
//5.发送预警通知并创建预警信息以存储 预警规定五次,每一分钟执行一次查询,并决定是否发送通知
EarlyWarningMessage warningMessage = messageService.detailquery(contact_id, monitor_id);
//执行预警信息创建前进行数据查询,避免重复记录
if (warningMessage == null) {
//5.发送预警通知并创建预警信息以存储
//sendMailService.sendSimpleTextMailActual("设备" + mtname + "掉线通知", "您的" + mtname + "于" + maxTime + "掉线,请关注", new String[]{"" + contact_e_mail + ""});
createMessage(
contact_id,
contact_monitor.getEarlywarning_monitor_id(),
(byte) 0,
6,
simpleDateFormat.format(new Date()),
simpleDateFormat.format(new Date())
);
warningMessage = messageService.detailquery(contact_id,monitor_id);
}
if (warningMessage != null) {
int[] earlywarning_times = {warningMessage.getEarlywarning_times()};
//不等于空执行邮件发送 map保存要预警的表
Map<String, Object> map = new HashMap<>();
map.put("warningMessage", warningMessage);
map.put("earlywarning_times[0]", earlywarning_times[0]);
map.put("mtname", mtname);
map.put("maxTime", maxTime);
map.put("contact_e_mail", contact_e_mail);
map.put("contact_phone",null);
mapMap.put(mtname, map);
}
} else {
//短信发送
if (contact_phone != null && !"".equals(contact_phone)) {
//5.发送预警通知并创建预警信息以存储 预警规定五次,每一分钟执行一次查询,并决定是否发送通知
EarlyWarningMessage warningMessage = messageService.detailquery(contact_id, monitor_id);
//执行预警信息创建前进行数据查询,避免重复记录
if (warningMessage == null) {
//5.发送预警通知并创建预警信息以存储
//SMSsendUtil.SMSsend(mtname, maxTime, contact_phone);
createMessage(
contact_id,
monitor_id,
(byte) 0,
6,
simpleDateFormat.format(new Date()),
simpleDateFormat.format(new Date())
);
//重新赋值
warningMessage = messageService.detailquery(contact_id, monitor_id);
}
if (warningMessage != null) {
int[] earlywarning_times = {warningMessage.getEarlywarning_times()};
//不等于空执行邮件发送 map保存要预警的表
Map<String, Object> map = new HashMap<>();
map.put("warningMessage", warningMessage);
map.put("earlywarning_times[0]", earlywarning_times[0]);
map.put("mtname", mtname);
map.put("maxTime", maxTime);
map.put("contact_e_mail", null);
map.put("contact_phone",contact_phone);
mapMap.put(mtname, map);
}
}
}
}
}
}
}
//要发送的邮件数据
sends(mapMap);
}
return MapControll.getInstance().success().put("data", monitorList).getMap();
}
/**
* 预警信息创建
*
* @param contact_id
* @param monitor
* @param earlyWarning_deal
* @param create_time
* @param update
*/
void createMessage(Integer contact_id, Integer monitor, Byte earlyWarning_deal, int earlywarning_times, String create_time, String update) {
EarlyWarningMessage earlyWarningMessage = new EarlyWarningMessage()
.setContact_id(contact_id)
.setMonitor_id(monitor)
.setEarlywarning_deal(earlyWarning_deal)
.setEarlywarning_times(earlywarning_times)
.setCreate_time(create_time)
.setUpdate_time(update);
messageService.create(earlyWarningMessage);
}
/**
* 预警信息更新
* @param earlywarning_message_id
* @param earlywarning_times
* @param update
*/
void updateMessage(Integer earlywarning_message_id, int earlywarning_times, String update) {
EarlyWarningMessage earlyWarningMessage = new EarlyWarningMessage()
.setEarlywarning_message_id(earlywarning_message_id)
.setEarlywarning_times(earlywarning_times)
.setUpdate_time(update);
messageService.updatetimes(earlyWarningMessage);
}
//全局map 控制
private Map<String, String> mapOnlyKey = new HashMap<>();
@SneakyThrows
public void sends(Map<String, Map<String, Object>> map) {
List<Thread> list = new ArrayList<>();
for (String key : map.keySet()) {
Map<String, Object> mapTemp = map.get(key);
EarlyWarningMessage warningMessage = (EarlyWarningMessage) mapTemp.get("warningMessage");
int[] earlywarning_times = {(int) mapTemp.get("earlywarning_times[0]")};
String mtname = (String) mapTemp.get("mtname");
String maxTime = (String) mapTemp.get("maxTime");
String contact_e_mail = (String) mapTemp.get("contact_e_mail");
String contact_phone = (String) mapTemp.get("contact_phone");
//创建线程对象
Thread thread = new Thread(new Runnable() {
@SneakyThrows
@Override
public synchronized void run() {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//判断是否有线程正在执行该表的预警
if (!ObjectUtils.isEmpty(mapOnlyKey.get(mtname))) {
return;
} else {
//没有就执行该线程
mapOnlyKey.put(mtname, mtname);
}
if (earlywarning_times[0] == 1) {
//移除map中数据。避免重新预警该表时,占用该表资源
mapOnlyKey.remove(mtname);
return;
} else {
int i = earlywarning_times[0];
while (i > 0) {
EarlyWarningMessage message_deal = messageService.detailquery(warningMessage.getEarlywarning_message_id());
if (i == 1) {
updateMessage(
warningMessage.getEarlywarning_message_id(),
i,
simpleDateFormat.format(new Date())
);
return;
}
if (message_deal.getEarlywarning_deal() == 1) {
break;
} else {
updateMessage(
warningMessage.getEarlywarning_message_id(),
i,
simpleDateFormat.format(new Date())
);
//5.发送预警通知并创建预警信息以存储
if(contact_e_mail != null && !"".equals(contact_e_mail)){
sendMailService.sendSimpleTextMailActual("设备" + mtname + "掉线通知", "您的" + mtname + "于" + maxTime + "掉线,请关注", new String[]{"" + contact_e_mail + ""});
}else if (contact_phone != null && !"".equals(contact_phone)){
SMSsendUtil.SMSsend(mtname, maxTime, contact_phone);
}
}
i--;
earlywarning_times[0]--;
//每执行一次预警通知,休眠1分钟 休眠时间综合小于定时任务时间
TimeUnit.MINUTES.sleep(1);
}
}
}
});
list.add(thread);
}
//启动保存的线程
for (int i = 0; i < list.size(); i++) {
list.get(i).start();
}
}
4.字符串转时间戳与日期工具类
public class StringToTimeUtil {
public static long StringToTime(String time){
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
long targetTime = 0;
try {
Date targetDate = simpleDateFormat.parse(time);
targetTime = targetDate.getTime();
} catch (ParseException e) {
e.printStackTrace();
}
return targetTime;
}
public static Date StringToTime(long time) throws ParseException {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date targetDate = simpleDateFormat.parse(simpleDateFormat.format(time));
return targetDate;
}
}
五.API请求监控预警
1.描述: 对访问本系统的请求进行监控,若在规定时间内没有请求操作则预警
2.具体实现:
- 接口请求时间记录
public class ApiRequestUtil{
public void start() {
try {
Jedis jedis = new Jedis("localhost");
//服务器端口号 9003
//建立监听 服务器实例化serverSocket对象
ServerSocket serverSocket = new ServerSocket(9003);
while (true) {
//建立连接,若没有请求则一直等待
Socket socket = serverSocket.accept();
InputStream in = socket.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in));
String line = null;
//获取相应信息
while ((line = bufferedReader.readLine())!=null){
System.out.println(line);
if (line.contains("Host")){
String replace = line.replace("Host:", "");
//将需要信息存入redis
jedis.set("Host",replace);
jedis.set("time", String.valueOf(System.currentTimeMillis()));
}
if (line.isEmpty()){
break;
}
}
socket.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args){
new ApiRequestUtil().start();
}
}
- 掉线判断工具类:
public class ApiListenerUtil {
public boolean apiMonitor() {
RedisConnectionUtil jedis = new RedisConnectionUtil();
//时间间隔
long intervalTime = 10 * 60 * 1000;
//当前时间
Long nowTime = System.currentTimeMillis();
//api请求时间
Long apiRequestTime = Long.parseLong(jedis.getKV("time"));
//当前时间与api请求时间的时间差
long timeDiff = nowTime - apiRequestTime;
//是否掉线
boolean isTimeOut = false;
//当时间差大于时间间隔时,发出预警
if (timeDiff > intervalTime){
isTimeOut = true;
}
return isTimeOut;
}
}
- 预警信息发送实现:
public void sendApiEarlyWarning() throws Exception {
//请求名
String devName = "Api请求";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//发送日期
String submitTime = simpleDateFormat.format(new Date());
RedisConnectionUtil jedis = new RedisConnectionUtil();
if (Integer.parseInt(jedis.getKV("api_earlywarning_times")) != 0){
List<String> list = jedis.hmGet("contact", "contact_count");
int contactCount = 0;
for (String i:list) {
contactCount = Integer.parseInt(i);
}
for (int i = 1; i <= contactCount; i++) {
List<String> MethodList = jedis.hmGet("contact", "contact_method"+i+"");
for (String index: MethodList) {
if (index.equals("contact_e_mail")){
List<String> eMailList = jedis.hmGet("contact", "" + index+""+i+"");
String eMail = eMailList.get(0);
//邮件通知
sendMailService.sendSimpleTextMailActual("设备" + devName + "掉线通知", "您的" + devName + "于" + submitTime + "掉线,请关注", new String[]{"" + eMail + ""});
}else if (index.equals("contact_phone")){
List<String> phoneList = jedis.hmGet("contact", "" + index+""+i+"");
String phone = phoneList.get(0);
//短信通知
SMSsendUtil.SMSsend(devName,submitTime,phone);
}
}
}
jedis.decr("api_earlywarning_times");
System.out.println("api_earlywarning_times"+jedis.getKV("api_earlywarning_times"));
TimeUnit.MINUTES.sleep(1);
}else if (Integer.parseInt(jedis.getKV("api_earlywarning_times")) <= 0){
System.out.println("api_earlywarning_times为0,不再发送预警信息");
jedis.close();
}
}
- 循环监听:
public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
EarlyWarningContacts contacts = new EarlyWarningContacts();
//连接本地的 Redis 服务
RedisConnectionUtil jedis = new RedisConnectionUtil();
jedis.setKV("api_earlywarning_times", "1");
System.out.println("api_earlywarning_times"+jedis.getKV("api_earlywarning_times"));
ScheduledExecutorService scheduler = new ScheduledThreadPoolExecutor(1);
scheduler.scheduleAtFixedRate(() -> {
try {
//启动Api请求监听
System.out.println("------------Api监听系统---------------");
boolean isTimeOut = new ApiListenerUtil().apiMonitor();
if (isTimeOut){
sendApiEarlyWarning();
}else {
System.out.println("Api请求正常!");
}
} catch (Exception e) {
e.printStackTrace();
}
//启动时延迟30s,周期1分钟执行一次=====>若周期时间小于线程休眠时间,则会出现定时器创建新线程导致预警多发的错误!
}, 30, 60, TimeUnit.SECONDS);
}
六.预警联系人缓存
当数据库连接不上时,想要发送预警就无法通过数据库获取预警联系人的信息,所以在之前可以将需要的信息从数据库中取出并存入redis数据库,在数据库挂掉后可以通过读取redis中储存的信息进行预警通知
代码实现:
public Map<String, String> contactList(EarlyWarningContacts contacts){
//建立redis连接
RedisConnectionUtil jedis = new RedisConnectionUtil();
//清空数据库缓存
//jedis.flushDB();
List<EarlyWarningContacts> contactsList = service.queryList(contacts);
Map<String,String> contactMap = new HashMap<>();
int i = 1;
for (EarlyWarningContacts c:contactsList) {
contactMap.put("name"+i+"",c.getContact_name());
//缓存联系信息
if (c.getContact_e_mail() == null || "".equals(c.getContact_e_mail())){
//联系方式
contactMap.put("contact_method"+i+"","contact_phone");
//详情
contactMap.put("contact_phone"+i+"",c.getContact_phone());
}else if (c.getContact_phone() == null || "".equals(c.getContact_phone())){
contactMap.put("contact_method"+i+"","contact_e_mail");
contactMap.put("contact_e_mail"+i+"",c.getContact_e_mail());
}
++i;
}
contactMap.put("contact_count", String.valueOf(i-1));
jedis.setHMap("contact", contactMap);
return jedis.hgetAllKV("contact");
}
以上就是关于预警系统的全部开发步骤,后续有补充再添加.