如果没有了解XXL-JOB的同学可以先去了解一下XXL-JOB是什么,然后再来看我这篇文章,会更加清晰!!
话不多说,走流程!!!
如果要发送邮件我们首先得开启 POP3/SMTP服务 获取到一个16位的密钥(非常重要!)没有这个是用不了的!!!
点击邮箱设置:
点击账户:
配置信息:
### xxl-job, email
spring.mail.host=smtp.qq.com (如果是163邮箱这里 这里是 smtp.163.com)
spring.mail.port=25
spring.mail.username=你的qq邮箱
spring.mail.from=你的qq邮箱
spring.mail.password=这里是你刚才拿到的密钥(不是qq密码!!)
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory
然后在任务编辑填写邮件名:
这里可以配置多个邮件,用逗号分开
我们要根据XXL-JOB智能预警对接微信公众号推送,我们首先查看XXL-JOb源码得知我们发送信息推送是通过XXL-JOB的邮件预警来进行处理的。
XXL-JOB的邮件预警发送原理是任务一旦有调度失败的或者执行结果失败的都会记录在xxl_job_log这张表中,(每一个任务都有一个任务id) 那他是怎么知道你一有调度失败就会发送消息呢?
我们来看代码:
private Thread monitorThread;
private volatile boolean toStop = false;
public void start() {
monitorThread = new Thread(new Runnable() {
@Override
public void run() {
LocalDateTime localDateTime = LocalDateTime.now().minusHours(1);
// monitor
while (!toStop) {
try {
List failLogIds = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().findFailJobLogIds(localDateTime, 1000);
if (failLogIds != null && !failLogIds.isEmpty()) {
for (long failLogId : failLogIds) {
// lock log
int lockRet = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().updateAlarmStatus(failLogId, 0, -1);
if (lockRet < 1) {
continue;
}
XxlJobLog log = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().load(failLogId);
XxlJobInfo info = XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().loadById(log.getJobId());
// 1、fail retry monitor
if (log.getExecutorFailRetryCount() > 0) {
JobTriggerPoolHelper.trigger(log.getJobId(), TriggerTypeEnum.RETRY, (log.getExecutorFailRetryCount() - 1), log.getExecutorShardingParam(), log.getExecutorParam(), null);
String retryMsg = "
>>>>>>>>>>>" + I18nUtil.getString("jobconf_trigger_type_retry") + "<<<<<<<<<<<
";
log.setTriggerMsg(log.getTriggerMsg() + retryMsg);
XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().updateTriggerInfo(log);
}
// 2、fail alarm monitor
int newAlarmStatus = 0; // 告警状态:0-默认、-1=锁定状态、1-无需告警、2-告警成功、3-告警失败
if (info != null && info.getAlarmEmail() != null && info.getAlarmEmail().trim().length() > 0) {
boolean alarmResult = XxlJobAdminConfig.getAdminConfig().getJobAlarmer().alarm(info, log);
newAlarmStatus = alarmResult ? 2 : 3;
} else {
newAlarmStatus = 1;
}
XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().updateAlarmStatus(failLogId, -1, newAlarmStatus);
}
}
} catch (Exception e) {
if (!toStop) {
logger.error(">>>>>>>>>>> xxl-job, job fail monitor thread error:{}", e);
}
}
try {
TimeUnit.SECONDS.sleep(10);
} catch (Exception e) {
if (!toStop) {
logger.error(e.getMessage(), e);
}
}
}
logger.info(">>>>>>>>>>> xxl-job, job fail monitor thread stop");
}
});
monitorThread.setDaemon(true);
monitorThread.setName("xxl-job, admin JobFailMonitorHelper");
monitorThread.start();
}
由此可见,XXL-JOB邮件预警源码里面是一个线程的一个死循环,只要你启动了一个任务(代码中的toStop不为false),这个循环就会一直的去查询你的xxl_job_log表,只要你开启的这个任务有一条执行错误或者调度失败,就会进入循环,然后发送邮件。
邮件信息:
然后我们想要对接其他第三方服务推送信息:
我们这里对接的是微信公众号。
首先,对接微信公众号进行消息推送,得有一个公众号。
我们打开网址 微信公众平台
申请公众号后,有一个微信的
appid,和一个 secret密钥
我们要通过这两个关键的密钥才能对接公众号推送信息。如果有没有公众号的同学也可以看一下大致原理是什么,非常简单!!!
首先我们得获取到Token令牌,我这里用的RestTemplate来进行发送请求
@Autowired
private RestTemplate restTemplate;
public String getToken() {
if (WxchatCache.AccessToken.expiration <= System.currentTimeMillis()) {
String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=你的appid&secret=你的secret";
ResponseEntity forEntity = this.restTemplate.getForEntity(url, String.class, new Object[0]);
JSONObject jsonObject = JSON.parseObject((String)forEntity.getBody());
Object errcode = jsonObject.get("errcode");
this.logger.info("error {}", jsonObject);
if (errcode != null && "40013".equals(errcode.toString())) {
throw new RuntimeException("推送失败");
}
WxchatCache.AccessToken.token = jsonObject.get("access_token").toString();
WxchatCache.AccessToken.expiration = (long)((Integer.parseInt(jsonObject.get("expires_in").toString()) - 1) * 1000) + System.currentTimeMillis();
}
return WxchatCache.AccessToken.token;
}
如果这里遇到获取不到token的问题,要到微信公众后台开启你本机ip的白名单!!
要想实现其他平台对接,我们查看文档得知要实现这一个接口:
选好公众号模板id,填写
@Override
public boolean doAlarm(XxlJobInfo info, XxlJobLog jobLog) {
// 获得任务名称
String jobDesc = info.getJobDesc();
// 获得Token
String token = wxchatAccessToken.getToken();
// 存入链接
String postUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + token;
JSONObject jsonObject = new JSONObject();
// 关注公众号用户的openId
jsonObject.put("touser", openid);
// 模板id
jsonObject.put("template_id", "xv7CCYfePuYyfS7RgiH5rSglQyBj3XWwZednoreq-4w");
// 跳转地址
jsonObject.put("url", "http://www.baidu.com");
// 提示的消息必须是JSON在data中
JSONObject data = new JSONObject();
JSONObject first = new JSONObject();
first.put("value", "淘联账号提醒:");
JSONObject keyword1 = new JSONObject();
keyword1.put("value", "【重要提示!】当前淘联可能被封禁或者被限流!请及时查看");
JSONObject keyword2 = new JSONObject();
keyword2.put("value", LocalDateTime.now());
JSONObject remark = new JSONObject();
remark.put("value", "站点:【" + profile + "】" + "优化师:" + info.getAuthor() + " 任务:" + info.getJobDesc());
data.put("first", first);
data.put("keyword1", keyword1);
data.put("keyword2", keyword2);
data.put("remark", remark);
jsonObject.put("data", data);
HttpClientUtils.sendPostJsonStr(postUrl, jsonObject.toJSONString());
return false;
}
至此:
创作不易,免费开源,希望大家点个小爱心!!!