搭建一个中心化的定时服务
1. 背景
在物联网络,很多设备之间都在进行交互,其中云端在远程交流中起到了很重要的作用。比如,一台设备想进行调温,但是需要知道此时房间的温度,那就需要定时去查询传感器测出来的房间温度,如果温度过高,就降低温度, 否则就升高温度。在这个过程中云端就需要对传感器的状态进行监控,其中的定时任务就起到了作用。
什么是定时任务呢?
定时任务简答来说就是在指定时间内触发执行某个动作,比如早上设备了闹钟,提醒你起床。
2. 定时搭建的方式
2.1.1 Spring提供的注解
在SpringBoot应用中,有提供@EnableScheduling、@Scheduled来实现定时。其中:
-
@Scheduled注解是SpringBoot提供的⽤于定时任务控制的注解,主要⽤于控制任务在某个指定时间执⾏,或者每隔⼀段时间执⾏。 -
注意需要配合
@EnableScheduling使⽤,定时任务需要在配置类上添加@EnableScheduling,表示对定时任务的支持;在对应执行任务的方法上添加@Scheduled,声明需要执行定时任务的方法。
@Scheduled主要有三种配置执⾏时间的⽅式:cron、fixedRate、fixedDelay。例子分别是:
@Scheduled(cron = "0 0/5 * * * ?")// 每5分钟执行一次@Scheduled(fixedDelay = 10000)// fixedDelay 表示固定延迟时间,上个任务完成后,延迟多长时间执行@Scheduled(fixedRate = 1000 * 60)// 按照一定频率执行任务,每隔1分钟执行一次
2.1.2 具体应用
使用@Scheduled注解的方式非常简单,首先我们创建一个类,并且加上@Component注解,确保可以被扫描。 然后我们在方法上加上这里要用到的定时任务注解@Scheduled() 其中,有个参数 cron="",是用来写入cron表达式的。
@Component
public class CronJob{// 定义每隔5分钟执行一次“Hello World”打印`@Scheduled`(cron="0 0/5 * * * ?")public void printHWScheduled(){System.out.println("Hello World");}
}
具体的cron表达式练习:
具体的cron表达式练习
除了配置@Scheduled注解,还需要在启动类上添加注解@EnableScheduling,以上两步就可以实现对方法实现定时。
@EnableScheduling
@SpringBootApplication
public class HelloWorldApplication {public static void main(String[] args) {SpringApplication.run(HelloWorldApplication.class, args);}}
综上所述,使用注解的方式在SpringBoot的框架是非常方便实现定时任务的。但是也存在缺点:
- 不支持集群: 常用于单机系统,如果部署到多台机器的话,会导致同时触发问题。
- 常用于小型任务:对于大型任务更需要单独任务调度平台,对于频繁更新
cron时, 以注解的方式就显得力不从心。
对此接下来介绍一种,轻量化分布式任务调度平台。xxl-job,地址为:
xxl-job项目地址
2.2.1 轻量化分布式任务调度平台 --xxl-job
XXL-JOB是一个分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。该项目在github完全开源,有着丰富的文档、活跃的社区。由于其开箱即用,已经被很多互联网公司接入产品线。
相较于@Scheduled注解,xxl-job有着一下的优点:
- 操作简单:可以使用Web页面对任务进行更新;
- 动态:支持动态修改任务状态、启动/停止任务,并且能即时生效;
- 调度中心HA(中心式):调度采用中心式设计,“调度中心”自研调度组件并支持集群部署,可保证调度中心HA。
等等,还有其他的优点。
2.2.2 如何搭建调度平台
接下就演示一下,在本地如何搭建一个xxl-job服务。
- 首先
clone项目到本地

- 运行
sql,建立数据库,建立必要的表


- 修改
xxl-job-admin中的数据库路径

- 使用
maven对项目进行打包,在终端使用命令:mvn install。如下图所示,生成了一个war包

- 这一步需要准备好
tomcat服务,将war包放到webapps目录下,然后再bin目录下,点击startup.bat启动tomcat


- 输入服务的地址:http://localhost:8080/xxl-job-admin-1.9.2/, 账号:
admin 12345

