xxl-job 实现email发送警告的代码解析(一行一行代码解读)

2022-08-03 17:32:32 浏览数 (1)

目录

  • 1 相关代码位置
  • 2 接口JobAlarm
  • 3 email 警告
  • 4 JobAlarmer

1 相关代码位置

我们下载了xxl-job 的源码,找到这个alarm 目录,这个目录里面的代码就是整个项目和发送警告相关的代码,alarm 中文翻译就是警告;

整个项目里面只有alarm 目录下有关于使用email发送警告的代码

2 接口JobAlarm

这个目录下一共有3个文件,首先是这个接口,这个接口的源码是:

为什么要使用接口,因为对于告警信息进行预报,不仅仅我们可以发送email,而且还可以发送qq,微信,短信等其他的通讯;所以只要重新写一个类,实现这个接口,就可以了,当前的xxl-job,这个项目,只是支持email告警,我们可以扩展,相当于写了接口,就是可拓展性强,便于维护。

3 email 警告

我们要实现email进行警告,所以写一个类,实现上面的接口就可以了,xxl-job 这个项目就是只是 支持email,所以后续我们想要自己实现短信,就自己写一个类,实现这个接口,重写里面的方法就可以了

现在解读xxl-job 源码里面,还有email进行发送警告的代码:

看这个实现类 里面的东西:

源码里面的每一行代码,都做 了注释,直接看下面的源码

代码语言:javascript复制
package com.xxl.job.admin.core.alarm.impl;

import com.xxl.job.admin.core.alarm.JobAlarm;
import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
import com.xxl.job.admin.core.model.XxlJobGroup;
import com.xxl.job.admin.core.model.XxlJobInfo;
import com.xxl.job.admin.core.model.XxlJobLog;
import com.xxl.job.admin.core.util.I18nUtil;
import com.xxl.job.core.biz.model.ReturnT;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;

import javax.mail.internet.MimeMessage;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**
 * job alarm by email
 *  通过电子邮件通知 告警信息
 * @author xuxueli 2020-01-19
 */
@Component
public class EmailJobAlarm implements JobAlarm {

//    定义当前的  日志对象
    private static Logger logger = LoggerFactory.getLogger(EmailJobAlarm.class);

    /**
     * fail alarm
     *  失败报警 逻辑
     *  开始进行  报警的逻辑
     * @param jobLog
     */
    @Override
    public boolean doAlarm(XxlJobInfo info, XxlJobLog jobLog){

//        定义报警结果状态
        boolean alarmResult = true;

        // send monitor email
        if (info!=null && info.getAlarmEmail()!=null && info.getAlarmEmail().trim().length()>0) {
            // 如果 任务信息不为空,报警邮件不为空
            // alarmContent  报警内容
            String alarmContent = "Alarm Job LogId="   jobLog.getId();  // 记录日志id


            if (jobLog.getTriggerCode() != ReturnT.SUCCESS_CODE) {
//                如果 日志的 调度结果 不成功  ,内容保存 调度-日志
                alarmContent  = "<br>TriggerMsg=<br>"   jobLog.getTriggerMsg();
            }



            if (jobLog.getHandleCode()>0 && jobLog.getHandleCode() != ReturnT.SUCCESS_CODE) {
//               如果 执行-状态  不为空,内容保存  执行-日志具体结果信息
                alarmContent  = "<br>HandleCode="   jobLog.getHandleMsg();
            }



            // email info

//            根据项目 id  查询出  执行器(项目)
            XxlJobGroup group = XxlJobAdminConfig.getAdminConfig().getXxlJobGroupDao().load(Integer.valueOf(info.getJobGroup()));

//          警告信息  发送人
            String personal = I18nUtil.getString("admin_name_full");//  值为这个:  分布式任务调度平台XXL-JOB
//          告警信息  标题
            String title = I18nUtil.getString("jobconf_monitor"); //  值为这个:任务调度中心监控报警

//            根据模板,填充信息
            String content = MessageFormat.format(loadEmailJobAlarmTemplate(),
                    group!=null?group.getTitle():"null",  // 项目名称
                    info.getId(),   // 任务id
                    info.getJobDesc(),// 任务 描述
                    alarmContent); // 报警内容

//            多个  报警邮件
            Set<String> emailSet = new HashSet<String>(Arrays.asList(info.getAlarmEmail().split(",")));


            for (String email: emailSet) {

                // 遍历多个报警邮件
                // make mail
                try {

                    //  创建邮件发送者 对象
                    MimeMessage mimeMessage = XxlJobAdminConfig.getAdminConfig().getMailSender().createMimeMessage();
                    //  创建 邮件发送线程
                    MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
//                    从配置文件里面获取自己配置的发送者 的邮箱,发送者的姓名
                    helper.setFrom(XxlJobAdminConfig.getAdminConfig().getEmailFrom(), personal);
//                    将邮件发送给谁
                    helper.setTo(email);
//                    发送的标题
                    helper.setSubject(title);
//                    发送的内容
                    helper.setText(content, true);
  //                  进行发送
                    XxlJobAdminConfig.getAdminConfig().getMailSender().send(mimeMessage);
                } catch (Exception e) {
                    logger.error(">>>>>>>>>>> xxl-job, job fail alarm email send error, JobLogId:{}", jobLog.getId(), e);

                    alarmResult = false;
                }

            }
        }


//        返回报警状态(是否成功报警,默认 是)
        return alarmResult;
    }

