一次性入门三款分布式定时任务调度框架:Quartz、ElasticJob3.0、xxl-job

news2024/10/19 16:47:47

分布式定时任务调度框架(文末有源码)

  • 前言
  • 1、Quartz
    • 1.1 数据库
    • 1.2 maven依赖
    • 1.3 代码实现
      • 1.3.1 创建一个job
      • 1.3.1 为job设置trigger
    • 1.4 配置文件
    • 1.5 启动、测试
      • 1.1 单机
      • 1.2 集群
  • 2、ElasticJob
    • 2.1 下载zk
    • 2.2 新建三个类型的作业
    • 2.3 配置文件
    • 2.4 启动项目,测试数据
    • 2.5 分片作业(集群测试)
      • 2.5.1 **官方的三个分片策略:**
      • 2.5.2 启动三个实例,模拟集群
      • 2.5.3 模拟集群故障
    • 2.6 数据流作业
    • 2.7 控制台console
  • 3、xxl-job
    • 1.搭建调度中心(必须要搭)
      • 1.1 创建好数据库
      • 1.2 修改application.properties文件
      • 1.3 修改logback.xml文件
      • 1.4 启动项目
      • 1.5 打包部署
    • 2.springboot项目中集成
      • 2.1 maven依赖
      • 2.2 配置文件
      • 2.3 注入config
      • 2.4 新增job
      • 2.5 简单归纳一下
    • 3.结合控制台使用
      • 3.1 配置执行管理器
      • 3.2 新增一个任务
      • 3.3 启动
    • 4.用分片任务,来验证xxl-job的集群功能
      • 4.1 修改端口
      • 4.2 新建执行器
      • 4.3 新建任务代码+任务
      • 4.4 运行一次验证
    • 5.对Quartz的优化
  • 4、结语
  • 5、附录1
  • 6、附录2

前言

本来是打算水三篇文章的,但是最后想想还是打包一起,这样后来自己看也方便一点,所以本文略长,大家可以按需目录跳转阅读。每个框架都包含了入门的代码示例,文末会贴上源码链接,大家可以下载阅读。

本文主要是为了示例,包含了 单机和集群 的代码,一些基本的概念知识就不说了,大家可以去官网详细阅读。

1、Quartz

最经典的一款框架,下面两个框架都是基于Quartz改进的。本文版本用的最新版本:2.3.0
核心理念

  • scheduler:调度器
  • job:任务本身
  • trigger:触发器

1.1 数据库

Quartz是基于数据库来做任务调度的,所以我们要先把数据库构造好,用官网给的SQL脚本。
由于脚本太长了,放在这里占位置影响阅读,附录1有完整脚本,直接copy
如果大家有源码的,在src\org\quartz\impl\jdbcjobstore这个目录下面,也可以解压maven依赖,一样可以获取到SQL脚本

创建好的就这么11张表
在这里插入图片描述

1.2 maven依赖

 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-quartz</artifactId>
 </dependency>
 <dependency>
     <groupId>com.mchange</groupId>
     <artifactId>c3p0</artifactId>
     <version>0.10.0</version>
 </dependency>

我这里引入c3p0是因为会报连接错误,但是网上其他文章不用引入这个依赖,我猜测可能是版本不一样,然后某个Maven依赖冲突导致的。

1.3 代码实现

创建job的方式有两种,一种是比较古老的,用scheduler去绑定job和config,由于配置复杂,不是很推荐,推荐用spring bean的自动装配。

1.3.1 创建一个job

@DisallowConcurrentExecution注解是关键,用于集群中单个job只能被一个实例机器执行。

//禁止并发执行
@DisallowConcurrentExecution
//更新JobDataMap 副本
@PersistJobDataAfterExecution
public class ZedJob extends QuartzJobBean {
    private static final Logger logger = LoggerFactory.getLogger(ZedJob.class);

    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        logger.info("我是ZedJob");
    }
}

1.3.1 为job设置trigger

@Configuration
public class QuartzConfig {
    @Bean
    public JobDetail jobDetail(){
        return JobBuilder.newJob(ZedJob.class)
                // 指定任务的名称
                .withIdentity("zedJob")
                // 任务描述
                .withDescription("任务描述:这是一个任务")
                // 每次任务执行后进行存储
                .storeDurably()
                .build();
    }

    @Bean
    public Trigger trigger() {
        //创建触发器
        SimpleScheduleBuilder simpleScheduleBuilder1 = SimpleScheduleBuilder.repeatSecondlyForever(5);
        return TriggerBuilder.newTrigger()
                // 绑定工作任务
                .withIdentity("zedJob")
                .forJob(jobDetail())
                // 每隔 5 秒执行一次 job
                .withSchedule(simpleScheduleBuilder1)
                .build();
    }
}

这里的Schedule常用的有两种,一个是SimpleScheduleBuilder,一个是CronScheduleBuilder,写cron表达式的,大家可以按照需要选取。

1.4 配置文件

上面基本都有注释

spring:
  quartz:
    #存储方式,默认是内存memory
    job-store: jdbc
    #应用关闭时,是否等待定时任务执行完成
    wait-for-jobs-to-complete-on-shutdown: true
    properties:
      org:
        quartz:
          scheduler:
            #相同 Scheduler 名字的节点,形成一个 Quartz 集群
            instanceName: SC_Scheduler
            instanceId: AUTO
          jobStore:
            class: org.quartz.impl.jdbcjobstore.JobStoreTX
