造个轮子-任务调度执行小框架-任务清单解析实现

这篇具有很好参考价值的文章主要介绍了造个轮子-任务调度执行小框架-任务清单解析实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

okey~每日编码一坤时,昨天的话我们已经实现了这个框架的IOC容器。通过这个IOC容器,我们就可以非常轻松地进行后续的操作,于是,我们接着这个工作,去完成这个任务清单的解析。

昨天的话,阐述了一下这个框架解决了哪些问题,那么接下来,是如何使用这个家伙。以及今天的任务解析清单主要解决了哪些问题,也就是实现了哪些特性。

当然这边这个项目是开源的,只是还没有做好没有上传仓库而已。

实现特性

okey,我们先来看看实现的特性,能够做什么。先前我们说过,这样的一个场景:

假设你要去超市买菜:为了方便买菜,你可以写一个购物清单,然后按照购物清单上面的每一个项,去购买东西。每一次写购物清单的时候,都要写上物品的名字,每次这样写实在是太麻烦了。不过,好在超市的商品有限,于是我们把这些商品都编上序号。于是下一次在书写购物清单的时候,只需要写上这个商品对应的编号就可以了,如果有特殊需求,只需要在商品序号上写上注释即可。同时有些常用的注释也有对应的序号,如果不是很特别的需求的话,直接写上这些注释序号就可以了。

然后我们先前还举个例子:

功能方法代码
class A{
	A1(){};
	A2(){};
}

class B{
	B1(){};
	B2(){};
}

class C{
	C1(){};
	C2(){};
}

class 购物{
	执行业务的方法(){
		B.B1();
		A.A2();
		C.C1();
	}
}

那么今天我们做到工作就是,这段代码变成了这样:

@TodoComponent
class A{
	A1(){};
	@TodoItem("买西红柿",index=1)
	A2(){};
}
@TodoComponent
class B{
	@TodoItem("买西红柿",index=0)
	B1(){};
	B2(){};
}
@TodoComponent
class C{
	@TodoItem("买西红柿",index=2)
	C1(){};
	C2(){};
}

@TodoList("买西红柿")
class 购物{
	//执行业务的方法(){
	//	B.B1();
	//	A.A2();
	//	C.C1();
	//}
	执行业务的方法(){
	  调度器.执行("买西红柿")
	}
}

当然这还是伪代码,因为还没有正式完工,不过也快了,因为接下来的工作并不难,预计6~8篇博文完成这个框架的编写。

涉及改动

那么关于这方面的话,主要就是实现注解,对应配置组件以及,我们的容器。
造个轮子-任务调度执行小框架-任务清单解析实现,手把手教你编写任务执行框架,java,spring,架构

然后是这里:
造个轮子-任务调度执行小框架-任务清单解析实现,手把手教你编写任务执行框架,java,spring,架构

那么这个的话就是基本改动的地方,那么接下来我们一一说明。

解析流程

所属启动流程

那么在开始之前的话,我们来看到这部分的所属整个项目启动的一个流程:
造个轮子-任务调度执行小框架-任务清单解析实现,手把手教你编写任务执行框架,java,spring,架构
所以的话,这个部分的话,其实还是我们的初始化部分,当我们的模板容器初始化完毕之后的话,之后就是我们的任务执行组件了。任务执行组件也是分为两大块,这里的话明天再说,重点是实现它的状态存储,让用户丝滑调用。

解析流程

那么现在我们来关系,这个这个家伙内部的一个流程:
造个轮子-任务调度执行小框架-任务清单解析实现,手把手教你编写任务执行框架,java,spring,架构

存储结构

这里的话,流程非常清晰,所以这里的话,我先来说说使用到的数据结构有哪些。

清单模板容器

首先是我们的清单模板容器:

package com.huterox.todoscheduler.core.global;

import com.huterox.todoscheduler.core.wapper.TodoListWrapper;

import java.io.Serializable;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 这里存放的是一个清单的模板,后期清单工厂通过这个清单模板去生成这个
 * 需要运行的对象,然后的话,执行器将这个对象进行执行
 *
 * 这里的话,它的数据结构是这样的:
 * {
 *     清单名字:{
 *          类型,等等信息
 *          执行方法:{
 *              0:需要执行的第一个方法,
 *              1:需要执行的第二个方法
 *          }
 *     }
 * }
 * */