如果出现了以上的界面,就说明任务调度中心Web界面就搭建完成。
2.2.3 如何使用xxl-job实现定时
接下来讲解下在SpringBoot中如何使用xxl-job。
- 首先在
pom.xml中导入依赖
<dependency><groupId>com.xuxueli</groupId><artifactId>xxl-job-core</artifactId><version>2.3.1</version>
</dependency>
- 新增配置类
package com.xxl.job.executor.core.config;import com.xxl.job.core.executor.XxlJobExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;/*** xxl-job config** @author xuxueli 2017-04-28*/
@Configuration
@ComponentScan(basePackages = "com.xxl.job.executor.service.jobhandler")
public class XxlJobConfig {private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);@Value("${xxl.job.admin.addresses}")private String adminAddresses;@Value("${xxl.job.executor.appname}")private String appName;@Value("${xxl.job.executor.ip}")private String ip;@Value("${xxl.job.executor.port}")private int port;@Value("${xxl.job.accessToken}")private String accessToken;@Value("${xxl.job.executor.logpath}")private String logPath;@Value("${xxl.job.executor.logretentiondays}")private int logRetentionDays;@Bean(initMethod = "start", destroyMethod = "destroy")public XxlJobExecutor xxlJobExecutor() {logger.info(">>>>>>>>>>> xxl-job config init.");XxlJobExecutor xxlJobExecutor = new XxlJobExecutor();xxlJobExecutor.setAdminAddresses(adminAddresses);xxlJobExecutor.setAppName(appName);xxlJobExecutor.setIp(ip);xxlJobExecutor.setPort(port);xxlJobExecutor.setAccessToken(accessToken);xxlJobExecutor.setLogPath(logPath);xxlJobExecutor.setLogRetentionDays(logRetentionDays);return xxlJobExecutor;}}
每个配置的含义如下:
/**### 调度中心部署根地址 [选填]:如调度中心集群部署存在多个地址则用逗号分隔。执行器将会使用该地址进行"执行器心跳注册"和"任务结果回调";为空则关闭自动注册;xxl.job.admin.addresses=http://localhost:8080/xxl-job-admin### 执行器通讯TOKEN [选填]:非空时启用;xxl.job.accessToken=### 执行器AppName [选填]:执行器心跳注册分组依据;为空则关闭自动注册xxl.job.executor.appname=xxl-job-executor-sample### 执行器注册 [选填]:优先使用该配置作为注册地址,为空时使用内嵌服务 ”IP:PORT“ 作为注册地址。从而更灵活的支持容器类型执行器动态IP和动态映射端口问题。xxl.job.executor.address=### 执行器IP [选填]:默认为空表示自动获取IP,多网卡时可手动设置指定IP,该IP不会绑定Host仅作为通讯实用;地址信息用于 "执行器注册" 和 "调度中心请求并触发任务";xxl.job.executor.ip=### 执行器端口号 [选填]:小于等于0则自动获取;默认端口为9999,单机部署多个执行器时,注意要配置不同执行器端口;xxl.job.executor.port=9999### 执行器运行日志文件存储磁盘路径 [选填] :需要对该路径拥有读写权限;为空则使用默认路径;xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler### 执行器日志文件保存天数 [选填] : 过期日志自动清理, 限制值大于等于3时生效; 否则, 如-1, 关闭自动清理功能;xxl.job.executor.logretentiondays=30* @return*/
- 实现
IJobHandler接口,实现execute方法,业务实现就在这里实现。
package com.xxl.job.executor.service.jobhandler;import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.IJobHandler;
import com.xxl.job.core.handler.annotation.JobHandler;
import com.xxl.job.core.log.XxlJobLogger;
import org.springframework.stereotype.Component;import java.util.concurrent.TimeUnit;/*** 任务Handler示例(Bean模式)** 开发步骤:* 1、继承"IJobHandler":“com.xxl.job.core.handler.IJobHandler”;* 2、注册到Spring容器:添加“@Component”注解,被Spring容器扫描为Bean实例;* 3、注册到执行器工厂:添加“@JobHandler(value="自定义jobhandler名称")”注解,注解value值对应的是调度中心新建任务的JobHandler属性的值。* 4、执行日志:需要通过 "XxlJobLogger.log" 打印执行日志;** @author xuxueli 2015-12-19 19:43:36*/
@JobHandler(value="demoJobHandler")
@Component
public class DemoJobHandler extends IJobHandler {@Overridepublic ReturnT<String> execute(String param) throws Exception {XxlJobLogger.log("XXL-JOB, Hello World.");for (int i = 0; i < 5; i++) {XxlJobLogger.log("beat at:" + i);TimeUnit.SECONDS.sleep(2);}return SUCCESS;}}
- 启动
SpringBoot项目,配置

