k8s搭建xxl-job过程

前言

好久没有写博客了,最近一直没有时间,但是做的东西还是蛮多的,因为刚搭建了xxl-job,趁现在记忆还有的话,记录一下搭建遇到的问题,以便之后回忆

1.1 xxl-job简介

XXL-JOB是一个分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,开箱即用。
中文文档可以多关注,多看看。
Github地址 中文文档

2.1 搭建

先从github上克隆源码 用IDEA打开项目 如下:
k8s搭建xxl-job过程_第1张图片

2.1.1 建表

“调度数据库初始化SQL脚本” 位置为

/xxl-job/doc/db/tables_xxl_job.sql

2.1.2 修改admin配置文件

告警邮箱参考博客 xxl-job告警邮箱配置
k8s搭建xxl-job过程_第2张图片
注意:网上有些博客配置了admin面板 登录的密码和用户名,我这边试了是不起效果的,我是进入面板修改密码才生效的
默认账号 :admin
默认密码: 123456

2.1.3 接入钉钉告警

钉钉开发文档
这边安全设置,我选择的是加密的方式,

2.1.3.1 DingJobAlarm

参考 EmailJobAlarm 文件模仿写一个钉钉的告警,如下:

/**
 * Created by lxc .([email protected] 672063)
 * 日期  2020/11/2 8:21
 */
@Component
public class DingJobAlarm implements JobAlarm {

    private static Logger logger = LoggerFactory.getLogger(DingJobAlarm.class);

    private static final String DING_WEB_HOOK_URL = "https://oapi.dingtalk.com/robot/send?access_token=";
    private static final String ACCESS_TOKEN = "your"; //这边用自己的
    private static final String DING_SECRET = "your"; // 这边用自己的

    @Override
    public boolean doAlarm(XxlJobInfo info, XxlJobLog jobLog) {
        logger.info(" doAlarm 钉钉开始~~");
        boolean alarmResult = true;
        if (info != null) {
            // alarmContent
            String alarmContent = "Alarm Job LogId=" + jobLog.getId() + "\n";
            if (jobLog.getTriggerCode() != ReturnT.SUCCESS_CODE) {
                alarmContent += "TriggerMsg = " + jobLog.getTriggerMsg() + "\n";
            }
            if (jobLog.getHandleCode() > 0 && jobLog.getHandleCode() != ReturnT.SUCCESS_CODE) {
                alarmContent += "HandleCode = " + jobLog.getHandleMsg() + "\n";
            }
            DingMessage dingMessage = new DingMessage();
            dingMessage.setMsgtype("text");
            dingMessage.setText(new DingMessage.DingContent(alarmContent));
            Long timestamp = System.currentTimeMillis();
            String stringToSign = timestamp + "\n" + DING_SECRET;
            Mac mac = null;
            try {
                mac = Mac.getInstance("HmacSHA256");
                mac.init(new SecretKeySpec(DING_SECRET.getBytes("UTF-8"), "HmacSHA256"));
                byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8"));
                String sign = URLEncoder.encode(new String(Base64.encodeBase64(signData)), "UTF-8");
                String webUrl = DING_WEB_HOOK_URL + ACCESS_TOKEN + "×tamp=" + timestamp + "&sign=" + sign;
                String data = JSON.toJSONString(dingMessage);
                String result = HttpUtil.request(webUrl, data, null, HttpMethod.POST, MediaType.APPLICATION_JSON);
                logger.info(" doAlarm 钉钉 请求结果->" + result);
            } catch (Exception e) {
                e.printStackTrace();
                alarmResult = false;
            }
        }
        return alarmResult;
    }
}
2.1.3.2 HttpUtil 工具类

这边我是网上找的别人的工具类,拿来自己试试

public class HttpUtil {
    /**
     * get请求
     *
     * @param url
     * @param params 请求参数
     * @return
     */
    public static String get(String url, MultiValueMap params) {
        return get(url, params, null);
    }

    /**
     * get请求
     *
     * @param url
     * @param params  请求参数
     * @param headers 请求头
     * @return
     */
    public static String get(String url, MultiValueMap params, MultiValueMap headers) {
        return request(url, params, headers, HttpMethod.GET);
    }

    /**
     * post请求
     *
     * @param url
     * @param params 请求参数
     * @return
     */
    public static String post(String url, MultiValueMap params) {
        return post(url, params, null);
    }

    /**
     * post请求
     *
     * @param url
     * @param params  请求参数
     * @param headers 请求头
     * @return
     */
    public static String post(String url, MultiValueMap params, MultiValueMap headers) {
        return request(url, params, headers, HttpMethod.POST);
    }

    /**
     * put请求
     *
     * @param url
     * @param params 请求参数
     * @return
     */
    public static String put(String url, MultiValueMap params) {
        return put(url, params, null);
    }

    /**
     * put请求
     *
     * @param url
     * @param params  请求参数
     * @param headers 请求头
     * @return
     */
    public static String put(String url, MultiValueMap params, MultiValueMap headers) {
        return request(url, params, headers, HttpMethod.PUT);
    }