public class TodoListTemplateMap implements Serializable {

    private static volatile TodoListTemplateMap INSTANCE;
    private Map<String, TodoListWrapper> map;

    private TodoListTemplateMap() {
        map = new ConcurrentHashMap<>();
    }
    public static TodoListTemplateMap getInstance() {
        if (INSTANCE == null) {
            synchronized (TodoListTemplateMap.class) {
                if (INSTANCE == null) {
                    INSTANCE = new TodoListTemplateMap();
                }
            }
        }
        return INSTANCE;
    }

    public Integer getSize(){
        return this.map.size();
    }

    public void put(String key, TodoListWrapper value) {
        map.put(key, value);
    }

    public TodoListWrapper get(String key) {
        return map.get(key);
    }

    public boolean containKey(String key){
        return map.containsKey(key);
    }
}
任务清单存储

之后的话是我们的任务清单的存储,这里的话我们封装为一个Wrapper对象

package com.huterox.todoscheduler.core.wapper;

import com.huterox.todoscheduler.core.enumType.TodoListElementType;
import com.huterox.todoscheduler.core.enumType.TodoListTempleCreateType;

import java.io.Serializable;
import java.util.Comparator;
import java.util.Map;
import java.util.TreeMap;

/**
 * 对清单的简单封装,主要是给创建模板使用的
 * */
public class TodoListWrapper implements Serializable {
    private String todoListName;
    private TodoListElementType todoListElementType;
    private TodoListTempleCreateType createType;
    private final Comparator<Integer> keyComparator = new Comparator<Integer>() {
        @Override
        public int compare(Integer key1, Integer key2) {
            // 根据键的大小进行比较
            return key1.compareTo(key2);
        }
    };
    private final Map<Integer, TodoItemMethodWrapper> sortedMap = new TreeMap<>(keyComparator);

    public TodoListTempleCreateType getCreateType() {
        return createType;
    }

    public void setCreateType(TodoListTempleCreateType createType) {
        this.createType = createType;
    }

    public TodoListWrapper() {
    }

    public String getTodoListName() {
        return todoListName;
    }

    public void setTodoListName(String todoListName) {
        this.todoListName = todoListName;
    }

    public TodoListElementType getTodoListElementType() {
        return todoListElementType;
    }

    public void setTodoListElementType(TodoListElementType todoListElementType) {
        this.todoListElementType = todoListElementType;
    }

    public Comparator<Integer> getKeyComparator() {
        return keyComparator;
    }

    public Map<Integer, TodoItemMethodWrapper> getItemMethodMap() {
        return sortedMap;
    }
}

任务清单任务项

之后的话是我们对应的任务项,这个玩意的话,其实就是开头提到的这个:
造个轮子-任务调度执行小框架-任务清单解析实现,手把手教你编写任务执行框架,java,spring,架构

所以的话,它是作用到方法上面的,我们也是把这个方法拿过来。

package com.huterox.todoscheduler.core.wapper;

import com.huterox.todoscheduler.core.enumType.TodoItemElementType;

import java.lang.reflect.Method;

/**
 * 将对应的方法和类存储起来,主要是为了创建模板
 * */
public class TodoItemMethodWrapper {

    private Object wrapperInstance;
    private Class<?> wrapperClass;
    private Method wrapperMethod;
    private TodoItemElementType todoItemElementType;

    public TodoItemMethodWrapper() {
    }

    public void setWrapperInstance(Object wrapperInstance) {
        this.wrapperInstance = wrapperInstance;
    }

    public TodoItemElementType getTodoItemElementType() {
        return todoItemElementType;
    }

    public void setTodoItemElementType(TodoItemElementType todoItemElementType) {
        this.todoItemElementType = todoItemElementType;
    }

    public void setWrapperClass(Class<?> wrapperClass) {
        this.wrapperClass = wrapperClass;
    }

    public Method getWrapperMethod() {
        return wrapperMethod;
    }

    public void setWrapperMethod(Method wrapperMethod) {
        this.wrapperMethod = wrapperMethod;
    }

    public TodoItemMethodWrapper(Object instance) {
        this.wrapperInstance = instance;
        this.wrapperClass = this.wrapperInstance.getClass();
    }