#            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
            dataSource: quartz_jobs
            #是否集群部署
            isClustered: true
            # 集群检查周期,单位为毫秒,可以自定义缩短时间。当某一个节点宕机的时候,其他节点等待多久后开始执行任务
            clusterCheckinInterval: 5000
          threadPool:
            threadCount: 25 # 线程池大小。默认为 10 。
            threadPriority: 5 # 线程优先级
            class: org.quartz.simpl.SimpleThreadPool # 线程池类型
          dataSource:
            #这个名字是上面的jobStore.dataSource定义的
            quartz_jobs:
              driver: com.mysql.cj.jdbc.Driver
              URL: jdbc:mysql://172.16.72.134:3306/quartz_jobs?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2b8&useUnicode=true
              user: root
              password: 123456

我这里挑几个比较重要的来说一下:

  • job-store:指定存储方式,如果要部署分布式集群,必须要选择jdbc
  • instanceName:同一个集群,instanceName要一样,quartz在数据库中是用名字来区分是否是一个集群的。
  • isClustered:这是集群的开启开关
  • dataSource:选择数据库集群后,才会有这个配置
  • quartz_jobs:命名记得一致

1.5 启动、测试

1.1 单机

启动单个服务,看看打印,都是正常的。
在这里插入图片描述

1.2 集群

只修改端口,启动两个实例,测试@DisallowConcurrentExecution 并发执行,记得数据库这些配置信息要一致
可以看到,我们第二个实例中,没有任何打印
在这里插入图片描述
我们关闭第一个实例,假装宕机,看看第二个实例能否正常接续工作
在这里插入图片描述
当关闭1后,我们可以看到,示例2中检测到了1的关闭,并且有打印三句话,这三句话的意思翻译一下:

  1. 检测到集群中有一个实例失去连接或者在重启
  2. 扫描是否有其他示例可以接待挂掉的那个主机继续执行任务
  3. 找到了1个实例,去继续执行

所以由此也可以看出quartz集群的能力和容错能力。

2、ElasticJob

ElasticJob把任务命名为作业,等同于任务,job,叫法不同而已,所以下面都用作业来说

2.1 下载zk

  1. 去官网下载最新版本:下载链接

  2. 解压,进入conf 路径下,将文件 zoo_sample.cfg 修改为 zoo.cfg

    mv zoo_sample.cfg zoo.cfg
    
  3. 在zk根目录下创建目录zkData

    mkdir zkData
    
  4. 打开 zoo.cfg 文件,修改 dataDir 路径为新创建的zkData路径

    dataDir=/usr/local/zookeeper/apache-zookeeper-3.9.2-bin/zkData
    
  5. 进入bin目录,启动zk

    ./zkServer.sh start
    
  6. 运行客户端,创建命名空间

    ./zkCli.sh
    
    create /elastic-job-test
    

2.2 新建三个类型的作业

ZedJob:普通的作业
FragmentationJob:分片作业
FlowJob:数据流作业

@Component
public class ZedJob implements SimpleJob {
    private static final Logger logger = LoggerFactory.getLogger(ZedJob.class);

    @Override
    public void execute(ShardingContext shardingContext) {
        logger.info("我是影流之主 Zed");
    }
}
@Component
public class FragmentationJob implements SimpleJob {
    private static final Logger logger = LoggerFactory.getLogger(FragmentationJob.class);

    @Override
    public void execute(ShardingContext shardingContext) {
        logger.info("分片任务");
        switch (shardingContext.getShardingItem()) {
            case 0:
                logger.info("分片0:{}",shardingContext.getShardingParameter());
                break;
            case 1:
                logger.info("分片1:{}",shardingContext.getShardingParameter());
                break;
            case 2:
                logger.info("分片2:{}",shardingContext.getShardingParameter());
                break;
            default:
                break;
        }
    }
}
@Component
public class FlowJob implements DataflowJob<UserInfo> {
    private static final Logger logger = LoggerFactory.getLogger(FlowJob.class);

    @Override
    public List<UserInfo> fetchData(ShardingContext shardingContext) {
        List<UserInfo> foos = new ArrayList<>();
        double random = Math.random();
        if (random > 0.5) {
            logger.info("fetchData------ {}", random);
            UserInfo foo = new UserInfo();
            foo.setUserName("小道仙");
            foos.add(foo);
        }
        return foos;
    }

    @Override
    public void processData(ShardingContext shardingContext, List<UserInfo> list) {
        logger.info("收到流数据");
        list.forEach(i -> logger.info("name为:{}", i.getUserName()));
    }
}

2.3 配置文件

大多都有注释,大家看看就行,其中shardingTotalCount必填,等待重试的间隔也很重要。

elasticjob:
  regCenter:
    #zookeeper 的ip:port
    serverLists: 172.16.72.133:2181
    #名命空间,和前面zk里面创建的一样就行
    namespace: elastic-job-test
    base-sleep-time-milliseconds: 10000
    # 等待重试的间隔时间的最大值,这个很重要,不然项目启动会出现timeout的报错
    max-sleep-time-milliseconds: 30000
  jobs:
    #我们创建的三个任务,在这里进行配置
    zedJob:
      #定时任务的全路径名
      elasticJobClass: com.wq.elasticjob.ZedJob
      #定时任务执行的cron表达式
      cron: 0/5 * * * * ?
      #分片数量
      shardingTotalCount: 1
    fragmentationJob:
      #定时任务的全路径名
      elasticJobClass: com.wq.elasticjob.FragmentationJob
      #定时任务执行的cron表达式
      cron: 0/10 * * * * ?
      #分片数量
      shardingTotalCount: 3
      #这是分片参数,代码中获取,记得加引号,不然获取不到
      shardingItemParameters: "0=text,1=image,2=video"
    flowJob:
      #定时任务的全路径名
      elasticJobClass: com.wq.elasticjob.FlowJob
      #定时任务执行的cron表达式
      cron: 0/10 * * * * ?
      #分片数量
      shardingTotalCount: 1

