xxl-job定时任务框架原理分析(二)

xxl-job执行器源码分享

执行器的分类

xxl-job一共定义了5种类型的执行器,这里放个截图
xxl-job执行器
这里我们挑选springboot项目来进行分析。

源码分析

  • 既然是boot项目,那么首先肯定是找执行类:XxlJobExecutorApplication,这是个简单的启动类。
public static void main(String[] args) {
     SpringApplication.run(XxlJobExecutorApplication.class, args);
}
  • 之后会进入配置类:XxlJobConfig,这里会读取resources/application.properties的配置信息,然后执行xxlJobExecutor()方法,贴下代码。
@Bean(initMethod = "start", destroyMethod = "destroy")
    public XxlJobSpringExecutor xxlJobExecutor() {
        logger.info(">>>>>>>>>>> xxl-job config init.");
        XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
        xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
        xxlJobSpringExecutor.setAppName(appName);
        xxlJobSpringExecutor.setIp(ip);
        xxlJobSpringExecutor.setPort(port);
        xxlJobSpringExecutor.setAccessToken(accessToken);
        xxlJobSpringExecutor.setLogPath(logPath);
        xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);

        return xxlJobSpringExecutor;
    }
  • 这里可以看到接下来就会调用XxlJobSpringExecutorstart()方法,OK,让我们在来看看他做了什么。
@Override
public void start() throws Exception {

    // 注册所有的jobHandler
    initJobHandlerRepository(applicationContext);

    // 不是很重要,就是注册个工程
    GlueFactory.refreshInstance(1);

    // 调用父类的start方法
    super.start();
}
  • 父类也就是XxlJobExecutorstart()方法执行,我们在来看看。
public void start() throws Exception {

        // 初始化日志路径
        XxlJobFileAppender.initLogPath(logPath);

        // 初始化调度中心的本地列表
        initAdminBizList(adminAddresses, accessToken);

        // 日志清除线程
        JobLogFileCleanThread.getInstance().start(logRetentionDays);

        // 回调线程开启
        TriggerCallbackThread.getInstance().start();
        port = port>0?port: NetUtil.findAvailablePort(9999);
        ip = (ip!=null&&ip.trim().length()>0)?ip: IpUtil.getIp();
        // 初始化服务器
        initRpcProvider(ip, port, appName, accessToken);
    }
  • 这里需要关注的是initAdminBizList()initRpcProvider(),那么同样看代码。
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) {

                    String addressUrl = address.concat(AdminBiz.MAPPING);

                    AdminBiz adminBiz = (AdminBiz) new XxlRpcReferenceBean(
                            NetEnum.JETTY,
                            Serializer.SerializeEnum.HESSIAN.getSerializer(),
                            CallType.SYNC,
                            LoadBalance.ROUND,
                            AdminBiz.class,
                            null,
                            10000,
                            addressUrl,
                            accessToken,
                            null,
                            null
                    ).getObject();

                    if (adminBizList == null) {
                        adminBizList = new ArrayList<AdminBiz>();
                    }
                    adminBizList.add(adminBiz);
                }
            }
        }
    }

这里主要意思就是得到AdminBiz代理并放入到adminBizList集合中,获取代理的方法是getObject(),然后接着看,接下来就是完成向任务调度中心发送请求进行服务注册操作,我们主要看如何发起请求的代码。

client.asyncSend(finalAddress, xxlRpcRequest);

在这里插入图片描述
这里会有三种实现,xxl-job默认采用JettyClient,继续追踪会发现其实就是封装了一个Request请求,然后向注册中心发送。这样注册流程就完成了。

  • 接下来该看看initRpcProvider()方法,那这个方法做了什么呢?想必看名字也大概知道了,没错,就是启动一个web服务,供之后调度中心的分发任务,看代码。
private void initRpcProvider(String ip, int port, String appName, String accessToken) throws Exception {

        // 初始化服务注册工厂
        String address = IpUtil.getIpPort(ip, port);
        Map<String, String> serviceRegistryParam = new HashMap<String, String>();
        serviceRegistryParam.put("appName", appName);
        serviceRegistryParam.put("address", address);

        xxlRpcProviderFactory = new XxlRpcProviderFactory();
        xxlRpcProviderFactory.initConfig(NetEnum.JETTY, Serializer.SerializeEnum.HESSIAN.getSerializer(), ip, port, accessToken, ExecutorServiceRegistry.class, serviceRegistryParam);

        // 添加服务
        xxlRpcProviderFactory.addService(ExecutorBiz.class.getName(), null, new ExecutorBizImpl());

        // 启动一个web服务
        xxlRpcProviderFactory.start();

    }
  • 在进入start()方法。
public void start() throws Exception {
		// start server
		serviceAddress = IpUtil.getIpPort(this.ip, port);
		server = netType.serverClass.newInstance();
		server.setStartedCallback(new BaseCallback() {		// serviceRegistry started
			@Override
			public void run() throws Exception {
				// start registry
				if (serviceRegistryClass != null) {
					serviceRegistry = serviceRegistryClass.newInstance();
					serviceRegistry.start(serviceRegistryParam);
					if (serviceData.size() > 0) {
						serviceRegistry.registry(serviceData.keySet(), serviceAddress);
					}
				}
			}
		});
		server.setStopedCallback(new BaseCallback() {		// serviceRegistry stoped
			@Override
			public void run() {
				// stop registry
				if (serviceRegistry != null) {
					if (serviceData.size() > 0) {
						serviceRegistry.remove(serviceData.keySet(), serviceAddress);
					}
					serviceRegistry.stop();
					serviceRegistry = null;
				}
			}
		});
		//前面就是一些地址,回调的设置,这里就是启动了一个jetty服务
		server.start(this);
	}
  • 至此,执行器的任务基本完成,来总结下,执行器启动后,首先会向注册中心注册自身,然后自己会启动一个jetty服务供之后的注册中心来分发任务。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值