    public Object getWrapperInstance() {
        return wrapperInstance;
    }

    public Class<?> getWrapperClass() {
        return wrapperClass;
    }
}

这样一来的话,我们就把这些方法都封装好了,然后创建我们的任务清单。

定义清单

之后的话,是关于我们清单的定义,就是这个清单的结构有哪些?

任务清单

我们先来看到清单这个家伙:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TodoList {

    String TodoListName() default "";
    TodoListElementType TodoType() default TodoListElementType.StrongConsistency;

}

清单的话,其实就只有两个基本属性,一个是名字,然后是类型。这里又两个类型:

public enum TodoListElementType {

    StrongConsistency("StrongConsistency"),
    WeakConsistency("WeakConsistency");
    private String elementCode;

    TodoListElementType(String s) {
        this.elementCode = s;
    }

    public String getElementCode() {
        return elementCode;
    }

    public void setElementCode(String elementCode) {
        this.elementCode = elementCode;
    }
}

强类型是指,当任务失败之后,恢复全部执行前的状态,这个过程其实和你手动开启事务的过程是类似的没错,其实这个家伙被设计出来的原因之一的话,也就是简化手动开启事务的流程,打上几个注解,实现恢复状态的方法就可以了,其他的你什么都不用管,就算服务器宕机,我们这里也有日志系统保证恢复现场。尤其是多个方法处理的时候,用这个会舒服好多。并且在微服务场景之下,可以保证每一个微服务的任务正常执行,当出现服务调用失败的时候,通过编写失败状体回调,或者状态恢复代码,你完全可以选择,在调用B服务之前,获取到B服务对应数据的状态,然后用这个框架存起来,然后编写失败恢复代码,你可以手动复原B服务对应的数据。这个过程中,你只需要实现几个接口即可,状态的保存,宕机恢复完全不需要你处理。

那么弱类型的话,就是,只是恢复当前失败的某一个任务项,以及执行完毕的不进行恢复。

之后的话,我们的任务清单又两个方式加入创建,一个的话,就是这个注解,还有一个就是这个:
造个轮子-任务调度执行小框架-任务清单解析实现,手把手教你编写任务执行框架,java,spring,架构
这里的话,把昨天说要暴露的给暴露了,这个给用户用的。

定义任务项

这个的话,就只能通过注解创建了,在你要作为清单项执行的方法上面打上注解。

package com.huterox.todoscheduler.annotate;


import com.huterox.todoscheduler.core.enumType.TodoItemElementType;

import java.lang.annotation.*;

/**
 * 任务清单当中的item,主要作用在方法上面
 **/

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TodoItem {

    String[] TodoListNames();
    int[] TodoListItemIndex();
    TodoItemElementType[] TodoItemType();

}

这里的话,类型是数组,因为啥呢,一个方法可能在多个清单上面。这里你不用担心状态会混淆啥的,但是为了便于代码阅读,也是建议在使用的时候,不要重复太多,不然你在业务上面不好区分。

解析创建实现

okey,说完了前置的内容,我们来看到具体的实现,当然这里的话,还有这个对应的这个错位类型,当然这个没有啥,聪明如你一看就知道里面有啥,所以就不提了。我们直接看到这个解析的创建实现:

package com.huterox.todoscheduler.core.suports;


import com.huterox.todoscheduler.annotate.TodoItem;
import com.huterox.todoscheduler.annotate.TodoList;
import com.huterox.todoscheduler.common.BeanNameConvert;
import com.huterox.todoscheduler.core.enumType.TodoItemElementType;
import com.huterox.todoscheduler.core.enumType.TodoListElementType;
import com.huterox.todoscheduler.core.enumType.TodoListTempleCreateType;
import com.huterox.todoscheduler.core.global.TodoListTemplateMap;
import com.huterox.todoscheduler.core.wapper.BeanWrapper;
import com.huterox.todoscheduler.core.wapper.TodoItemMethodWrapper;
import com.huterox.todoscheduler.core.wapper.TodoListWrapper;
import com.huterox.todoscheduler.exception.TodoDuplicateDefinitionException;
import com.huterox.todoscheduler.exception.TodoItemMisMatchError;
import com.huterox.todoscheduler.exception.TodoMissingDefinitionException;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * 解析出清单模板,然后的话,把这个清单模板放在我们的global
 * 的TodListTemplateMap当中,因为后面清单工厂和任务调度器都要用到这个玩意
 * 所以TodoListTemplateMap是作为全局变量使用的
 * */