2.4 启动项目,测试数据

我们先看看普通的作业,这个没可说的,看看能否正常运行就好
在这里插入图片描述
接下来重点说说分片任务,以及流数据任务。

2.5 分片作业(集群测试)

2.5.1 官方的三个分片策略:

AverageAllocationJobShardingStrategy:根据分片项平均分片
如果分片不能整除,则不能整除的多余分片将依次追加到序号小的服务器。策略举例:
假设有3台服务器,
分成9片,则每台服务器分到的分片是:1【0,1,2】,2【3,4,5】,3【6,7,8】
分成8片,则每台服务器分到的分片是:1【0,1,6】,2【2,3,7】,3【4,5】
分成10片,则每台服务器分到的分片是:1【0,1,2】,2【3,4,5】,3【6,7,8】

OdevitySortByNameJobShardingStrategy:根据作业名称哈希值的奇偶数决定按照作业服务器 IP 升序或是降序的方式分片
缺点是,一旦分片数小于作业服务器数,作业将永远分配至IP地址靠前的服务器,导致IP地址靠后的服务器空闲

RotateServerByNameJobShardingStrategy:根据作业名称轮询分片
假设有3台服务器,顺序为 【0, 1, 2】,如果作业名的哈希值根据作业分片总数取模为 1, 作业节点顺序变为 【1, 2, 0】。

2.5.2 启动三个实例,模拟集群

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
回顾一下,我们分片任务的配置:shardingItemParameters: “0=text,1=image,2=video”,总数有三个,启动三个实例,刚好一个机器一个,而且参数也能打印出来,而且分片策略,默认采用的是平均分片。

2.5.3 模拟集群故障

现在我把三个集群中index为0的干掉,看看效果。
在这里插入图片描述
在这里插入图片描述
通过打印可以看到,本来三个集群一人一个,现在挂掉了一个,其中一个服务还是一个,另一个服务则是拥有了两个分片,到这里也就验证结束

2.6 数据流作业

回到我们流数据任务的代码:

    @Override
    public List<UserInfo> fetchData(ShardingContext shardingContext) {
        List<UserInfo> foos = new ArrayList<>();
        double random = Math.random();
        if (random > 0.5) {
            logger.info("fetchData------ {}", random);
            UserInfo foo = new UserInfo();
            foo.setUserName("小道仙");
            foos.add(foo);
        }
        return foos;
    }

    @Override
    public void processData(ShardingContext shardingContext, List<UserInfo> list) {
        logger.info("收到流数据");
        list.forEach(i -> logger.info("name为:{}", i.getUserName()));
    }

我们实现的DataflowJob接口,覆盖了两个方法,一个fetchData,一个processData

  • fetchData:对数据作处理
  • processData:如果fetchData方法中产生了数据(数据发生了改变),则会携带者数据进入这个方法

我们看看日志打印,当我们在fetchData中设置了userName后,就会进入processData方法,就会拿到我们设置的userName属性
在这里插入图片描述

2.7 控制台console

  1. 选择对应版本下载
    控制台官网下载:https://www.apache.org/dyn/closer.cgi/shardingsphere/elasticjob-ui-3.0.0-RC1/apache-shardingsphere-elasticjob-3.0.0-RC1-lite-ui-bin.tar.gz
  2. 解压后进入bin目录,选择start.bat双击启动
  3. 网页访问localhost:8088/,用户名/密码:root/root
  4. 按照下图三个步骤配置zk注册中心,然后就能使用了
    在这里插入图片描述

3、xxl-job

截止本文编写时候,xxl的最新Maven版本为2.4.1,所以我们就用最新的

我们把xxl-job看做两部分,一部分是搭建调度中心,一部分是代码中实现集成

1.搭建调度中心(必须要搭)

下载源码,仓库地址:
gitee地址:https://gitee.com/xuxueli0323/xxl-job/blob/master/doc/db/tables_xxl_job.sql
GitHub地址:https://github.com/xuxueli/xxl-job

1.1 创建好数据库

脚本在这个目录下面:doc/db/tables_xxl_job.sql

调度中心支持集群部署,集群情况下各节点务必连接同一个mysql实例;
如果mysql做主从,调度中心集群节点务必强制走主库;

这里给出所有数据库的作用:

  • xxl_job_lock:任务调度锁表;
  • xxl_job_group:执行器信息表,维护任务执行器信息;
  • xxl_job_info:调度扩展信息表: 用于保存XXL-JOB调度任务的扩展信息,如任务分组、任务名、机器地址、执行器、执行入参和报警邮件等等;
  • xxl_job_log:调度日志表: 用于保存XXL-JOB任务调度的历史信息,如调度结果、执行结果、调度入参、调度机器和执行器等等;
  • xxl_job_log_report:调度日志报表:用户存储XXL-JOB任务调度日志的报表,调度中心报表功能页面会用到;
  • xxl_job_logglue:任务GLUE日志:用于保存GLUE更新历史,用于支持GLUE的版本回溯功能;
  • xxl_job_registry:执行器注册表,维护在线的执行器和调度中心机器地址信息;
  • xxl_job_user:系统用户表;

不想去找的直接文末附录二有完整的SQL脚本,直接copy

1.2 修改application.properties文件

