springboot集成xxl-job执行定时任务
在开发项目的过程中涉及到了定时任务的功能 , 这里学习并使用XXL-JOB来设置定时任务
官方文档地址 : 分布式任务调度平台XXL-JOB (xuxueli.com)
简介
XXL-JOB是一个分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,开箱即用。
环境要求
Maven3+
Jdk1.8+
Mysql5.7+
快速使用
依赖引入
123456<!-- http://repo1.maven.org/maven2/com/xuxueli/xxl-job-core/ --><dependency> <groupId>com.xuxueli</groupId> <artifactId>xxl-job-core</artifactId> <version>${最新稳定版本}</version></dependency>
根据当前的实际需求, 在这里选择Bean模式
配置调度中心
引入项目源码
在github或者Gitee上面download源码之后, 导入我们自己的项目
12345xxl-job-admin:调度中心xxl-job-core:公共依赖xxl-job-executor-samples:执行器Sample示例(选择合适的版本执行器,可直接使用,也可以参考其并将现有项目改造成执行器) :xxl-job-executor-sample-springboot:Springboot版本,通过Springboot管理执行器,推荐这种方式; :xxl-job-executor-sample-frameless:无框架版本;
配置数据库
执行doc/db//tables_xxl_job.sql , 然后获得下面的数据库
完成调度中心配置
调度中心项目:xxl-job-admin
作用:统一管理任务调度平台上调度任务,负责触发调度执行,并且提供任务管理平台。
这里主要就是更改数据库的相关配置
配置信息说明
1234567891011121314151617181920212223### 调度中心JDBC链接:链接地址请保持和 2.1 ...
关于mutil-moudle项目与微服务的理解
起因
在学习微服务知识以及跟着做gulimall之前, 开发上遇到的springboot项目基本都是单个模块的项目 ,
后来到学习微服务项目才动手去做多个模块的项目。
gulimall
mutil-moudle
经过
在学习springcloud的时候, 课程基本都是先讲什么注册中心, 配置中心, 网关, 负载均衡, openFeign这样的知识, 导致我想当然的就任务nacos, gateway , eureka 这样的技术都是springcloud的东西, 简单的把微服务理解成了多个模块的springboot , 然后会引入一些别的技术
那么我们继续来回顾一下微服务的特点:
服务按照业务来划分,每个服务通常只专注于某一个特定的业务、所需代码量小,复杂度低、易于维护。
每个微服都可以独立开发、部署和运行,且代码量较少,因此启动和运行速度较快。
每个服务从设计、开发、测试到维护所需的团队规模小,一般 8 到 10 人,团队管理成本小。
采用单体架构的应用程序只要有任何修改,就需要重新部署整个应用才能生效,而微服务则完美地解决了这一问题。在微服架构中,某个微服务修改后,只需要重新部署这个服务即可,而不需要重新部署整个应用程序。
在微服务架构中,开发人员可以结合项目业务及团队的特点,合理地选择语言和工具进行开发和部署,不同的微服务可以使用不同的语言和工具。
微服务具备良好的可扩展性。随着业务的不断增加,微服务的体积和代码量都会急剧膨胀,此时我们可以根据业务将微服务再次进行拆分;除此之外,当用户量和并发量的增加时,我们还可以将微服务集群化部署,从而增加系统的负载能力。
微服务能够与容器(Docker)配合使用,实现快速迭代、快速构建、快速部署。
微服务具有良好的故障隔离能力,当应用程序中的某个微服发生故障时,该故障会被隔离在当前服务中,而不会波及到其他微服务造成整个系统的瘫痪。
微服务系统具有链路追踪的能力。
上面做出标记的部分可以着重理解 ,
但是springboot本身也提供了多模块的写法
在Spring Boot中使用多模块和Spring Cloud微服务理念有冲突吗? - 知乎 (zhihu.com)
用Spring Boot开发Multi Module应用,应该包含一个Application Project和若干个Library
Proje ...
leetcode题目(5)
题目 🍐
4. 寻找两个正序数组的中位数
难度困难6151
给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个==正序数组==的 中位数 。
算法的时间复杂度应该为 O(log (m+n)) 。
示例 1:
输入:nums1 = [1,3], nums2 = [2]
输出:2.00000
解释:合并数组 = [1,2,3] ,中位数 2
示例 2:
输入:nums1 = [1,2], nums2 = [3,4]
输出:2.50000
解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5
提示:
nums1.length == m
nums2.length == n
0 <= m <= 1000
0 <= n <= 1000
1 <= m + n <= 2000
-106 <= nums1[i], nums2[i] <= 106
这个题目既然要求了
算法的时间复杂度应该为 O(log (m+n))
那么必然是用到了二分相关的思想
那么回顾一下中位数的定义,
如果某个有序数组长度是奇数,那么其中位数就是最中间那个,如果是偶数,那么就是最中间两个数字的平均值。
这里对于两个有序数组也是一样的,假设两个有序数组的长度分别为m和n,由于两个数组长度之和 m+n 的奇偶不确定,因此需要分情况来讨论,对于奇数的情况,直接找到最中间的数即可,偶数的话需要求最中间两个数的平均值。
为了简化代码,不分情况讨论,我们可以这样来计算,我们分别找第 (m+n+1) / 2 个,和 (m+n+2) / 2 个,然后求其平均值即可,这对于奇偶数均适用。
假如m+n 为奇数的话,那么其实 (m+n+1) / 2 和 (m+n+2) / 2 的值相等,相当于两个相同的数字相加再除以2,还是其本身。
我们可以这样来做 , 对于一次操作 , 我们每次从总的数组中排除一些必然不可能是中位数的数字
具体的做法
我们统计 两个数组的总长度 ,然后通过这个总长度来计算中位数的下标 , 我们记为k(k为中位数的下标),
那么一定会有这种的情况, 中位数位于某一个数组的 必然是 0< idx < k
那么我们可以 每次取到 两个数组的k/2 的位置的下标, ...
(四)文件系统[os]
4.1.1.文件管理
文件――就是一组有意义的信息/数据集合。
文件的属性
文件名: 由创建文件的用户决定文件名,主要是为了方便用户找到文件,同一目录下不允许有重名文件。
标识符: 一个系统内的各文件标识符唯一,对用户来说毫无可读性,因此标识符只是操作系统用于区分各个文件的一种内部名称。
类型: 指明文件的类型
位置: 文件存放的路径(让用户使用)、在外存中的地址(操作系统使用,对用户不可见)
大小: 指明文件大小创建时间、上次修改时间文件所有者信息
保护信息: 对文件进行保护的访问控制信息
文件分为有结构文件和无结构文件。
操作系统向上(用户和应用程序)提供的功能
4.1.2.文件的逻辑结构
按文件是否有结构分类,可以分为无结构文件、有结构文件两种。
无结构文件:文件内部的数据就是一系列二进制流或字符流组成。又称“流式文件”。
如:Windows操作系统中的.txt文件。
⭐有结构文件:由一组相似的记录组成,又称“记录式文件”。每条记录又若干个数据项组成。如:数据库表文件。一般来说,每条记录有一个数据项可作为关键字(作为识别不同记录的ID)
我们主要研究有结构文件。
1.顺序文件
顺序文件:文件中的记录一个接一个地顺序排列(逻辑上),记录可以是定长的或可变长的。各个记录在物理上可以顺序存储(相当于数组)或链式存储(相当于链表)。
顺序存储又可以分为串结构和顺序结构。
那么这几种存储方式是否可以快速找到第i个记录对应的地址呢 ?
注:一般来说,考试题目中所说的“顺序文件”指的是物理上顺序存储的顺序文件。之后的讲解中提到的顺序文件也默认如此可见,顺序文件的缺点是增加/删除一个记录比较困难(如果是串结构则相对简单 , 因为不需要保证按照关键词顺序存储)
结论 : 定长记录的顺序文件,若物理上采用顺序存储,则可实现随机存取;若能再保证记录的顺序结构,则可实现快速检索(即根据关键字快速找到对应记录)
2.索引文件
思考:对于可变长记录文件,要找到第i个记录,必须先顺序第查找前i-1个记录, 但是很多应用场景中又必须使用可变长记录。如何解决这个问题?
这时我们可以建立一张索引表来快速找到第i个记录。如图所示:
文件中的记录 可以 离散的存放, 但是索引表中的记录需要连续存放
索引表本身是定长记录的顺序文件。 因此可以快速找到第i个记录对应 ...
(三)内存管理[os]
3.1.基础知识
内存是用于存放数据的硬件。程序执行前需要先放到内存中才能被CPU处理。
相对地址和绝对地址
编译时产生的指令只关心“相对地址”,实际放入内存中时再想办法根据起始位置得到“绝对地址”。
Eg: 编译时只需确定变量x存放的相对地址是100(也就是说相对于进程在内存中的起始地址而言的地址)。CPU 想要找到x在内存中的实际存放位置,只需要用进程的起始地址+100即可。
相对地址又称逻辑地址,绝对地址又称物理地址。
写程序到程序运行
3.2.内存管理
操作系统对内存进行管理,那么要管理哪些内容呢?
内存空间的分配和回收
操作系统需要提供某种技术从逻辑上对内存空间进行扩充。
操作系统需要提供地址转换功能,负责程序的逻辑地址与物理地址的转换
操作系统需要提供内存保护功能。保证各进程在各自存储空间内运行,互不干扰
内存保护可采取两种方法:
方法一:在CPU中设置一对上、下限寄存器,存放进程的上、下限地址。进程的指令要访问某个地址时,CPU检查是否越界。
方法二:采用重定位寄存器(又称基址寄存器)和界地址寄存器(又称限长寄存器)进行越界检查。重定位寄存器中存放的是进程的起始物理地址。界地址寄存器中存放的是进程的最大逻辑地址。
3.3.覆盖和交换
1.覆盖技术
覆盖技术的思想 : 将程序分为多个段(多个模块)。常用的段常驻内存,不常用的段在需要时调入内存。
内存中分为一个“固定区”和若干个“覆盖区”。需要常驻内存的段放在“固定区”中,调入后就不再调出(除非运行结束)不常用的段放在“覆盖区”,需要用到时调入内存,用不到时调出内存。
必须由程序员声明覆盖结构,操作系统完成自动覆盖。**缺点:对用户不透明,增加了用户编程负担。**覆盖技术只用于早期的操作系统中,现在已成为历史。
2.交换技术
交换(对换)技术的设计思想: 内存空间紧张时,系统将内存中某些进程暂时换出外存,把外存中某些已具备运行条件的进程换入内存(进程在内存与磁盘间动态调度)。之前讲的中级调度(内存调度)就是为这个服务的。
1.应该在外存(磁盘)的什么位置保存被换出的进程?
具有对换功能的操作系统中,通常把磁盘空间分为文件区和对换区两部分。文件区主要用于存放文件,主要追求存储空间的利用率,因此对文件区空间的管理采用离散分配方式;对换区空间只占磁盘空间的小部分,被换出的进程数据就存 ...
(补充)操作系统基本操作[os]
1.操作系统的启动
(1)CPU, I/O, 内存通过总线连接。
(2)DISK: 存放OS;
BIOS:基本I/O处理系统( basic I/O system); Bootloader: 加载OS到内存中。
(3)当电脑通电时,段寄存器CS和指令寄存器IP能够确定一个内存地址,例如 CS:IP = 0xf000:fff0.
(4)POST(加电自检),寻找显卡和执行BIOS。(显示器,键盘…是否正常)。
(5)步骤:
BIOS: 将Bootloader从磁盘的磁盘的引导扇区(512字节)加载到0x7c00;跳转到CS:IP=0000:7c00的内存区域(以便下一步)
Bootloader:将操作系统的代码和数据从硬盘加载到内存中;跳转到操作系统的起始地址。
(6)系统调用:(来源于应用程序)应用程序主动向操作系统发出服务请求。
(7)异常:(来源于不良的应用程序)非法指令或其它花的处理状态(e.g.内存出错)。
(8)中断:(来源于外设)来自不同的硬件设备的计时器和网络的中断。
(9)为什么应用程序不能直接访问硬件而是通过操作系统?
计算机运行时,内核是被信任的第三方。
只有内核可以执行特权指令。
为了方便应用程序。
(10)讨论的问题:操作系统如何设计和实现中断/异常和系统调用;他们三者的区别和特点。
(11)产生的源头
中断:外设(键盘/鼠标/网卡/声卡/显卡,可以产生各种事件)
异常:应用程序意想不到的行为(e.g.异常,恶意程序,应用程序需要的资源未得到满足)
系统调用(system call):应用程序请求操作提供服务(e.g.打开/关闭/读写文件,发送网络包)
(12)处理时间
中断:异步;
异常:同步;
系统调用:同步或异步。
(13)响应
中断:持续,对用户应用程序时透明的
异常:杀死或者重新执行意想不到的应用程序指令
系统调用:等待和持续
2.中断/异常和系统调用
(1)中断/异常处理机制
中断是外设的事件,异常是CPU的事件;中断/异常迫使CPU访问一些被中断和异常服务访问的功能。
(2)中断处理机制
硬件:设置中断标记(CPU初始化)
将内部/外部事件设置中断标记;
中断事件的ID(程序访问的中断向量地址)
软件(操作系统):
保存当前处理状态
中断服务程序处理
清除中断标记
恢复之前保存的处理状态
(3)异常处理 ...
5调度与调度算法
2.4.1.处理机调度的概念和层次
含义
在多道程序系统中,进程的数量往往是多于处理机的个数的,这样不可能同时并行地处理各个进程。
处理机调度,就是从就绪队列中按照一定的算法选择一个进程并将处理机分配给它运行,以实现进程的并发执行。
调度分为三个层次,分别为高级调度,中级调度,初级调度。
1.高级调度
由于内存空间有限,有时无法将用户提交的作业全部放入内存,因此就需要确定某种规则来决定将作业调入内存的顺序。
高级调度(作业调度)。按一定的原则从外存上处于后备队列的作业中挑选一个(或多个)作业,给他们分配内存等必要资源,并建立相应的进程(建立PCB),以使它(们)获得竞争处理机的权利。
==高级调度是辅存(外存)与内存之间的调度==。每个作业只调入一次,调出一次。作业调入时会建立相应的PCB,作业调出时才撤销PCB。高级调度主要是指调入的问题,因为只有调入的时机需要操作系统来确定,调出的时机必然是作业运行结束才调出。
2.中级调度
引入了虚拟存储技术之后,可将暂时不能运行的进程调至外存等待。等它重新具备了运行条件且内存又稍有空闲时,再重新调入内存。这么做的目的是为了提高内存利用率和系统吞吐量。
==暂时调到外存等待的进程状态为挂起状态==。值得注意的是,==PCB并不会一起调到外存,而是会常驻内存==。PCB中会记录进程数据在外存中的存放位置,进程状态等信息,操作系统通过内存中的PCB来保持对各个进程的监控、管理。被挂起的进程PCB会被放到的挂起队列中。
中级调度(内存调度),就是要决定将哪个处于挂起状态的进程重新调入内存。
一个进程可能会被多次调出、调入内存,因此中级调度发生的频率要比高级调度更高。
补充知识:进程的七状态模型
暂时被调到外存等待的进程状态称为挂起状态。
挂起状态又可以进一步细分为就绪挂起,堵塞挂起两种状态。
3.低级调度
低级调度(进程调度),其主要任务是按照某种方法和策略从就绪队列中选取一个进程,将处理机分配给它。
进程调度是操作系统中最基本的一种调度,在一般的操作系统中都必须配置进程调度。
进程调度的频率很高,一般几十毫秒一次。
4.三种调度的联系和对比
2.4.2.进程调度的时机,切换过程和方式
1.进程调度的时机
临界资源: 一个时间段内只允许一个进程使用的资源。各进程需要互斥的访问临界资源。
临界区: ...
(二)进程与线程:3进程通信[os]
2.3.1 进程同步
在多道程序环境下,进程是并发执行的,不同进程之间存在着不同的相互制约关系。
同步与异步
进程同步机制的主要任务,是对多个具有相互制约关系的进程在执行次序上进行协调,使并发执行的进程间能按照一定的规则或时序共享系统资源,实现相互合作,从而使程序的执行具有可再现性。
异步:不确定的、不可预知的
同步:确定的、可预知的、可再现的
进程间的制约关系有两种:==互斥制约==与==合作制约==。但无论哪种制约关系,在多道程序环境下,进程何时可以获得处理器,运行的速度如何,并不是进程自身可以控制的。此为进程的异步性。
互斥制约: 当多个进程都对同一个临界资源进行访问时,它们之间就具有互斥制约关系。互斥制约关系中一定会出现临界资源。
临界资源: 多个进程间需要采取互斥方式实现对某种资源的共享,那么这种资源就称为临界资源。例如,打印机、磁带机等都属于临界资源
例如,多个进程都要访问打印机,那么它们之间就属于互斥制约关系。这多个进程对于打印请求的提交是异步的,但打印过程必须保持同步:一个进程的打印任务未完成之前,另一个进程不能进行打印
说白了就是我用的时候,你不能用
合作制约: 当某项任务需要多个进程同时协作完成时,它们之间就具有合作制约关系。
例如,生产者进程在生产产品,并将产品提供给消费者进行消费。为了使生产者进程与消者进程能够并发执行,在它们之间设置了一个具有n个缓冲区的缓冲池。生产者将一个产品放入到一个缓冲区,消费者可以从一个缓冲区取走一个产品消费。此时,生产者与消费者间就是合作制约关系。
所有生产者与所有的消费者都是以==异步方式==(谁先谁后不知道)运行的,但它们之间必须保特同步:不允许消费者到一个空缓冲区取产品,也不允许生产者向满缓冲区中投放产品。若缓冲池中的所有缓冲区都是空的,那么所有消费者进程阻塞,:若缓冲池中所有缓冲区都是满的,那么所有生产者进程阻塞。
异步带来的问题
多道程序环境下异步是不可避免的,但没有完善的同步机制,会产生很多无法预料的结果。
伪代码
以下是生产者与消费者共享的变量:
12Item buffer[n]; //具有n个缓冲区的缓冲池int counter=0; //当前缓冲池中具有的缓冲数据的数量,其范围是[0, n]
以下是==生产者==伪代码:
12345678910int in =0; ...
(二)进程与线程:2线程[os]
2.2.1 线程的使用
在传统操作系统中,每个进程有一个地址空间和一个控制线程。事实上,这几乎就是进程的定义。不过,经常存在在同一个地址空间中准井行运行多个控制线程的情形,这些线程就像(差不多)分离的进程(共享地址空间除外)。
在早期的操作系统中都是以进程作为独立运行的基本单位,直到后面,计算机科学家们又提出了更小的能独立运行的基本单位,也就是线程。
我们举个例子,假设你要编写一个视频播放器软件,那么该软件功能的核心模块有三个:
从视频文件当中读取数据;
对读取的数据进行解压缩;
把解压缩后的视频数据播放出来;
对于单进程的实现方式,我想大家都会是以下这个方式:
对于单进程的这种方式,存在以下问题:
播放出来的画面和声音会不连贯,因为当 CPU 能力不够强的时候,Read 的时候可能进程就等在这了,这样就会导致等半天才进行数据解压和播放;
各个函数之间不是并发执行,影响资源的使用效率;
那改进成多进程的方式:
对于多进程的这种方式,依然会存在问题:
进程之间如何通信,共享数据?
维护进程的系统开销较大,如创建进程时,分配资源、建立 PCB;终止进程时,回收资源、撤销 PCB;进程切换时,保存当前进程的状态信息;
那到底如何解决呢?需要有一种新的实体,满足以下特性:
实体之间可以并发运行;
实体之间共享相同的地址空间;
这个新的实体,就是线程( Thread ),线程之间可以并发运行且共享相同的地址空间。
2.2.2 线程与进程的比较
线程是进程当中的一条执行流程。
同一个进程内多个线程之间可以共享代码段、数据段、打开的文件等资源,但每个线程各自都有一套独立的寄存器和栈,这样可以确保线程的控制流是相对独立的。
假设用户正在写一本书。从作者的观点来看,最容易的方法是把整本书作为一个文件,这样一来,查询内容、完成全局替换等都非常容易。另一种方法是,把每一立都处理成单独一个文件。但是,在把每个小节和子小节都分成单个的文件之后,若必须对全书进行全局的修改时,那就真是麻烦了,因为有成百个文件必须一个个地编辑。例如,如果所建议的某个标准XX XX正好在书付印之前被批准了,千是“标准草案XXXX"一类的字眼就必须改为“标准XXXX n。如果整本书是一个文件,那么只要一个命令就可以完成全部的替换处理。相反,如果一本书分成了300个文件,那么就必须分别对每 ...
(二)进程与线程:进程[os]
"我们写好的一行行代码,为了让其工作起来,我们还得把它送进城(进程)里,那既然进了城里,那肯定不能胡作非为了。
城里人有城里人的规矩,城中有个专门管辖你们的城管(操作系统),人家让你休息就休息,让你工作就工作,毕竟摊位不多,每个人都要占这个摊位来工作,城里要工作的人多着去了。
所以城管为了公平起见,它使用一种策略(调度)方式,给每个人一个固定的工作时间(时间片),时间到了就会通知你去休息而换另外一个人上场工作。
另外,在休息时候你也不能偷懒,要记住工作到哪了,不然下次到你工作了,你忘记工作到哪了,那还怎么继续?
有的人,可能还进入了县城(线程)工作,这里相对轻松一些,在休息的时候,要记住的东西相对较少,而且还能共享城里的资源。"
5.1 进程、线程基础知识|小林coding (xiaolincoding.com)
OS中进程是作为资源分配与独立运行的基本单位出现的。
OS的四大特征(==并发、共享、虚拟、异步==)也都是基于进程而形成的。
所以,在OS中,进程是一个极其重要的概念。
到80年代中期,又出现了比进程更小的基本单位——线程。用它来提高程序并发执行程度,以进一步改善系统的服务质量。现代OS无一例外的引入了线程,所以,线程也是一个非常重要的概念。
2.1.1 进程描述
进程控制块PCB
PCB听起来有点熟悉,实际上还有另一个PCB
PCB(Printed Circuit Board),中文名称为印制电路板,又称印刷线路板,是重要的电子部件,是电子元器件的支撑体,是电子元器件电气相互连接的载体。由于它是采用电子印刷术制作的,故被称为“印刷”电路板
为了方便控制和管理参与并发执行的每个程序的独立运行,在操作系统中为之配置一种专门的数据结构,称为进程控制块,Process Control Block,==PCB==。
系统利用PCB来描述进程的基本信息与活动过程,进而控制和管理进程。
此时就产生了一个新的概念——**进程实体,**又称进程映像。
程序段、相关数据段和PCB三部分构成了进程实体。
以下是PCB结构体的部分描述属性:
123456789101112131415struct task_struct { long state; //进程运行状态:-1不可运行,0可运行,>0已停止 long priority; //进程运行优先级 long ...




![(三)内存管理[os]](https://dhx-blog.oss-cn-beijing.aliyuncs.com/dhx/230206-16775101265e7e.jpg)
![(二)进程与线程:3进程通信[os]](https://dhx-blog.oss-cn-beijing.aliyuncs.com/dhx/wallhaven-4gp5gl.jpg)
![(二)进程与线程:进程[os]](https://dhx-blog.oss-cn-beijing.aliyuncs.com/dhx/0bd44a2d1fusXjl.jpg)