public class TodoListTemplateContext {

    private final TodoApplicationContext todoApplicationContext;
    private final TodoListTemplateMap todoListTemplateMap;

    //统计有TodoList的数量和实际清单的数量是否相同,如果不相同不好意思,创建失败
    private final Map<String,Integer> ListFromTodoItemAn = new HashMap<>();

    public TodoListTemplateContext() {
        //拿到容器
        todoApplicationContext = new TodoApplicationContext();
        //拿到TodoListTemplateMap
        todoListTemplateMap = TodoListTemplateMap.getInstance();
        //创建清单
        doCreateTodoListTemplate();
        //是否为安全创建
        doCheckSafeCreate();
    }

    private void doCheckSafeCreate(){
        if(todoListTemplateMap.getSize()!=this.ListFromTodoItemAn.size()){
            new TodoMissingDefinitionException("Missing task list definition",-1)
                    .printStackTrace();
            System.exit(-1);
        }
    }

    private void doCreateTodoListTemplate() {
        for (Map.Entry<String, BeanWrapper> beanWrapperEntry : this.todoApplicationContext
                .getFactoryBeanInstanceCache().entrySet())
        {
            /*
             * 由于历史遗留问题,我们在创建IOC容器的时候,beanName和全包名都放在了
             * map当中,这里主要是为了getBean方法,通过class也可以调用导致的,也就是有通过
             * className.getName() 获取到容器,所以存了两个,并且这两个对象是不同的可以删掉,但是先
             * 留着也许那天用上了。
             * */
            BeanWrapper beanWrapper = beanWrapperEntry.getValue();
            Class<?> clazz = beanWrapper.getWrapperClass();
            String beanName = BeanNameConvert.toLowerFirstCase(clazz.getSimpleName());
            String willCreateBeanName = beanWrapperEntry.getKey();
            if(beanName.equals(willCreateBeanName)){
                analysisTemplate(beanWrapper);
            }
        }
    }