修改server.port为自己需要的
修改spring.datasource.url,数据库配置为自己的
修改spring.mail.username和from为自己的实际邮箱地址(不修改也可以,这个就是通知用的)

1.3 修改logback.xml文件

将name=“log.path” 这个路径修改为自己的路径,并且在路径下创建xxl-job-admin.log文件,如果你不修改用默认的也行。

1.4 启动项目

浏览器访问:localhost:8088/xxl-job-admin/,默认用户名密码为admin,123456
出现下面这个界面则搭建成功
在这里插入图片描述

1.5 打包部署

生产环境下,配置好以后,打包部署到服务器即可

2.springboot项目中集成

2.1 maven依赖

<dependency>
    <groupId>com.xuxueli</groupId>
    <artifactId>xxl-job-core</artifactId>
    <version>2.4.1</version>
</dependency>

2.2 配置文件

xxl:
  job:
    admin:
      #如调度中心集群部署存在多个地址则用逗号分隔。执行器将会使用该地址进行"执行器心跳注册"和"任务结果回调";为空则关闭自动注册
      addresses: http://127.0.0.1:8088/xxl-job-admin
    executor:
      appname: zed-demo
      logpath:
      logretentiondays: 30
      #执行器IP:默认为空表示自动获取IP
      ip: 127.0.0.1
      #默认为9999
      port: 9999
      #优先使用该配置作为注册地址,为空时使用内嵌服务 ”IP:PORT“ 作为注册地址
      address:
    #执行器通讯TOKEN [选填]:非空时启用; 要和调度中心服务部署配置的accessToken一致
    accessToken: default_token

2.3 注入config

这个config是官方源码,内容一样,但是必须要copy进我们自己的项目里

@Configuration
public class XxlJobConfig {
    private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);

    @Value("${xxl.job.admin.addresses}")
    private String adminAddresses;

    @Value("${xxl.job.accessToken}")
    private String accessToken;

    @Value("${xxl.job.executor.appname}")
    private String appname;

    @Value("${xxl.job.executor.address}")
    private String address;

    @Value("${xxl.job.executor.ip}")
    private String ip;

    @Value("${xxl.job.executor.port}")
    private int port;

    @Value("${xxl.job.executor.logpath}")
    private String logPath;

    @Value("${xxl.job.executor.logretentiondays}")
    private int logRetentionDays;


    @Bean
    public XxlJobSpringExecutor xxlJobExecutor() {
        logger.info(">>>>>>>>>>> xxl-job config init.");
        XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
        xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
        xxlJobSpringExecutor.setAppname(appname);
        xxlJobSpringExecutor.setAddress(address);
        xxlJobSpringExecutor.setIp(ip);
        xxlJobSpringExecutor.setPort(port);
        xxlJobSpringExecutor.setAccessToken(accessToken);
        xxlJobSpringExecutor.setLogPath(logPath);
        xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);

        return xxlJobSpringExecutor;
    }

    /**
     * 针对多网卡、容器内部署等情况,可借助 "spring-cloud-commons" 提供的 "InetUtils" 组件灵活定制注册IP;
     *
     *      1、引入依赖:
     *          <dependency>
     *             <groupId>org.springframework.cloud</groupId>
     *             <artifactId>spring-cloud-commons</artifactId>
     *             <version>${version}</version>
     *         </dependency>
     *
     *      2、配置文件,或者容器启动变量
     *          spring.cloud.inetutils.preferred-networks: 'xxx.xxx.xxx.'
     *
     *      3、获取IP
     *          String ip_ = inetUtils.findFirstNonLoopbackHostInfo().getIpAddress();
     */

}

2.4 新增job

这里用最常用最推荐的一种写法,就是将任务绑定在方法上,@XxlJob注解标明每一个任务。当然还有绑定在Bean上的,不过这样就会写很多Bean,用方法的话,一个类就够了。

@Component
public class XxlJobFactory {
    private static Logger logger = LoggerFactory.getLogger(XxlJobFactory.class);

    @XxlJob("zedJobTest")
    public void zedJobTest(){
        logger.info("这是zedJobTest");
    }
}

2.5 简单归纳一下

我们在springBoot项目集成的时候,有几个比较关键的点,我在这里给大家总结一下,免得绕进去。

  1. 第一步搭建的调度中心,你可以理解为es job 的zookeeper一样,或者nacos这样的角色,它是一个注册中心,是整个框架的驱动核心,采用db的方式来进行服务的注册。
  2. xxl.job.admin:这个在springboot中的配置,就是配置第一步的调度中心的,地址前面一定要加http
  3. xxl.job.executor:这个是接下来要说的执行管理器,去执行任务的executor,它配置在我们的网页控制台中。这个的ip和端口是单独分开的,专门控制executor
  4. 很多配置都是空的,因为都有默认的,但是我们在注入XxlJobConfig的时候必须要用,所以空着就空着

3.结合控制台使用

3.1 配置执行管理器

新增一个执行管理器,这就是我们前面说到的,xxl.job.executor配置所控制的东西,它有一个默认的,我们不用默认的用自己的。
在这里插入图片描述
在这里插入图片描述
这个appName一定要和xxl.job.executor里面的appname一样,一般默认自动注册就好,如果自动注册不行,就手动录入,输入我们的ip和端口,这个ip和端口,也一定要和xxl.job.executor.port一致

3.2 新增一个任务

在这里插入图片描述
这里面最主要注意三个点,就是我标出来的这三个
在这里插入图片描述

  1. 执行器选择我们第二步中创建的执行器
  2. 运行模式常用Bean
  3. 然后jobHander要和代码中,注解@XxlJob中的Value一致