    /**
     * delete请求
     *
     * @param url
     * @param params 请求参数
     * @return
     */
    public static String delete(String url, MultiValueMap params) {
        return delete(url, params, null);
    }

    /**
     * delete请求
     *
     * @param url
     * @param params  请求参数
     * @param headers 请求头
     * @return
     */
    public static String delete(String url, MultiValueMap params, MultiValueMap headers) {
        return request(url, params, headers, HttpMethod.DELETE);
    }

    /**
     * 表单请求
     *
     * @param url
     * @param params  请求参数
     * @param headers 请求头
     * @param method  请求方式
     * @return
     */
    public static String request(String url, MultiValueMap params, MultiValueMap headers, HttpMethod method) {
        if (params == null) {
            params = new LinkedMultiValueMap<>();
        }
        return request(url, params, headers, method, MediaType.APPLICATION_FORM_URLENCODED);
    }

    /**
     * http请求
     *
     * @param url
     * @param params    请求参数
     * @param headers   请求头
     * @param method    请求方式
     * @param mediaType 参数类型
     * @return
     */
    public static String request(String url, Object params, MultiValueMap headers, HttpMethod method, MediaType mediaType) {
        if (url == null || url.trim().isEmpty()) {
            return null;
        }
        RestTemplate client = new RestTemplate();
        // header
        HttpHeaders httpHeaders = new HttpHeaders();
        if (headers != null) {
            httpHeaders.addAll(headers);
        }
        // 提交方式:表单、json
        httpHeaders.setContentType(mediaType);
        HttpEntity httpEntity = new HttpEntity(params, httpHeaders);
        ResponseEntity response = client.exchange(url, method, httpEntity, String.class);
        return response.getBody();
    }
}


2.1.3.3 Json

添加如下依赖:


	com.alibaba
	fastjson
	1.2.62

实体:


/**
 * Created by lxc .([email protected] 672063)
 * 日期  2020/11/2 9:00
 */

public class DingMessage {
    String msgtype;
    DingContent text;

    public DingMessage() {
    }


    public String getMsgtype() {
        return msgtype;
    }

    public void setMsgtype(String msgtype) {
        this.msgtype = msgtype;
    }

    public DingContent getText() {
        return text;
    }

    public void setText(DingContent text) {
        this.text = text;
    }

    public static class DingContent{
        String content;

        public DingContent(String content) {
            this.content = content;
        }

        public String getContent() {
            return content;
        }

        public void setContent(String content) {
            this.content = content;
        }
    }
}

2.1.4 部署调度中心

然后生成jar包,打包成docker镜像push自己的harbor上,具体步骤就不描述了~~ 初始化成功 如下图:
k8s搭建xxl-job过程_第3张图片

2.1.5 xxl-job-admin面板

这边要注意要加上/xxl-job-admin/ 一开始我用ingress地址访问直接404
我还以为k8s哪里部署的不对,这里花费了点时间 check
k8s搭建xxl-job过程_第4张图片

3.1 部署 Spring boot 执行器应用

3.1.1 修改配置文件

xxl-job-admin 的地址配置

xxl.job.admin.addresses=http://xxxxxxxx/xxl-job-admin

3.1.2 ExceptionHandler

在 SampleXxlJob 这个类下添加异常的任务,方便测试钉钉告警和邮箱告警

    @XxlJob("ExceptionHandler")
    public ReturnT ExceptionHandler(String param) throws Exception{
        XxlJobLogger.log("XXL-JOB ExceptionHandler, Hello World.");
        int i = 1/0;
        return ReturnT.SUCCESS;
    }

3.1.3 部署

此处省略…同上一样,打包Jar 生成 docker 镜像 写k8s部署文件…Zz…

k8s搭建xxl-job过程_第5张图片

3.2 测试

3.2.1 新建执行器

把刚刚Springboot 应用里写的Exception执行器配置一下 如下:
k8s搭建xxl-job过程_第6张图片
操作执行一次,查看日志 如下:
在这里插入图片描述
k8s搭建xxl-job过程_第7张图片
k8s搭建xxl-job过程_第8张图片
都是有收到的 ~~~ 达到预期效果

4.1 遇到的问题

4.1.1 xxl-rpc remoting error(connect timed out)

k8s搭建xxl-job过程_第9张图片
k8s搭建xxl-job过程_第10张图片
我后来发现是我本地的调试,影响的容器的调度机器,其实我也不知道为什么我本地的可以成为调度机器,本地去调用执行器肯定是不行的,当时一直不知道为什么原因… 看到调度机器的ip地址才明白,当然我电脑重启后,之后的调度都是成功的… 但是其原理我还是不懂,因为本地也影响不了容器部署的xxl-job-admin,难道像服务一样注册到什么上面,才能变成调度机器?
我也再github上留言了,也看了许多人也有这个问题,希望有人知道的话可以告知,谢谢

总结


因为是回过头来写的博客,和准备的资料,不知道博客的流程是否完整,希望有不足的地方,大家批评指点 。
有用的话,点个赞吧~!

你可能感兴趣的:(k8s,xxl-job,k8s)