一.实现数据库连接监控

描述:通过定时对数据库进行连接操作实现监控数据库的目的,当数据库连接失败时进行预警通知.
第一步: 配置数据库信息并测试连接

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");
    }

以上就是关于预警系统的全部开发步骤,后续有补充再添加.

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