日志执行:如下显示demoJobHandler已经注册成功,并且执行成功了两次
17:41:34.934 logback [Thread-7] INFO c.x.j.c.t.ExecutorRegistryThread - >>>>>>>>>>> xxl-job registry success, registryParam:RegistryParam{registGroup='EXECUTOR', registryKey='xxl-job-ex
ecutor-sample', registryValue='10.14.161.30:9999'}, registryResult:ReturnT [code=200, msg=null, content=null]
17:42:04.952 logback [Thread-7] INFO c.x.j.c.t.ExecutorRegistryThread - >>>>>>>>>>> xxl-job registry success, registryParam:RegistryParam{registGroup='EXECUTOR', registryKey='xxl-job-ex
ecutor-sample', registryValue='10.14.161.30:9999'}, registryResult:ReturnT [code=200, msg=null, content=null]
3. 结语
综上所述,一共讨论了两种定时的实现方式,所有的操作都是基于SpringBoot框架实现的;每种方式都要自己的优势所在,可以根据自己业务的难易进行选择;以上的步骤亲测可以实现,欢迎留言讨论。
相关文章:
搭建一个中心化的定时服务
1. 背景 在物联网络,很多设备之间都在进行交互,其中云端在远程交流中起到了很重要的作用。比如,一台设备想进行调温,但是需要知道此时房间的温度,那就需要定时去查询传感器测出来的房间温度,如果温度过高&a…...
【CSS】快速入门笔记
视频链接:https://www.bilibili.com/video/BV1mS4y1Z7Ga/?spm_id_from333.999.0.0&vd_source1ad00d913eae8281cbadad6ae66fb06c 文章目录一、CSS语法1.结构2.样式类型1)内联样式 Inline Style2)内部样式 Internal Style3)外部…...
第161篇 笔记-去中心化的含义
本文主要内容来自Vitalik Buterin的文章。“去中心化”这个词是在加密经济学领域用得最多的一个词,通常也作为辨别区块链的依据。然而,这个词也可能是被定义得最不恰当的一个词。数千小时的研究和价值数十亿美元哈希算力的投入都旨在实现去中心化&#x…...
「计算机组成原理」数据的表示和运算(二)
文章目录五、奇偶校验码六、算术逻辑单元ALU6.1 电路的基本原理6.2 加法器的设计6.2.1 一位全加器6.2.2 串行加法器6.2.3 串行进位的并行加法器6.2.4 并行进位的并行加法器七、补码加减运算器八、标志位的生成九、定点数的移位运算9.1 算数移位9.2 逻辑移位9.3 循环移位五、奇偶…...
建立自己的博客
环境安装: w10系统安装 第一步:安装git Git 官网: https://git-scm.com/ 第二步:安装Node.js Node.js官网:https://nodejs.org/zh-cn/ 使用cmd检测: node -v 第三步:安装Hexo Hexo官网:htt…...
Docker 安装mysql Mac 环境下
已安装桌面端 Docker (Mac安装Docker) 安装方式一 打开链接 https://www.docker.com/products/docker-desktop 选择平台下载 安装方式二 安装homebrew /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/m…...
《C++代码分析》第三回:类成员函数覆盖父类函数的调用(分析this指针的变化)
一、前言 在C的学习中我们知道,子类是可以覆盖父类的方法,这里我们探讨一下子类方法调用父类方法时this指针时如何变化的。 二、示例代码 #include "windows.h" #include "windef.h" #include <iostream> #include <tch…...
Altium designer--软件简介及安装教程(Altium designer16)
一、软件介绍(完整安装包资源见文末链接,含破解license) Altium Designer 是一款简单易用、原生3D设计增强的一体化设计环境,结合了原理图、ECAD库、规则和限制条件、BoM、供应链管理、ECO流程和世界一流的PCB设计工具。通过原理…...
Windows系统下基于开源软件的多物理场仿真
Windows系统下基于开源软件的多物理场仿真实践技术应用随着计算机技术的发展,计算机仿真技术日益成为继实验和理论之后的第三种重要研究和设计手段。真实世界中遇到的问题往往是固体力学,流体力学,热,电磁等多种现象耦合而成&…...
【STL】list剖析及模拟实现
✍作者:阿润菜菜 📖专栏:C 初识list 1. list基本概况 list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立…...
Go打包附件内容到执行文件
前言 如果我们的应用在启动的时候需要对数据库进行初始化(比如建表等), 可以通过读取.sql文件内容直接执行. 但是, 这样会带出一个问题: 在发送可执行文件的时候, 需要连带着附件文件, 并且相对路径还不能出错. 这样太麻烦了有时我们并不希望附件的内容被使用者看到 处于种种…...
Spring的配置属性
介绍 以前都是用XML来设置属性值,SpringBoot的自动配置可以简化Spring应用的开发。配置属性只是配置Spring应用上下文中bean的属性而已,可以通过多个源来配置,包括JVM系统属性、环境变量等。 Spring中有两种不同(但相关)的配置 bean装配&…...
132.《render-props, Hoc,自定义hooks 详解》
文章目录render-props 模式props 方式children 方式(推荐)Hoc(高阶组件)使用步骤示例props 丢失解决方案自定义 hook1.只执行一次2.防抖hook高阶组件与自定义hook有什么区别相同点不同点React 中代码逻辑复用有三种方式,render-props, Hoc&am…...
通过Session共享数据验证码进行用户登录
通过Session共享数据验证码进行用户登录 需求: 访问带有验证码的登录页面login.jsp。用户输入用户名,密码以及验证码。 ①。如果用户名和密码输入有误,跳转登陆页面,提示:用户名或密码错误。 ②。如果验证码输入有误…...
C++STL详解(六)——stack和queue
文章目录空间适配器stackstack的定义方式stack的使用stack的模拟实现queuequeue的定义方式queue的使用queue的模拟实现空间适配器 适配器是一种设计模式(设计模式是一套被反复使用的,多数人知晓的,经过分类编目的,代码设计经验的…...
javaEE 初阶 — CSS 的 基本语法 与 引入方式
文章目录1. 基本语法规范2. 三种引入方式1. 基本语法规范 CSS 的基本语法规范是由 选择器 和 若干个声明 组成的。 选择器选中一个元素之后,这些属性都是针对于这个元素展开的。 先来看一个没有 CSS 的效果。 <body><p>这是一个段落</p> </bo…...
QEMU启动ARM32 Linux内核
目录前言前置知识ARM Versatile Express开发板简介ARM处理器家族简介安装qemu-system-arm安装交叉编译工具交叉编译ARM32 Linux内核交叉编译ARM32 Busybox使用busybox制作initramfs使用QEMU启动ARM32 Linux内核模拟vexpress-a9开发板模拟vexpress-a15开发板参考前言 本文介绍采…...
than的用法合集
首先需要了解一下than的词性,其有两个词性,一个是介词,一个是连词。 介词后面一定要接上名词性的词语,比如 i am taller then him 我比我的老师高 连词就比较自由,一般用来连接两个句子;但是使用than连词词…...
Unet 基于TCGA颅脑肿瘤MRI分割(高阶API分割模型)
目录 1. 介绍 2. dice 指标 3. resnet34 作为 backbone 的分割 4. deeplabv3 图像分割 4.1 问题 4.2 训练 4.3 预测 5. MAnet 图像分割...
[NIPS 2017] Improved Training of Wasserstein GANs (WGAN-GP)
Contents IntroductionDifficulties with weight constraintsCapacity underuseExploding and vanishing gradientsGradient penaltyReferencesIntroduction WGAN 增加了 GAN 模型训练的稳定性,但有时仍然会有生成质量不高或难以收敛的问题。作者发现上述问题经常是由 WGAN 中…...
PEI转染试剂及相关工具在生命科学研究中的应用解析【曼博生物官方代理Polysciences】
摘要:聚乙烯亚胺(PEI)转染试剂在基因递送、病毒载体生产等领域应用广泛。本文结合Polysciences相关产品体系,对PEI转染、微球技术及神经示踪染料等工具进行系统梳理。 关键词:PEI转染、聚乙烯亚胺、基因转染、HEK293、…...
cutlass代码架构分析
CUTLASS 代码架构分析 本文档基于 cutlass代码进行梳理,快速理解 CUTLASS 4.x 的模块边界与调用链路。 1. 总体架构 CUTLASS 本质上是一个 header-only 的 CUDA C++ 模板库,外围配套了可选构建目标: include/:核心库(cutlass + cute) tools/:库实例化、性能测试与通用…...
Cartool实战:手把手教你完成静息态EEG微状态分析的组水平聚类与模板匹配
Cartool实战:静息态EEG微状态分析全流程解析与避坑指南 在认知神经科学研究中,静息态EEG微状态分析正成为探索大脑动态功能网络的重要工具。不同于传统频域分析,微状态分析通过捕捉毫秒级地形图变化,揭示大脑信息处理的离散状态转…...
SEO_2024年最新SEO策略与趋势深度解析(352 )
<h2>2024年最新SEO策略与趋势深度解析</h2> <p>在数字化时代,搜索引擎优化(SEO)依然是网站流量和品牌影响力的核心驱动力。2024年,随着互联网技术的不断进步,SEO策略和趋势也在不断演变。本文将详细…...
RK3568 NPU RKNN(五):RKNN-ToolKit2性能与内存评估实战解析
1. 环境准备与工具链搭建 在开始RKNN-ToolKit2的性能与内存评估之前,我们需要先搭建完整的开发环境。这里以野火LubanCat开发板为例,具体硬件配置为RK3568芯片4GB内存版本。开发主机建议使用Ubuntu 20.04系统,确保Python版本在3.6-3.8之间。 …...
用Logisim搞定六进制计数器:从真值表到同步置数/异步清零的保姆级布线教程
用Logisim搞定六进制计数器:从真值表到同步置数/异步清零的保姆级布线教程 第一次在Logisim里搭建计数器电路时,看着那些密密麻麻的逻辑门和跳线,我盯着屏幕发呆了半小时——明明按照课本上的真值表连接,仿真时却总是卡在某个状态…...
TinyMCE 5插件开发实战:手把手教你定制首行缩进功能(Vue版)
TinyMCE 5插件开发实战:手把手教你定制首行缩进功能(Vue版) 在内容创作领域,富文本编辑器的灵活性和扩展性往往决定了最终的用户体验。TinyMCE作为一款广受欢迎的富文本编辑器,其插件系统为开发者提供了无限可能。本文…...
英雄联盟智能工具League Akari:提升游戏体验的终极指南
英雄联盟智能工具League Akari:提升游戏体验的终极指南 【免费下载链接】League-Toolkit 兴趣使然的、简单易用的英雄联盟工具集。支持战绩查询、自动秒选等功能。基于 LCU API。 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit League Akari是…...
深度解析Windows微信自动化:Wechaty Puppet XP零成本架构设计与实战指南
深度解析Windows微信自动化:Wechaty Puppet XP零成本架构设计与实战指南 【免费下载链接】puppet-xp Wechaty Puppet WeChat Windows Protocol 项目地址: https://gitcode.com/gh_mirrors/pu/puppet-xp 在即时通讯自动化领域,Windows平台微信机器…...
SAP EWM开发实战:手把手教你用ABAP OO类 /SCWM/CL_SP_PRD_INB 创建内向交货单
SAP EWM开发实战:基于ABAP OO类实现内向交货单自动化创建 1. 理解内向交货单创建的技术背景 在SAP扩展仓库管理(EWM)系统中,内向交货单(Inbound Delivery)是管理入库流程的核心凭证。与传统的SAP ERP系统不同,EWM模块在设计上采用了更加灵活的…...