    /**
     * load email job alarm template
     * 加载邮件作业告警模板,,前端的页面模板
     * @return
     */
    private static final String loadEmailJobAlarmTemplate(){
        String mailBodyTemplate = "<h5>"   I18nUtil.getString("jobconf_monitor_detail")   ":</span>"  
                "<table border="1" cellpadding="3" style="border-collapse:collapse; width:80%;" >n"  
                "   <thead style="font-weight: bold;color: #ffffff;background-color: #ff8c00;" >"  
                "      <tr>n"  
                "         <td width="20%" >"  I18nUtil.getString("jobinfo_field_jobgroup")  "</td>n"  
                "         <td width="10%" >"  I18nUtil.getString("jobinfo_field_id")  "</td>n"  
                "         <td width="20%" >"  I18nUtil.getString("jobinfo_field_jobdesc")  "</td>n"  
                "         <td width="10%" >"  I18nUtil.getString("jobconf_monitor_alarm_title")  "</td>n"  
                "         <td width="40%" >"  I18nUtil.getString("jobconf_monitor_alarm_content")  "</td>n"  
                "      </tr>n"  
                "   </thead>n"  
                "   <tbody>n"  
                "      <tr>n"  
                "         <td>{0}</td>n"  
                "         <td>{1}</td>n"  
                "         <td>{2}</td>n"  
                "         <td>"  I18nUtil.getString("jobconf_monitor_alarm_type")  "</td>n"  
                "         <td>{3}</td>n"  
                "      </tr>n"  
                "   </tbody>n"  
                "</table>";

        return mailBodyTemplate;
    }

}

4 JobAlarmer

这个类,因为继承ApplicationContextAware, InitializingBean 这两个类,所以在项目启动的时候,就加载这个类

这个类的作用就是

代码语言:javascript复制
在JobAlarmer类中容器初始化时从spring上下文中获取
JobAlarm类的对象list:jobAlarmList,(主要代码:
applicationContext.getBeansOfType(JobAlarm.class);)
alarm方法中遍历jobAlarmList调用重写的doAlarm方法


(报警具体实现),当需要触发报警时,
只需要调用JobAlarmer类的alarm方法,
即可自动触发所有的报警实现,因xxl默认只有邮箱报警,
所本文代码只贴出了邮箱报警EmailJobAlarm类的代码,
此方式的好处是当需要其他报警方式:如短信报警,
只需要添加类实现JobAlarm接口,使用@Component注解,
并重写方法doAlarm即可,便会在JobAlarm类的alarm方法
jobAlarmList中触发调用子类实现的短信报警方法,
可拓展性强,便于维护。

这个类核心就是 从spring管理器里面获取JobAlarm 接口的所有实现类,都放到list里面,遍历这个list,实现多种方式的告警;

目前只有一个email,因为xxl-job 这个人家的项目,只是实现了这一个告警

代码语言:javascript复制
package com.xxl.job.admin.core.alarm;

import com.xxl.job.admin.core.model.XxlJobInfo;
import com.xxl.job.admin.core.model.XxlJobLog;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
 * 上下文,项目初始化的时候  加载这个
 */
@Component
public class JobAlarmer implements ApplicationContextAware, InitializingBean {

//    定义 当前类 日志对象
    private static Logger logger = LoggerFactory.getLogger(JobAlarmer.class);

//    上下文  管理器
    private ApplicationContext applicationContext;
//    发送告警信息  list
//    多个报警类  bean对象的  集合
    private List<JobAlarm> jobAlarmList;


    /**
     * 设置上下文
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    /**
     * 设置上下文
     */
    @Override
    public void afterPropertiesSet() throws Exception {
//        从spring管理器 里面  获取到  报警类的 bean对象
//        根据类型获取  多个bean对象
        Map<String, JobAlarm> serviceBeanMap = applicationContext.getBeansOfType(JobAlarm.class);
        if (serviceBeanMap != null && serviceBeanMap.size() > 0) {
            jobAlarmList = new ArrayList<JobAlarm>(serviceBeanMap.values());
        }
    }

    /**
     * job alarm
     *
     * @param info
     * @param jobLog
     * @return
     */
    public boolean alarm(XxlJobInfo info, XxlJobLog jobLog) {

        boolean result = false;

//        如果  多个报警类  bean对象的  集合 不为空
        if (jobAlarmList!=null && jobAlarmList.size()>0) {

//        result = true 意味的  全部的 报警email 发放  都成功了
            result = true;  // success means all-success

            for (JobAlarm alarm: jobAlarmList) {
//                遍历  每一个  email发送类对象

//               每一个  email发送类对象   是否发送成功
                boolean resultItem = false;
                try {

//                    发送email
                    resultItem = alarm.doAlarm(info, jobLog);
                } catch (Exception e) {
                    logger.error(e.getMessage(), e);
                }
                if (!resultItem) {
                    result = false;
                }
            }
        }

        return result;
    }

}

0 人点赞