其他的根据自己需求改写就行

3.3 启动

在这里插入图片描述
这里选择执行一次,忽略corn表达式,只执行一次,选择下面的启动,才会走corn表达式逻辑。

执行一次这里,可以加任务参数和重新指定机器地址,由于我们执行器里面配置好了的,所以不用填写让它自动获取。
在这里插入图片描述

看看控制台打印,任务是调动成功了的。
在这里插入图片描述
然后数据库里,也可以看到我们新增的任务,还有其他表的信息
在这里插入图片描述

4.用分片任务,来验证xxl-job的集群功能

4.1 修改端口

修改springboot的端口和executor的port,启动三个实例

4.2 新建执行器

新建一个执行器fragmentatio
在这里插入图片描述
这里自动注册如果获取不到,我们就手动录入,三个不同的端口之间用逗号分隔。外面查看也是正确的。
在这里插入图片描述

4.3 新建任务代码+任务

    /**
     * 2、分片广播任务
     */
    @XxlJob("shardingJobHandler")
    public void shardingJobHandler(String param) throws Exception {
        int shardTotal = XxlJobHelper.getShardTotal();
        int index = XxlJobHelper.getShardIndex();
        logger.info("总共:{}个分片,当前的index为:{}", shardTotal, index);
    }

记得路由策略选择分片广播
在这里插入图片描述

4.4 运行一次验证

我们看看控制台打印,我这里贴一个就行了,三个实例,总共3个分片,index为0,1,2,大家可以根据分片总数和index,自己去实现分片处理逻辑,比如取模。
在这里插入图片描述

5.对Quartz的优化

xxl-job,是徐雪里基于Quartz改进来的,Quartz有下面几点不足:

  1. 调用API的的方式操作任务,不人性化;
  2. 需要持久化业务QuartzJobBean到底层数据表中,系统侵入性相当严重。
  3. 调度逻辑和QuartzJobBean耦合在同一个项目中,这将导致一个问题,在调度任务数量逐渐增多,同时调度任务逻辑逐渐加重的情况下,此时调度系统的性能将大大受限于业务;
  4. quartz底层以“抢占式”获取DB锁并由抢占成功节点负责运行任务,会导致节点负载悬殊非常大;而XXL-JOB通过执行器实现“协同分配式”运行任务,充分发挥集群优势,负载各节点均衡。

XXL-JOB弥补了quartz的上述不足之处

4、结语

都看到这里了,给我点个赞和关注不过分吧,如果你只是使用分布式任务调度框架,本文的示例绝对够用,如果你们项目很庞大而且很复杂,那么还要去官网查看更详细的配置。

本文完整项目代码GitHub地址
https:https://github.com/wangqing-github/DubboAndNacos.git
ssh:git@github.com:wangqing-github/DubboAndNacos.git
有三个分支,代码都是独立的,大家可以从主干切换。
在这里插入图片描述

5、附录1

Quartz的数据库SQL脚本:

#
# Quartz seems to work best with the driver mm.mysql-2.0.7-bin.jar
#
# PLEASE consider using mysql with innodb tables to avoid locking issues
#
# In your Quartz properties file, you'll need to set
# org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#

DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
DROP TABLE IF EXISTS QRTZ_LOCKS;
DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
DROP TABLE IF EXISTS QRTZ_CALENDARS;


CREATE TABLE QRTZ_JOB_DETAILS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    JOB_NAME  VARCHAR(200) NOT NULL,
    JOB_GROUP VARCHAR(200) NOT NULL,
    DESCRIPTION VARCHAR(250) NULL,
    JOB_CLASS_NAME   VARCHAR(250) NOT NULL,
    IS_DURABLE VARCHAR(1) NOT NULL,
    IS_NONCONCURRENT VARCHAR(1) NOT NULL,
    IS_UPDATE_DATA VARCHAR(1) NOT NULL,
    REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
    JOB_DATA BLOB NULL,
    PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
);

CREATE TABLE QRTZ_TRIGGERS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    JOB_NAME  VARCHAR(200) NOT NULL,
    JOB_GROUP VARCHAR(200) NOT NULL,
    DESCRIPTION VARCHAR(250) NULL,
    NEXT_FIRE_TIME BIGINT(13) NULL,
    PREV_FIRE_TIME BIGINT(13) NULL,
    PRIORITY INTEGER NULL,
    TRIGGER_STATE VARCHAR(16) NOT NULL,
    TRIGGER_TYPE VARCHAR(8) NOT NULL,
    START_TIME BIGINT(13) NOT NULL,
    END_TIME BIGINT(13) NULL,
    CALENDAR_NAME VARCHAR(200) NULL,
    MISFIRE_INSTR SMALLINT(2) NULL,
    JOB_DATA BLOB NULL,
    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
        REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP)
);

CREATE TABLE QRTZ_SIMPLE_TRIGGERS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    REPEAT_COUNT BIGINT(7) NOT NULL,
    REPEAT_INTERVAL BIGINT(12) NOT NULL,
    TIMES_TRIGGERED BIGINT(10) NOT NULL,
    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);

CREATE TABLE QRTZ_CRON_TRIGGERS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    CRON_EXPRESSION VARCHAR(200) NOT NULL,
    TIME_ZONE_ID VARCHAR(80),
    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);

