前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何在xxl-job调度框架中集成企业微信告警功能

如何在xxl-job调度框架中集成企业微信告警功能

原创
作者头像
空洞的盒子
发布2023-11-17 14:13:58
1.3K3
发布2023-11-17 14:13:58
举报
文章被收录于专栏:JD的专栏JD的专栏

前言:XXL-Job作为一款轻量级的调度框架,在日常任务调度场景中应用广泛。提供了多种任务运行模式,覆盖Java,shell,Python,PHP等语言。提供了完善的任务监控机制,失败重试机制,任务告警机制。同时支持容器化部署,做到开箱即用。

本文,我们主要介绍如何在XXL-Job中集成企业微信告警功能。在xxl-job中默认提供了邮件告警,可以自行扩展钉钉,企业微信登告警方式。如果需要新增一种告警方式,需要自行新增一个 “com.xxl.job.admin.core.alarm.JobAlarm” 接口的告警实现。

1.前期准备

首先我们需要再企业微信中申请一个机器人,获取机器人的webhook地址。因为在后续的告警中,我们需要调用机器人的webhook URL将告警信息通过机器人发送至我们的企微群中。

2.企微告警逻辑开发

在xxl-job中,告警功能都是通过实现JobAlarm接口。

首先我们需要再 com.xxl.job.admin.core.model包的XxlJobInfo类中,新增private String alarmWeChat;的变量,并生成相应的getter,setter方法。供我们进行调用。

代码语言:javascript
复制
	private String alarmWeChat; // 企微告警
	public String getAlarmWeChat() {
		return alarmWeChat;
	}

	public void setAlarmWeChat(String alarmWeChat) {
		this.alarmWeChat = alarmWeChat;
	}

我们在com.xxl.job.admin.core.alarm.impl包中新定义一个企微告警类,用于实现JobAlarm接口。实现该接口后,我们需要重写接口中的doAlarm()方法。在以下代码中,我们在通过XxlJobInfo进行任务信息的获取,构建失败告警的内容,由于是不属于内网容器集群中,访问公网需要通过代理,所以我们这里直接构造失败告警信息(这里使用的是企微机器人的text格式消息。)与curl请求体(比较粗暴)。通过execCurl()方法进行失败告警信息的发送。

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

import com.alibaba.fastjson2.JSON;
import com.xxl.job.admin.core.alarm.JobAlarm;
import com.xxl.job.admin.core.model.XxlJobInfo;
import com.xxl.job.admin.core.model.XxlJobLog;
import com.xxl.job.core.biz.model.ReturnT;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.*;
import java.util.HashMap;
import java.util.Map;

@Component
public class WeChatJobAlarm implements JobAlarm {
    @Value("${WEBHOOK_URL}")
    private String WEBHOOK_URL;
    private static Logger logger = LoggerFactory.getLogger(WeChatJobAlarm.class);
    HttpHeaders headers = new HttpHeaders();
    SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
    RestTemplate restTemplate = new RestTemplate();
    @Override
    public boolean doAlarm(XxlJobInfo info, XxlJobLog jobLog) {
        logger.info("开始调用失败任务ID");
        boolean alarmResult = true;
        if (logger != null && info.getAlarmWeChat() != null && info.getAlarmWeChat().trim().length() > 0) {
            // 告警内容
            String alarmMessage = "Failed Task ID: " + jobLog.getJobId();
            if (jobLog.getTriggerCode() != ReturnT.SUCCESS_CODE) {
                alarmMessage += "<br>TriggerMsg=<br>" + jobLog.getTriggerMsg();
            }
            if (jobLog.getHandleCode() > 0 && jobLog.getHandleCode() != ReturnT.SUCCESS_CODE) {
                alarmMessage += "<br>HandleCode=" + jobLog.getHandleMsg();
            }
            //构造企微告警消息 new WeChatBotMessage(alarmMessage)
            Map messageMap = new HashMap(8);
            Map contentMap = new HashMap(8);
            contentMap.put("content",alarmMessage);
            messageMap.put("msgtype","text");
            messageMap.put("text",contentMap);
            String weChatMessage = JSON.toJSONString(messageMap);
            String webhook = info.getAlarmWeChat();
            //正式环境
            String[] prUrl = {
                    "curl",
                    "-x",
                    "http://proxy-xxxx:1000",
                    "-H",
                    "Content-Type: application/json",
                    "POST",
                    webhook,
                    "-d",
                    weChatMessage
            };

            try {
                execCurl(prUrl);
                logger.info("企微告警发送成功。");
            }catch (Exception e){
                e.printStackTrace();
            }

           /* //发送告警信息
            headers.setContentType(MediaType.APPLICATION_JSON);
            HttpEntity<String> request = new HttpEntity<>(weChatMessage, headers);
            ResponseEntity<String> response = restTemplate.postForEntity(webhook, request, String.class);
            if (response.getStatusCode().is2xxSuccessful()) {
                logger.info("机器人消息发送成功");
            } else {
                alarmResult = false;
                logger.error("机器人消息发送失败");
            }*/

        }
        return alarmResult;
    }