    /**
     * 负责解析清单了,先解析出有哪些些清单
     * 注意由于这里支持两种模式创建清单:
     *  1. 像RabbitMQ一样直接在类上面创建
     *  2. 直接通过配置类创建
     * */
    private void analysisTemplate(BeanWrapper beanWrapper) {
        Class<?> clazz = beanWrapper.getWrapperClass();
        String beanName = BeanNameConvert.toLowerFirstCase(clazz.getSimpleName());

        //先解析这个TodoList类生成标签
        if(clazz.isAnnotationPresent(TodoList.class)){
            //发现是TodoList注解的类,于是先初始化生成
            TodoList todoListAn = clazz.getAnnotation(TodoList.class);
            String todoListName = todoListAn.TodoListName();
            TodoListElementType todoListElementType = todoListAn.TodoType();
            if("".equals(todoListName)){
                //如果没有写清单的名字,那么把当前的beanName作为清单的名字
                todoListName = beanName;
            }
            //获取到清单的名字
            if(todoListTemplateMap.containKey(todoListName)){
                TodoListWrapper todoListWrapper = todoListTemplateMap.get(todoListName);
                if(todoListWrapper.getCreateType()==TodoListTempleCreateType.UserCreateByCode){
                    //用户以及用代码创建了这个玩意,现在用注解又创建了一个是不允许的
                    new TodoDuplicateDefinitionException("There is a duplicate task list in the configuration",-1)
                            .printStackTrace();
                    System.exit(-1);
                } else if (todoListWrapper.getCreateType()==TodoListTempleCreateType.TodoListAnnotate) {
                    new TodoDuplicateDefinitionException("There is a duplicate task list in the annotation",-1)
                            .printStackTrace();
                    System.exit(-1);
                }else if (todoListWrapper.getCreateType()==TodoListTempleCreateType.TodoItemEarly){
                    //如果是提取创建的,将对应的信息进行修正
                    todoListWrapper.setTodoListElementType(todoListElementType);
                }
            }else {
                TodoListWrapper todoListWrapper = new TodoListWrapper();
                todoListWrapper.setTodoListName(todoListName);
                todoListWrapper.setTodoListElementType(todoListElementType);
                todoListWrapper.setCreateType(TodoListTempleCreateType.TodoListAnnotate);
                todoListTemplateMap.put(todoListName,todoListWrapper);
            }
        }
        //解析方法,把方法加入进来
        Method[] declaredMethods = clazz.getDeclaredMethods();
        for(Method method:declaredMethods){
            method.setAccessible(true);
            if(!(method.isAnnotationPresent(TodoItem.class))) continue;
            TodoItem todoItemAn = method.getAnnotation(TodoItem.class);

            //获取到这个家伙对应的清单信息
            String[] todoListNames = todoItemAn.TodoListNames();
            int[] itemIdxes = todoItemAn.TodoListItemIndex();
            TodoItemElementType[] todoItemElementTypes = todoItemAn.TodoItemType();
            if(!(todoListNames.length == itemIdxes.length && todoListNames.length == todoItemElementTypes.length)){
                new TodoItemMisMatchError("任务项数量与清单数量不匹配",-1).printStackTrace();
                System.exit(-1);
            }
            //将当前的方法,加入到对应的清单当中
            int indexM = 0;
            for(String todoListName:todoListNames){
                //进行一个简单记录,在方法当中清单的数量和实际通过配置以及TodoList注解创建的
                //清单数量是不是匹配的,因为存在,清单没有先初始化,但是方法先扫描到的情况。
                //所以为了安全,我们还是会选择先创建任务清单模板。最后在比对一下有没有对上数量
                //如果没有对上数量,不好意思,非法创建
                this.ListFromTodoItemAn.put(todoListName,1);
                TodoListWrapper todoListWrapper = null;
                //1. 先判断当前有没有这个清单,如果没有进行创建
                if(todoListTemplateMap.containKey(todoListName)){
                    todoListWrapper = todoListTemplateMap.get(todoListName);
                }else {
                    todoListWrapper = new TodoListWrapper();
                    todoListWrapper.setTodoListName(todoListName);
                    //这个信息暂时不知道,先默认生成先,后面等检测到了TodoList注解对应的真正的
                    //定义好了的信息,再修正就好了
                    todoListWrapper.setTodoListElementType(TodoListElementType.StrongConsistency);
                    todoListWrapper.setCreateType(TodoListTempleCreateType.TodoListAnnotate);
                    todoListTemplateMap.put(todoListName,todoListWrapper);
                }
                Map<Integer, TodoItemMethodWrapper> itemMethodMap = todoListWrapper.getItemMethodMap();
                TodoItemMethodWrapper todoItemMethodWrapper = new TodoItemMethodWrapper();
                todoItemMethodWrapper.setWrapperMethod(method);
                todoItemMethodWrapper.setWrapperClass(clazz);
                todoItemMethodWrapper.setWrapperInstance(beanWrapper.getWrapperInstance());
                todoItemMethodWrapper.setTodoItemElementType(todoItemElementTypes[indexM]);
                itemMethodMap.put(itemIdxes[indexM],todoItemMethodWrapper);
                indexM++;
            }
        }
    }

}

任务清单生命周期

okey,那么接下来是我们的最后一个部分,那就是这个家伙的生命周期。
造个轮子-任务调度执行小框架-任务清单解析实现,手把手教你编写任务执行框架,java,spring,架构

当然我们还有对应的失败的恢复周期。当然过程是一样的,只是叫你多实现一个恢复接口和错误处理接口,不实现,那就走默认

总结

okey,以上就是全部内容了,包括博文编写差不多三个小时了,不说了晚上加个班干高数去。现在是比赛中场,选手准备开启加速燃烧室。there is no way to pay nothing to get what you want!!!文章来源地址https://www.toymoban.com/news/detail-638099.html

