原理篇-- 定时任务xxl-job-执行器项目启动过程--XxlJobExecutor 初始化(2)


前言

本文对XxlJobExecutor 初始化内容进行介绍。


一、XxlJobExecutor作用:

XxlJobExecutor是一个任务调度执行器,通常用于快速集成分布式任务调度功能到项目中。它可以方便地实现定时任务、定时调度、分布式调度等功能。

具体来说,XxlJobExecutor是一个基于分布式任务调度平台xxl-job的执行器,可以与xxl-job平台进行通信,接收并执行任务。通过使用XxlJobExecutor,可以实现任务的动态添加、暂停、恢复、删除等操作,同时支持对任务执行日志进行管理和监控。

二、XxlJobExecutor 源码内容:

2.1 start() 方法

 public void start() throws Exception {

        // init logpath  
      //  执行器运行日志文件存储磁盘路径 赋值
     XxlJobFileAppender.initLogPath(logPath);

     // init invoker, admin-client
     //  初始化服务器的地址与令牌
     initAdminBizList(adminAddresses, accessToken);


     // init JobLogFileCleanThread
     // 日志删除
     JobLogFileCleanThread.getInstance().start(logRetentionDays);

     // init TriggerCallbackThread
     // 任务的回调,告诉xxljob server 任务是否执行成功
     TriggerCallbackThread.getInstance().start();

     // init executor-server
     // 执行器注册,开启netty  接收xxljob server 端任务的调用
     initEmbedServer(address, ip, port, appname, accessToken);
 }

2.2 initAdminBizList 初始化:

2.2.1 服务端访问对象AdminBiz 封装:

private static List<AdminBiz> adminBizList;
/**
 接收服务端地址 及 通信的token 并包装成AdminBiz  对象,方便后续通过AdminBiz 向服务端发送http 请求
* adminAddresses : xxl.job.admin.addresses 配置地址 多个地址以  "," 分隔
*  accessToken: xxl.job.accessToken配置的访问令牌
**/
private void initAdminBizList(String adminAddresses, String accessToken) throws Exception {
    if (adminAddresses!=null && adminAddresses.trim().length()>0) {
    	// 以"," 分隔服务端的地址 并进行遍历
        for (String address: adminAddresses.trim().split(",")) {
            if (address!=null && address.trim().length()>0) {
				// 封装成为AdminBiz  对象
                AdminBiz adminBiz = new AdminBizClient(address.trim(), accessToken);

                if (adminBizList == null) {
                    adminBizList = new ArrayList<AdminBiz>();
                }
                // 将 封装成好的 AdminBiz 钓友服务端的对象放入集合中
                adminBizList.add(adminBiz);
            }
        }
    }
}

2.2.2 AdminBiz 内容:

/**
 * admin api test
 *
 * @author xuxueli 2017-07-28 22:14:52
 */
public class AdminBizClient implements AdminBiz {

    public AdminBizClient() {
    }
    // 构造方法实例化  AdminBizClient  对象
    public AdminBizClient(String addressUrl, String accessToken) {
        this.addressUrl = addressUrl;
        this.accessToken = accessToken;

        // valid
        if (!this.addressUrl.endsWith("/")) {
            this.addressUrl = this.addressUrl + "/";
        }
    }

    private String addressUrl ;
    private String accessToken;
    private int timeout = 3;

	// 发送任务执行器情况 给服务端
    @Override
    public ReturnT<String> callback(List<HandleCallbackParam> callbackParamList) {
        return XxlJobRemotingUtil.postBody(addressUrl+"api/callback", accessToken, timeout, callbackParamList, String.class);
    }
	// 执行器项目启动后向 服务端发送执行器的地址,进行注册
    @Override
    public ReturnT<String> registry(RegistryParam registryParam) {
        return XxlJobRemotingUtil.postBody(addressUrl + "api/registry", accessToken, timeout, registryParam, String.class);
    }
	// 执行器项目停止后向 服务端发送执行器的地址,服务端进行对应执行器的移除
    @Override
    public ReturnT<String> registryRemove(RegistryParam registryParam) {
        return XxlJobRemotingUtil.postBody(addressUrl + "api/registryRemove", accessToken, timeout, registryParam, String.class);
    }

}