CREATE TABLE QRTZ_SIMPROP_TRIGGERS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    STR_PROP_1 VARCHAR(512) NULL,
    STR_PROP_2 VARCHAR(512) NULL,
    STR_PROP_3 VARCHAR(512) NULL,
    INT_PROP_1 INT NULL,
    INT_PROP_2 INT NULL,
    LONG_PROP_1 BIGINT NULL,
    LONG_PROP_2 BIGINT NULL,
    DEC_PROP_1 NUMERIC(13,4) NULL,
    DEC_PROP_2 NUMERIC(13,4) NULL,
    BOOL_PROP_1 VARCHAR(1) NULL,
    BOOL_PROP_2 VARCHAR(1) NULL,
    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
    REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);

CREATE TABLE QRTZ_BLOB_TRIGGERS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    BLOB_DATA BLOB NULL,
    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);

CREATE TABLE QRTZ_CALENDARS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    CALENDAR_NAME  VARCHAR(200) NOT NULL,
    CALENDAR BLOB NOT NULL,
    PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
);

CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_GROUP  VARCHAR(200) NOT NULL,
    PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
);

CREATE TABLE QRTZ_FIRED_TRIGGERS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    ENTRY_ID VARCHAR(95) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    INSTANCE_NAME VARCHAR(200) NOT NULL,
    FIRED_TIME BIGINT(13) NOT NULL,
    SCHED_TIME BIGINT(13) NOT NULL,
    PRIORITY INTEGER NOT NULL,
    STATE VARCHAR(16) NOT NULL,
    JOB_NAME VARCHAR(200) NULL,
    JOB_GROUP VARCHAR(200) NULL,
    IS_NONCONCURRENT VARCHAR(1) NULL,
    REQUESTS_RECOVERY VARCHAR(1) NULL,
    PRIMARY KEY (SCHED_NAME,ENTRY_ID)
);

CREATE TABLE QRTZ_SCHEDULER_STATE
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    INSTANCE_NAME VARCHAR(200) NOT NULL,
    LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
    CHECKIN_INTERVAL BIGINT(13) NOT NULL,
    PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
);

CREATE TABLE QRTZ_LOCKS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    LOCK_NAME  VARCHAR(40) NOT NULL,
    PRIMARY KEY (SCHED_NAME,LOCK_NAME)
);


commit;

6、附录2

xxl的sql脚本

CREATE database if NOT EXISTS `xxl_job` default character set utf8mb4 collate utf8mb4_unicode_ci;
use `xxl_job`;

SET NAMES utf8mb4;