到了这里,关于造个轮子-任务调度执行小框架-任务清单解析实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 任务调度框架-如何实现定时任务+RabbitMQ事务+手动ACK

    比如: 1.每天早上6点定时执行 2.每月最后一个工作日,考勤统计 3.每个月25号信用卡还款 4.会员生日祝福 5.每隔3秒,自动提醒 10分钟的超时订单的自动取消,每隔30秒或1分钟查询一次订单,拿当前的时间上前推10分钟 定时任务,资源会有误差的存在,如果使用定时任务 定时

    2024年02月08日
    浏览(39)
  • 【后端-Quartz】Springboot整合Quartz支持集群环境-设计业务与框架分离及实现定时任务调度

    我们的各个服务需要改造支持集群,现在的授权、日程使用的是基于内存的spring scheduler定时任务,如果部署多个节点,那么到了时间点,多个节点都会开始执行定时任务从而可能引起业务和性能上的问题。 服务中的定时任务比较轻量,为了避免引入redis、zookeeper、单独的定时

    2023年04月09日
    浏览(43)
  • linux-crontab每分钟定时执行/定时任务调度

    本文讲解linux上如何调用定时任务,如每分钟打印日志,每日24点执行日志切割脚本等等。 在Linux系统中,crontab命令是一个用于执行定时任务的命令, crond(crontab)是系统默认自带的定时服务 。我们可以通过编辑crontab文件来设置定时任务,使系统可以自动按照设定的时间和频率

    2024年02月06日
    浏览(59)
  • XXL-JOB 任务调度中心 后台任意命令执行漏洞

    在日常开发中,经常会用定时任务执行某些不紧急又非常重要的事情,例如批量结算,计算当日的订单量,当日的成本收入等。当存在大量定时任务的时候,任务的管理也会成为一个比较头痛的问题。xxl-job,就是一个比较成熟的分布式任务调度平台。XXL-JOB 任务调度中心系统

    2024年02月08日
    浏览(45)
  • 分布式定时任务调度框架Quartz

    Quartz是一个定时任务调度框架,比如你遇到这样的问题: 比如淘宝的待支付功能,后台会在你生成订单后24小时后,查看订单是否支付,未支付则取消订单 比如vip的每月自动续费功能 … 想定时在某个时间,去做某件事 Quartz是一套轻量级的任务调度框架,只需要定义了 Job(

    2024年02月04日
    浏览(45)
  • 分布式任务调度框架Power-Job

    在大型业务业务系统中,不可避免会出现一些需要定时执行需求的场景,例如定时同步数据,定时清洗数据,定时生成报表,大量机器一同执行某个任务,甚至有些需要分布式处理的任务例如需要更新一大批数据,单机耗时太长需要进行任务分发,利用集群的计算能力等等

    2024年02月04日
    浏览(48)
  • 太强了!全新一代分布式任务调度与计算框架!

    大家好,我是 Java陈序员 。 我们在工作开发中,离不开任务调度。通过指定的间隔时间执行各类操作,来完成无需用户操作的任务。 目前市场上,有一些编程语言本身自带的定时任务工具,如 Java 中 Timer。也有一些比较成熟的定时任务框架,如 Quartz。现在大部分系统都是使

    2024年02月03日
    浏览(49)
  • Flink源码解析四之任务调度和负载均衡

    jobmanager scheduler :这部分与 Flink 的任务调度有关。 CoLocationConstraint :这是一个约束类,用于确保某些算子的不同子任务在同一个 TaskManager 上运行。这通常用于状态共享或算子链的情况。 CoLocationGroup CoLocationGroupImpl :这些与 CoLocationConstraint 相关,定义了一组需要在同一个

    2024年02月06日
    浏览(48)
  • Flink源码解析八之任务调度和负载均衡

    jobmanager scheduler :这部分与 Flink 的任务调度有关。 CoLocationConstraint :这是一个约束类,用于确保某些算子的不同子任务在同一个 TaskManager 上运行。这通常用于状态共享或算子链的情况。 CoLocationGroup CoLocationGroupImpl :这些与 CoLocationConstraint 相关,定义了一组需要在同一个

    2024年02月05日
    浏览(44)
  • 【c#】Quartz开源任务调度框架学习及练习Demo

    Quartz是一个开源的任务调度框架,作用是支持开发人员可以定时处理业务,比如定时发布邮件等定时操作。 Quartz大致可以分为四部分,但是按功能分的话三部分就可以:schedule(调度器是schedule的一个调度单元)、job(任务)、Trigger(触发器) scedule功能:统筹任务调度, JOB:实现

    2024年02月08日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包