2.3 JobLogFileCleanThread log 日志删除:

/**
 * job file clean thread
 *
 * @author xuxueli 2017-12-29 16:23:43
 */
public class JobLogFileCleanThread {
	// log 日志对象获取
    private static Logger logger = LoggerFactory.getLogger(JobLogFileCleanThread.class);
	// 实例化 JobLogFileCleanThread  对象
    private static JobLogFileCleanThread instance = new JobLogFileCleanThread();
    public static JobLogFileCleanThread getInstance(){
        return instance;
    }
	// 声明清理日志文件的 线程
    private Thread localThread;
    // 理日志文件线程的 停止标识
    private volatile boolean toStop = false;
    //  logRetentionDays  xxl.job.executor.logretentiondays 配置的值 默认值30 天
    public void start(final long logRetentionDays){

        // limit min value 
        //  过期日志自动清理, 限制值大于等于3时生效; 否则, 如-1, 关闭自动清理功能
        if (logRetentionDays < 3 ) {
            return;
        }
		// 清理日志线程
        localThread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (!toStop) {
                    try {
                        // clean log dir, over logRetentionDays
                        // 获取配置的  xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler 路径下的目录文件
                        File[] childDirs = new File(XxlJobFileAppender.getLogPath()).listFiles();
                        if (childDirs!=null && childDirs.length>0) {

                            // today 获取今天的时间
                            Calendar todayCal = Calendar.getInstance();
                            todayCal.set(Calendar.HOUR_OF_DAY,0);
                            todayCal.set(Calendar.MINUTE,0);
                            todayCal.set(Calendar.SECOND,0);
                            todayCal.set(Calendar.MILLISECOND,0);

                            Date todayDate = todayCal.getTime();

                            for (File childFile: childDirs) {

                                // valid 文件不是目录则继续下一次循环
                                if (!childFile.isDirectory()) {
                                    continue;
                                }
                                // 目录的名字不包含"-" 则继续下一次循环
                                if (childFile.getName().indexOf("-") == -1) {
                                    continue;
                                }

                                // file create date
                                Date logFileCreateDate = null;
                                try {
                                	// 根据文件的名字 获取 改文件是何时生成的
                                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                                    logFileCreateDate = simpleDateFormat.parse(childFile.getName());
                                } catch (ParseException e) {
                                    logger.error(e.getMessage(), e);
                                }
                                if (logFileCreateDate == null) {
                                    continue;
                                }
								// 根据文件的生成时间是 判断是否在保留的天数之内
                                if ((todayDate.getTime()-logFileCreateDate.getTime()) >= logRetentionDays * (24 * 60 * 60 * 1000) ) {
                                // 删除日志文件
                                    FileUtil.deleteRecursively(childFile);
                                }

                            }
                        }

                    } catch (Exception e) {
                        if (!toStop) {
                            logger.error(e.getMessage(), e);
                        }

                    }

                    try {
                    	// 线程睡1天
                        TimeUnit.DAYS.sleep(1);
                    } catch (InterruptedException e) {
                        if (!toStop) {
                            logger.error(e.getMessage(), e);
                        }
                    }
                }
                logger.info(">>>>>>>>>>> xxl-job, executor JobLogFileCleanThread thread destroy.");

            }
        });
        // 设置线程为守护线程,设置线程的名字,启动线程
        localThread.setDaemon(true);
        localThread.setName("xxl-job, executor JobLogFileCleanThread");
        localThread.start();
    }
	// 当容器停止时 调用toStop() 方法 释放资源
    public void toStop() {
    	// 重置清除日志线程的标识,使其跳出while 循环
        toStop = true;

        if (localThread == null) {
            return;
        }

        // interrupt and wait
        localThread.interrupt();
        try {
        	// 等待 清理日志的localThread 线程 完成任务
            localThread.join();
        } catch (InterruptedException e) {
            logger.error(e.getMessage(), e);
        }
    }

}

日志文件记录地址如下:
在这里插入图片描述

文件日志:
在这里插入图片描述


总结

本文对XxlJobExecutor 初始化时 执行器的封装以及 日志清理 内容进行介绍。

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值