    public String execCurl(String[] cmds){
        ProcessBuilder process = new ProcessBuilder(cmds);

        Process p;
        try {
            p = process.start();
            BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
            StringBuilder builder = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                builder.append(line);
                builder.append(System.getProperty("line.separator"));
            }
            return builder.toString();

        } catch (IOException e) {
            logger.error("企微告警信息发送失败。");
            e.printStackTrace();
        }
        return null;
    }
}

至此,我们的消息发送部分就已经编写完成。但是我们的功能仍未完成。

3.企微告警信息持久化

当我们在创建任务时,需要对调度任务进行配置,我们需要将任务信息持久化到数据库中,同理我们新增的企微告警配置,关于企微机器人的webhook地址也需要进行持久化,索引我们还需要在XxlJobInfoMapper.xml文件中对我们的企微告警字段进行添加。

需要添加以下内容,以保证我们的企微告警地址能够被持久化到数据库中,在更新时也能够正常更新。

代码语言:html
复制
#在<resultMap></resultMap>部分添加以下内容
<resultMap id="XxlJobInfo" type="com.xxl.job.admin.core.model.XxlJobInfo" >
	<result column="alarm_wechat" property="alarmWeChat" />
</resultMap>
#在<sql id="Base_Column_List"></sql>中添加以下内容
<sql id="Base_Column_List">
		t.alarm_wechat		
</sql>
#在insert与update语句块中,分别添加以下内容,以确保该字段能够被插入与更新
alarm_wechat, #{alarmWeChat}

4.前端页面配置

后端部分开发完成后,我们还需要在前端页面上新增一个企微告警的入口,便于我们在创建任务,编辑任务时填入webhookURL。

xxl-job的页面主要由js进行开发。在jobinfo.index.1.js文件中我们首先需要找到任务详情与更新部分的js代码。然后添加以下代码:

代码语言:javascript
复制
$("#updateModal .form input[name='alarmWeChat']").val( row.alarmWeChat );
代码语言:javascript
复制
$("#addModal .form input[name='alarmWeChat']").val( row.alarmWeChat );

5.本地调试

xxl-job在启动时,需要再相应目录下创建日志文件。为了避免由于该问题导致启动失败,我们还需要在logback.xml文件中将log.path修改为本地路径,便于我们进行本地进行调试。

工程启动后,我们在xxl-job主页进行任务的新增与更新。

我们可以看到在页面上我们的企微告警功能已经开发完成。我们手动触发任务后,并人工干预失败后,我们就可以再企业微信群收到任务失败的告警信息了。

至此,我们在xxl-job中的新增的企微告警功能就以开发完成。

我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.前期准备
  • 2.企微告警逻辑开发
  • 3.企微告警信息持久化
  • 4.前端页面配置
  • 5.本地调试
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档