CREATE TABLE `xxl_job_info` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `job_group` int(11) NOT NULL COMMENT '执行器主键ID',
  `job_desc` varchar(255) NOT NULL,
  `add_time` datetime DEFAULT NULL,
  `update_time` datetime DEFAULT NULL,
  `author` varchar(64) DEFAULT NULL COMMENT '作者',
  `alarm_email` varchar(255) DEFAULT NULL COMMENT '报警邮件',
  `schedule_type` varchar(50) NOT NULL DEFAULT 'NONE' COMMENT '调度类型',
  `schedule_conf` varchar(128) DEFAULT NULL COMMENT '调度配置,值含义取决于调度类型',
  `misfire_strategy` varchar(50) NOT NULL DEFAULT 'DO_NOTHING' COMMENT '调度过期策略',
  `executor_route_strategy` varchar(50) DEFAULT NULL COMMENT '执行器路由策略',
  `executor_handler` varchar(255) DEFAULT NULL COMMENT '执行器任务handler',
  `executor_param` varchar(512) DEFAULT NULL COMMENT '执行器任务参数',
  `executor_block_strategy` varchar(50) DEFAULT NULL COMMENT '阻塞处理策略',
  `executor_timeout` int(11) NOT NULL DEFAULT '0' COMMENT '任务执行超时时间,单位秒',
  `executor_fail_retry_count` int(11) NOT NULL DEFAULT '0' COMMENT '失败重试次数',
  `glue_type` varchar(50) NOT NULL COMMENT 'GLUE类型',
  `glue_source` mediumtext COMMENT 'GLUE源代码',
  `glue_remark` varchar(128) DEFAULT NULL COMMENT 'GLUE备注',
  `glue_updatetime` datetime DEFAULT NULL COMMENT 'GLUE更新时间',
  `child_jobid` varchar(255) DEFAULT NULL COMMENT '子任务ID,多个逗号分隔',
  `trigger_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '调度状态:0-停止,1-运行',
  `trigger_last_time` bigint(13) NOT NULL DEFAULT '0' COMMENT '上次调度时间',
  `trigger_next_time` bigint(13) NOT NULL DEFAULT '0' COMMENT '下次调度时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE `xxl_job_log` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `job_group` int(11) NOT NULL COMMENT '执行器主键ID',
  `job_id` int(11) NOT NULL COMMENT '任务,主键ID',
  `executor_address` varchar(255) DEFAULT NULL COMMENT '执行器地址,本次执行的地址',
  `executor_handler` varchar(255) DEFAULT NULL COMMENT '执行器任务handler',
  `executor_param` varchar(512) DEFAULT NULL COMMENT '执行器任务参数',
  `executor_sharding_param` varchar(20) DEFAULT NULL COMMENT '执行器任务分片参数,格式如 1/2',
  `executor_fail_retry_count` int(11) NOT NULL DEFAULT '0' COMMENT '失败重试次数',
  `trigger_time` datetime DEFAULT NULL COMMENT '调度-时间',
  `trigger_code` int(11) NOT NULL COMMENT '调度-结果',
  `trigger_msg` text COMMENT '调度-日志',
  `handle_time` datetime DEFAULT NULL COMMENT '执行-时间',
  `handle_code` int(11) NOT NULL COMMENT '执行-状态',
  `handle_msg` text COMMENT '执行-日志',
  `alarm_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '告警状态:0-默认、1-无需告警、2-告警成功、3-告警失败',
  PRIMARY KEY (`id`),
  KEY `I_trigger_time` (`trigger_time`),
  KEY `I_handle_code` (`handle_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE `xxl_job_log_report` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `trigger_day` datetime DEFAULT NULL COMMENT '调度-时间',
  `running_count` int(11) NOT NULL DEFAULT '0' COMMENT '运行中-日志数量',
  `suc_count` int(11) NOT NULL DEFAULT '0' COMMENT '执行成功-日志数量',
  `fail_count` int(11) NOT NULL DEFAULT '0' COMMENT '执行失败-日志数量',
  `update_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `i_trigger_day` (`trigger_day`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE `xxl_job_logglue` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `job_id` int(11) NOT NULL COMMENT '任务,主键ID',
  `glue_type` varchar(50) DEFAULT NULL COMMENT 'GLUE类型',
  `glue_source` mediumtext COMMENT 'GLUE源代码',
  `glue_remark` varchar(128) NOT NULL COMMENT 'GLUE备注',
  `add_time` datetime DEFAULT NULL,
  `update_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE `xxl_job_registry` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `registry_group` varchar(50) NOT NULL,
  `registry_key` varchar(255) NOT NULL,
  `registry_value` varchar(255) NOT NULL,
  `update_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `i_g_k_v` (`registry_group`,`registry_key`,`registry_value`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE `xxl_job_group` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `app_name` varchar(64) NOT NULL COMMENT '执行器AppName',
  `title` varchar(12) NOT NULL COMMENT '执行器名称',
  `address_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '执行器地址类型:0=自动注册、1=手动录入',
  `address_list` text COMMENT '执行器地址列表,多地址逗号分隔',
  `update_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE `xxl_job_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(50) NOT NULL COMMENT '账号',
  `password` varchar(50) NOT NULL COMMENT '密码',
  `role` tinyint(4) NOT NULL COMMENT '角色:0-普通用户、1-管理员',
  `permission` varchar(255) DEFAULT NULL COMMENT '权限:执行器ID列表,多个逗号分割',
  PRIMARY KEY (`id`),
  UNIQUE KEY `i_username` (`username`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE `xxl_job_lock` (
  `lock_name` varchar(50) NOT NULL COMMENT '锁名称',
  PRIMARY KEY (`lock_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT INTO `xxl_job_group`(`id`, `app_name`, `title`, `address_type`, `address_list`, `update_time`) VALUES (1, 'xxl-job-executor-sample', '示例执行器', 0, NULL, '2018-11-03 22:21:31' );
INSERT INTO `xxl_job_info`(`id`, `job_group`, `job_desc`, `add_time`, `update_time`, `author`, `alarm_email`, `schedule_type`, `schedule_conf`, `misfire_strategy`, `executor_route_strategy`, `executor_handler`, `executor_param`, `executor_block_strategy`, `executor_timeout`, `executor_fail_retry_count`, `glue_type`, `glue_source`, `glue_remark`, `glue_updatetime`, `child_jobid`) VALUES (1, 1, '测试任务1', '2018-11-03 22:21:31', '2018-11-03 22:21:31', 'XXL', '', 'CRON', '0 0 0 * * ? *', 'DO_NOTHING', 'FIRST', 'demoJobHandler', '', 'SERIAL_EXECUTION', 0, 0, 'BEAN', '', 'GLUE代码初始化', '2018-11-03 22:21:31', '');
INSERT INTO `xxl_job_user`(`id`, `username`, `password`, `role`, `permission`) VALUES (1, 'admin', 'e10adc3949ba59abbe56e057f20f883e', 1, NULL);
INSERT INTO `xxl_job_lock` ( `lock_name`) VALUES ( 'schedule_lock');

commit;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2218614.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Windows下配置Nginx和PHP

之前在Windows开发php项目用的是phpstudy&#xff0c;好用的很。但是phpstudy好久没有更新了&#xff0c;感觉PHP像没有人再用了一样。但是PHP拿来开发小系统&#xff0c;还是很高效的&#xff0c;今天记录如何在Windows环境下配置Nginx和PHP。 1. 配置nginx Nginx软件下载解压…

基于Springboot+Vue的宠物管理系统(含源码数据库)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 这个系…

实现双向链表的增删改查

头文件 #pragma once #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <stdlib.h> #include <stdbool.h> typedef int LTDataType; typedef struct ListNode {LTDataType data;struct ListNode* prev;struct ListNode* next; } LTNode; //v…

QGraphics类型学习使用【Qt】【C++】

QGraphics类型学习使用 需求过程全部完整代码 首先已知&#xff0c;QGraphicsView&#xff0c;QGraphicsScene, QGraphicsItem&#xff0c;分别称为&#xff1a;视图&#xff0c;场景&#xff0c;图元&#xff0c;图表就是各种各样的元素&#xff0c;图片元素&#xff0c;线条元…

react18中在列表项中如何使用useRef来获取每项的dom对象

在react中获取dom节点都知道用ref&#xff0c;但是在一个列表循环中&#xff0c;这样做是行不通的&#xff0c;需要做进一步的数据处理。 实现效果 需求&#xff1a;点击每张图片&#xff0c;当前图片出现在可视区域。 代码实现 .box{border: 1px solid #000;list-style: …

ParallelsDesktop20最新版本虚拟机 一键切换系统 游戏娱乐两不误

让工作生活更高效&#xff1a;Parallels Desktop 20最新版本虚拟机的神奇之处 大家好&#xff01;&#x1f44b; 今天我要跟大家安利一款让我工作效率飞升的神器——Parallels Desktop 20最新版本虚拟机。作为一个日常需要在不同操作系统间来回穿梭的人&#xff0c;这款软件简直…

react18中的计算属性及useMemo的性能优化技巧

react18里面的计算属性和使用useMemo来提升组件性能的方法 计算属性 实现效果 代码实现 函数式组件极简洁的实现&#xff0c;就这样 import { useState } from "react"; function FullName() {const [firstName, setFirstName] useState("");const [la…

OpenCV高级图形用户界面(14)交互式地选择一个或多个感兴趣区域函数selectROIs()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 允许用户在给定的图像上选择多个 ROI。 该函数创建一个窗口&#xff0c;并允许用户使用鼠标来选择多个 ROI。控制方式&#xff1a;使用空格键或…

明日周刊-第23期

十月已过半&#xff0c;气温也转凉了&#xff0c;大家注意保温哦。冬吃萝卜&#xff0c;夏吃姜&#xff0c;在快要到来的冬季大家可以选择多吃点萝卜。 配图是本周末去商场抓娃娃的时候拍的照片&#xff0c;现在抓娃娃单次普遍都控制在1块钱以下了&#xff0c;还记得多年前的抓…

智能手表PPG技术原理:【图文讲解】

光体积变化描记图法&#xff08;Photoplethysmography&#xff0c;简称PPG&#xff09;是借光电手段在活体组织中监测血液容积变化的一种无创监测方法 目前智能手表比较标配的功能&#xff1a;血糖、血压、心电、心率、血氧 1&#xff1a;人体血管 先温习一下&#xff0c;人…

Java项目-基于Springboot的智慧养老平台项目(源码+文档).zip

作者&#xff1a;计算机学长阿伟 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、ElementUI等&#xff0c;“文末源码”。 开发运行环境 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBoot、SpringClud、Vue、Mybaits Plus、ELementUI工具&…

TikTok广告账号被封?常见原因及解决方法分享

TikTok广告投放往往会给我们的账号带来高效曝光和精准流量&#xff0c;但同时许多用户也面临着一个困扰——广告账号被封禁的问题。将在此文一起商讨TikTok广告账号被封禁的原因&#xff0c;分析平台的具体规定&#xff0c;提供解决问题的应对策略&#xff0c;帮助大家有效规避…

PRCV 2024 - Day 1

2024年10月18日至10月20日&#xff0c;第七届中国模式识别与计算机视觉大会&#xff08;The 7th Chinese Conference on Pattern Recognition and Computer Vision, PRCV 2024&#xff09;在新疆乌鲁木齐的新疆国际会展中心举办&#xff0c;是国内顶级的模式识别和计算机视觉领…

专家系统简介

本文对基于规则的专家系统进行简介&#xff0c;举例专家系统的结构类似 MYCIN 系统&#xff0c;同时串联介绍专家系统的各种思想。需要注意的是&#xff0c;本文所述仅是专家系统的一种实现途径&#xff0c;其依赖规则进行知识表示和推理&#xff0c;另外还有基于语义网络、框架…

详解23种设计模式——第一部分:概述+创建型模式

目录 1. 概述 2. 创建型模式 2.1 简单&#xff08;静态&#xff09;工厂模式 2.1.1 介绍 2.1.2 实现 2.2 工厂模式 2.3 抽象工厂模式 2.4 单例模式 2.4.1 饿汉模式 2.4.2 懒汉模式 2.4.3 线程安全的懒汉式 2.4.4 DCL单例 - 高性能的懒汉式 2.5 建造者模式 2.6 原…

linux模拟:chrony同步时间

实验材料&#xff1a; 服务器&#xff1a;linux,红帽-9.1 客户端&#xff1a;linux&#xff0c;乌班图-18.4 Server/client; 安装chrony yum install -y chrony 查看chrony的状态&#xff1a; systemctl status chronyd 服务器&#xff1a; 在/etc/chrony.conf文件里面…

理解VSCODE基于配置的设置,避免臃肿

这节课我们讲两点&#xff1a; &#xff08;一&#xff09;下载、安装、汉化及美化 VSCODE&#xff1b; &#xff08;二&#xff09;理解VSCODE中基于配置&#xff08;Profiles&#xff09;的设置&#xff08;Settings&#xff09;&#xff0c;让 VSCODE 保持清爽。 &#xff0…

无极低码课程【redis windows下服务注册密码修改】

下载Windows版本的Redis linux环境 (自行下载) 1.打开官网https://redis.io/downloads/ windows环境 1.打开github https://github.com/microsoftarchive/redis/releases 然后选择你喜欢的版本zip或msi下载 2.这里下载zip版,解压后后,打开安装目录 3.双击redis-server…

学习莫烦python---神经网络

一、卷积神经网络区别 1、“卷积” 和 “神经网络”. 卷积也就是说神经网络不再是对每个像素的输入信息做处理了,而是图片上每一小块像素区域进行处理, 这种做法加强了图片信息的连续性. 使得神经网络能看到图形, 而非一个点. 这种做法同时也加深了神经网络对图片的理解 –翻译…

快充协议有哪些,都有哪些特点

什么是PD协议 PD协议是一种充电协议&#xff0c;全称为“USB Power Delivery&#xff08;USB PD&#xff09;”&#xff0c;是由USB-IF&#xff08;USB Implementers Forum&#xff09;组织制定的一种标准协议‌。它是一种基于USB接口的快速充电技术&#xff0c;可以实现高达1…