<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          分布式任務(wù)調(diào)度有那么難嗎?來,10分鐘帶你實(shí)戰(zhàn)

          共 14408字,需瀏覽 29分鐘

           ·

          2021-09-17 21:23

          一、概述

          1.1、什么是任務(wù)調(diào)度

          我們可以思考一下下面業(yè)務(wù)場景的解決方案:

          • 某電商平臺(tái)需要每天上午10點(diǎn),下午3點(diǎn),晚上8點(diǎn)發(fā)放一批優(yōu)惠券

          • 某銀行系統(tǒng)需要在信用卡到期還款日的前三天進(jìn)行短信提醒

          • 某財(cái)務(wù)系統(tǒng)需要在每天凌晨0:10分結(jié)算前一天的財(cái)務(wù)數(shù)據(jù),統(tǒng)計(jì)匯總

          以上場景就是任務(wù)調(diào)度所需要解決的問題,任務(wù)調(diào)度是為了自動(dòng)完成特定任務(wù),在約定的特定時(shí)刻去執(zhí)行任務(wù)的過程。

          在Spring中也提供了定時(shí)任務(wù)注解@Scheduled。我們只需要在業(yè)務(wù)中貼上注解然后在啟動(dòng)類上貼上@EnableScheduling注解即可完成任務(wù)調(diào)度功能。

          @Scheduled(cron = "0/20 * * * * ? ") // 每隔20秒執(zhí)行一次
          public void doWork(){
          //doSomething
          }
          復(fù)制代碼

          1.2、分布式調(diào)度出現(xiàn)

          感覺Spring給我們提供的這個(gè)注解可以完成任務(wù)調(diào)度的功能,好像已經(jīng)完美解決問題了,為什么還需要分布式呢?主要的原因有以下幾點(diǎn):

          1. 機(jī)處理極限:原本1分鐘內(nèi)需要處理1萬個(gè)訂單,但是現(xiàn)在需要1分鐘內(nèi)處理10萬個(gè)訂單;原來一個(gè)統(tǒng)計(jì)需要1小時(shí),現(xiàn)在業(yè)務(wù)方需要10分鐘就統(tǒng)計(jì)出來。你也許會(huì)說,你也可以多線程、單機(jī)多進(jìn)程處理。的確,多線程并行處理可以提高單位時(shí)間的處理效率,但是單機(jī)能力畢竟有限(主要是CPU、內(nèi)存和磁盤),始終會(huì)有單機(jī)處理不過來的情況。

          2. 高可用:單機(jī)版的定式任務(wù)調(diào)度只能在一臺(tái)機(jī)器上運(yùn)行,如果程序或者系統(tǒng)出現(xiàn)異常就會(huì)導(dǎo)致功能不可用。雖然可以在單機(jī)程序?qū)崿F(xiàn)的足夠穩(wěn)定,但始終有機(jī)會(huì)遇到非程序引起的故障,而這個(gè)對于一個(gè)系統(tǒng)的核心功能來說是不可接受的。

          3. 防止重復(fù)執(zhí)行: 在單機(jī)模式下,定時(shí)任務(wù)是沒什么問題的。但當(dāng)我們部署了多臺(tái)服務(wù),同時(shí)又每臺(tái)服務(wù)又有定時(shí)任務(wù)時(shí),若不進(jìn)行合理的控制在同一時(shí)間,只有一個(gè)定時(shí)任務(wù)啟動(dòng)執(zhí)行,這時(shí),定時(shí)執(zhí)行的結(jié)果就可能存在混亂和錯(cuò)誤了。

          1.3、Elastic-Job

          Elastic-Job是一個(gè)分布式調(diào)度的解決方案,由當(dāng)當(dāng)網(wǎng)開源,它由兩個(gè)相互獨(dú)立的子項(xiàng)目Elastic-job-Lite和Elastic-Job-Cloud組成,使用Elastic-Job可以快速實(shí)現(xiàn)分布式任務(wù)調(diào)度。Elastic-Job的github地址。他的功能主要是:

          • 分布式調(diào)度協(xié)調(diào)

            在分布式環(huán)境中,任務(wù)能夠按照指定的調(diào)度策略執(zhí)行,并且能夠避免同一任務(wù)多實(shí)例重復(fù)執(zhí)行。

          • 豐富的調(diào)度策略:

            基于成熟的定時(shí)任務(wù)作業(yè)框架Quartz cron表達(dá)式執(zhí)行定時(shí)任務(wù)。

          • 彈性拓容縮容

            當(dāng)集群中增加一個(gè)實(shí)例,它應(yīng)當(dāng)能夠被選舉被執(zhí)行任務(wù);當(dāng)集群減少一個(gè)實(shí)例時(shí),他所執(zhí)行的任務(wù)能被轉(zhuǎn)移到別的示例中執(zhí)行。

          • 失效轉(zhuǎn)移

            某示例在任務(wù)執(zhí)行失敗后,會(huì)被轉(zhuǎn)移到其他實(shí)例執(zhí)行。

          • 錯(cuò)過執(zhí)行任務(wù)重觸發(fā)

            若因某種原因?qū)е伦鳂I(yè)錯(cuò)過執(zhí)行,自動(dòng)記錄錯(cuò)誤執(zhí)行的作業(yè),并在下次次作業(yè)完成后自動(dòng)觸發(fā)。

          • 支持并行調(diào)度

            支持任務(wù)分片,任務(wù)分片是指將一個(gè)任務(wù)分成多個(gè)小任務(wù)在多個(gè)實(shí)例同時(shí)執(zhí)行。

          • 作業(yè)分片一致性

            當(dāng)任務(wù)被分片后,保證同一分片在分布式環(huán)境中僅一個(gè)執(zhí)行實(shí)例。

          • 支持作業(yè)生命周期操作

            可以動(dòng)態(tài)對任務(wù)進(jìn)行開啟及停止操作。

          • 豐富的作業(yè)類型

            支持Simple、DataFlow、Script三種作業(yè)類型

          1.4、啟動(dòng)zookeeper

          1. 解壓包

          2. 到conf目錄中把oo_sample.cfg 拷貝一份 , 修改名字為zoo.cfg。

          3. 到bin目錄中啟動(dòng)startup.cmd文件(用1命令行啟動(dòng))。

          1.4、啟動(dòng)zookeeper圖形化界面

          1. 解壓。

          2. 到1build目錄中,找到j(luò)ar包。

          3. 使用命令:java -jar jar包的名字

          二、Elastic-Job快速入門

          Elastic-Job的1環(huán)境要求:

          • JDK 要求1.7以上保本

          • Maven 要求3.0.4及以上版本

          • Zookeeper 要求采取3.4.6以上版本

          2.1、環(huán)境搭建

          安裝運(yùn)行zookeeper

          創(chuàng)建一個(gè)maven項(xiàng)目并導(dǎo)入依賴

          <dependency>
          <groupId>com.dangdang</groupId>
          <artifactId>elastic-job-lite-core</artifactId>
          <version>2.1.5</version>
          </dependency>
          復(fù)制代碼

          寫任務(wù)類

          public class XiaoLinJob implements SimpleJob {

          // 寫任務(wù)類
          @Override
          public void execute(ShardingContext shardingContext) {
          System.out.println("定時(shí)任務(wù)開始");
          }
          }
          復(fù)制代碼

          編寫配置類

          public class JobDemo {

          public static void main(String[] args) {
          new JobScheduler(createRegistryCenter(), createJobConfiguration()).init();
          }
          private static CoordinatorRegistryCenter createRegistryCenter() {
          //配置zk地址,調(diào)度任務(wù)的組名
          ZookeeperConfiguration zookeeperConfiguration = new ZookeeperConfiguration("127.0.0.1:2181", "elastic-job-demo");
          zookeeperConfiguration.setSessionTimeoutMilliseconds(1000);
          CoordinatorRegistryCenter regCenter = new ZookeeperRegistryCenter(zookeeperConfiguration);
          regCenter.init();
          return regCenter;
          }

          private static LiteJobConfiguration createJobConfiguration() {
          // 定義作業(yè)核心配置
          JobCoreConfiguration simpleCoreConfig = JobCoreConfiguration.newBuilder("demoSimpleJob","0/1 * * * * ?",1).build();
          // 定義SIMPLE類型配置
          SimpleJobConfiguration simpleJobConfig = new SimpleJobConfiguration(simpleCoreConfig, XiaoLinJob.class.getCanonicalName());
          // 定義Lite作業(yè)根配置
          LiteJobConfiguration simpleJobRootConfig = LiteJobConfiguration.newBuilder(simpleJobConfig).build();
          return simpleJobRootConfig;
          }
          }
          復(fù)制代碼

          2.2、測試

          1. 當(dāng)只有一臺(tái)啟動(dòng)的時(shí)候,按照corn表達(dá)式進(jìn)行任務(wù)調(diào)度。

          2. 開啟兩臺(tái)機(jī)器的1時(shí)候,新開的一臺(tái)會(huì)繼續(xù)執(zhí)行定時(shí)任務(wù),舊的1那一臺(tái)會(huì)停止。

          三、SpringBoot集成Elastic-Job

          3.1、引入依賴

           <parent>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-parent</artifactId>
          <version>2.1.3.RELEASE</version>
          </parent>

          <dependencies>
          <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
          </dependency>
          <dependency>
          <groupId>com.dangdang</groupId>
          <artifactId>elastic-job-lite-spring</artifactId>
          <version>2.1.5</version>
          </dependency>
          <dependency>
          <groupId>org.projectlombok</groupId>
          <artifactId>lombok</artifactId>
          </dependency>
          </dependencies>
          復(fù)制代碼

          3.2、編寫配置文件

          application.yaml

          因?yàn)榕渲弥行牡牡刂凡皇枪潭ǖ?,所以我們不能寫死在代碼中,需要把他寫在配置文件中。新建一個(gè)配置文件:

          elasticjob:
          zookeeper-url: localhost:2181
          group-name: elastic-job-group
          復(fù)制代碼

          zookeeper注冊中心配置類

          // 注冊中心的配置類
          @Configuration
          public class RegistryCenterConfig {

          @Bean(initMethod = "init")
          // 從配置文件中獲取注冊中心的的url和命名空間
          public CoordinatorRegistryCenter coordinatorRegistryCenter(
          @Value("${elasticjob.zookeeper-url}") String zookeeperUrl,
          @Value("${elasticjob.group-name}") String namespace)
          {
          // zk的配置
          ZookeeperConfiguration zookeeperConfiguration =
          new ZookeeperConfiguration(zookeeperUrl,namespace);
          // 設(shè)置超時(shí)時(shí)間
          zookeeperConfiguration.setMaxSleepTimeMilliseconds(10000000);
          // 創(chuàng)建注冊中心
          ZookeeperRegistryCenter zookeeperRegistryCenter = new ZookeeperRegistryCenter(zookeeperConfiguration);
          return zookeeperRegistryCenter;
          }
          }
          復(fù)制代碼

          任務(wù)調(diào)度的配置類

          @Configuration
          public class JobConfig {

          @Autowired
          XiaoLinJob xiaoLinJob;

          @Autowired
          private CoordinatorRegistryCenter registryCenter;
          private static LiteJobConfiguration createJobConfiguration(
          final Class<? extends SimpleJob> jobClass, // 任務(wù)的名字
          final String cron, // cron表達(dá)式
          final int shardingTotalCount, // 分片的數(shù)量
          final String shardingItemParameters // 分片類信奉的參數(shù)
          )
          {
          JobCoreConfiguration.Builder jobCoreConfigurationBuilder = JobCoreConfiguration.newBuilder(jobClass.getSimpleName(),cron,shardingTotalCount);
          if(!StringUtils.isEmpty(shardingItemParameters)){
          jobCoreConfigurationBuilder.shardingItemParameters(shardingItemParameters);
          }
          SimpleJobConfiguration simpleJobConfig = new SimpleJobConfiguration(jobCoreConfigurationBuilder.build(), XiaoLinJob.class.getCanonicalName());
          LiteJobConfiguration simpleJobRootConfig = LiteJobConfiguration.newBuilder(simpleJobConfig).overwrite(true).build();
          return simpleJobRootConfig;

          }
          @Bean(initMethod = "init")
          public SpringJobScheduler initSimpleElasticJob(){
          SpringJobScheduler springJobScheduler = new SpringJobScheduler(xiaoLinJob,registryCenter,createJobConfiguration(XiaoLinJob.class,"0/3 * * * * ?",1,null));
          return springJobScheduler;
          }

          }
          復(fù)制代碼

          自定義任務(wù)類

          @Component
          public class XiaoLinJob implements SimpleJob {

          @Override
          public void execute(ShardingContext shardingContext) {
          System.out.println("============");
          }
          }
          復(fù)制代碼

          3.3、測試

          四、小案例

          4.1、單機(jī)版本

          4.1.1、需求描述

          數(shù)據(jù)庫中有一些列的數(shù)據(jù),需要對這些數(shù)據(jù)進(jìn)行備份操作,備份完之后,修改數(shù)據(jù)的狀態(tài),標(biāo)記已經(jīng)備份了。

          4.1.2、創(chuàng)建數(shù)據(jù)庫

          SET FOREIGN_KEY_CHECKS=0;

          -- ----------------------------
          -- Table structure for t_file_custom
          -- ----------------------------
          DROP TABLE IF EXISTS `t_file_custom`;
          CREATE TABLE `t_file_custom` (
          `id` bigint(20) NOT NULL AUTO_INCREMENT,
          `name` varchar(255) DEFAULT NULL,
          `content` varchar(255) DEFAULT NULL,
          `type` varchar(255) DEFAULT NULL,
          `backedUp` tinyint(4) DEFAULT NULL,
          PRIMARY KEY (`id`)
          ) ENGINE
          =InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8;

          -- ----------------------------
          -- Records of t_file_custom
          -- ----------------------------
          INSERT INTO `t_file_custom` VALUES ('1', '文件1', '內(nèi)容1', 'text', '1');
          INSERT INTO `t_file_custom` VALUES ('2', '文件2', '內(nèi)容2', 'text', '1');
          INSERT INTO `t_file_custom` VALUES ('3', '文件3', '內(nèi)容3', 'text', '1');
          INSERT INTO `t_file_custom` VALUES ('4', '文件4', '內(nèi)容4', 'image', '1');
          INSERT INTO `t_file_custom` VALUES ('5', '文件5', '內(nèi)容5', 'image', '1');
          INSERT INTO `t_file_custom` VALUES ('6', '文件6', '內(nèi)容6', 'text', '1');
          INSERT INTO `t_file_custom` VALUES ('7', '文件6', '內(nèi)容7', 'radio', '1');
          INSERT INTO `t_file_custom` VALUES ('8', '文件8', '內(nèi)容8', 'radio', '1');
          INSERT INTO `t_file_custom` VALUES ('9', '文件9', '內(nèi)容9', 'vedio', '1');
          INSERT INTO `t_file_custom` VALUES ('10', '文件10', '內(nèi)容10', 'vedio', '1');
          INSERT INTO `t_file_custom` VALUES ('11', '文件11', '內(nèi)容11', 'vedio', '1');
          INSERT INTO `t_file_custom` VALUES ('12', '文件12', '內(nèi)容12', 'vedio', '1');
          INSERT INTO `t_file_custom` VALUES ('13', '文件13', '內(nèi)容13', 'image', '1');
          INSERT INTO `t_file_custom` VALUES ('14', '文件14', '內(nèi)容14', 'text', '1');
          INSERT INTO `t_file_custom` VALUES ('15', '文件15', '內(nèi)容15', 'image', '1');
          INSERT INTO `t_file_custom` VALUES ('16', '文件16', '內(nèi)容16', 'text', '1');
          INSERT INTO `t_file_custom` VALUES ('17', '文件17', '內(nèi)容17', 'radio', '1');
          INSERT INTO `t_file_custom` VALUES ('18', '文件18', '內(nèi)容18', 'image', '1');
          INSERT INTO `t_file_custom` VALUES ('19', '文件19', '內(nèi)容19', 'radio', '1');
          INSERT INTO `t_file_custom` VALUES ('20', '文件20', '內(nèi)容20', 'vedio', '1');

          復(fù)制代碼

          4.1.3、Druid&MyBatis

          4.1.3.1、添加依賴

                  <dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>druid</artifactId>
          <version>1.1.10</version>
          </dependency>
          <dependency>
          <groupId>org.mybatis.spring.boot</groupId>
          <artifactId>mybatis-spring-boot-starter</artifactId>
          <version>1.2.0</version>
          </dependency>
          <!--mysql驅(qū)動(dòng)-->
          <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          </dependency>
          復(fù)制代碼

          4.1.3.2、集成數(shù)據(jù)庫

          spring:
          datasource:
          url: jdbc:mysql://localhost:3306/elastic-job-demo?serverTimezone=GMT%2B8
          driverClassName: com.mysql.jdbc.Driver
          type: com.alibaba.druid.pool.DruidDataSource
          username: root
          password: admin
          復(fù)制代碼

          4.1.4、添加實(shí)體類

          @Data
          public class FileCustom {
          //唯一標(biāo)識
          private Long id;
          //文件名
          private String name;
          //文件類型
          private String type;
          //文件內(nèi)容
          private String content;
          //是否已備份
          private Boolean backedUp = false;
          public FileCustom(){}
          public FileCustom(Long id, String name, String type, String content){
          this.id = id;
          this.name = name;
          this.type = type;
          this.content = content;
          }
          }
          復(fù)制代碼

          4.1.5、添加任務(wù)類

          @Slf4j
          @Component
          public class FileCustomElasticJob implements SimpleJob {

          @Autowired
          FileCopyMapper fileCopyMapper;

          @Override
          public void execute(ShardingContext shardingContext) {
          doWork();
          }

          private void doWork() {
          List<FileCustom> fileCustoms = fileCopyMapper.selectAll();
          if (fileCustoms.size() == 0){
          log.info("備份完成");
          return;
          }
          log.info("需要備份的文件個(gè)數(shù)為:"+fileCustoms.size());
          for (FileCustom fileCustom : fileCustoms) {
          backUpFile(fileCustom);
          }
          }

          private void backUpFile(FileCustom fileCustom) {
          try {
          Thread.sleep(1000);
          log.info("執(zhí)行備份文件:"+fileCustom);
          fileCopyMapper.backUpFile(fileCustom.getId());

          } catch (InterruptedException e) {
          e.printStackTrace();
          }
          }
          }
          復(fù)制代碼

          4.1.6、添加Mapper

          @Mapper
          public interface FileCopyMapper {

          @Select("select * from t_file_custom where backedUp = 0")
          List<FileCustom> selectAll();

          @Update("update t_file_custom set backedUp = 1 where id = #{id}")
          void backUpFile(Long id);
          }
          復(fù)制代碼

          4.1.7、添加任務(wù)調(diào)度配置

            @Bean(initMethod = "init")
          public SpringJobScheduler initFileCustomElasticJob(FileCustomElasticJob fileCustomElasticJob){
          SpringJobScheduler springJobScheduler = new SpringJobScheduler(fileCustomElasticJob,registryCenter,createJobConfiguration(XiaoLinJob.class,"0/3 * * * * ?",1,null));
          return springJobScheduler;
          }
          復(fù)制代碼

          4.1.8、存在的問題

          為了高可用,我們會(huì)對這個(gè)項(xiàng)目做集群的操作,可以保證其中一臺(tái)掛了,另外一臺(tái)可以繼續(xù)工作.但是在集群的情況下,調(diào)度任務(wù)只在一臺(tái)機(jī)器上運(yùn)行,如果單個(gè)任務(wù)調(diào)度比較耗時(shí),耗資源的情況下,對這臺(tái)機(jī)器的消耗還是比較大的。

          但是這個(gè)時(shí)候,其他機(jī)器卻是空閑著的,如何合理的利用集群的其他機(jī)器且如何讓任務(wù)執(zhí)行得更快些呢?這時(shí)候Elastic-Job提供了任務(wù)調(diào)度分片的功能。

          4.2、集群版本

          4.2.1、分片概念

          作業(yè)分片是指任務(wù)的分布式執(zhí)行,需要將一個(gè)任務(wù)拆分為多個(gè)獨(dú)立的任務(wù)項(xiàng),然后由分布式的應(yīng)用實(shí)例分別執(zhí)行某一個(gè)或者幾個(gè)分布項(xiàng)。

          例如在單機(jī)版本的備份數(shù)據(jù)的案例,如果有兩臺(tái)服務(wù)器,每臺(tái)服務(wù)器分別跑一個(gè)應(yīng)用實(shí)例。為了快速執(zhí)行作業(yè),那么可以講任務(wù)分成4片,每個(gè)應(yīng)用實(shí)例都執(zhí)行兩片。作業(yè)遍歷數(shù)據(jù)邏輯應(yīng)為:實(shí)例1查找text和image類型文件執(zhí)行備份,實(shí)例2查找radio和vedio類型文件執(zhí)行備份。

          如果由于服務(wù)器拓容應(yīng)用實(shí)例數(shù)量增加為4,則作業(yè)遍歷數(shù)據(jù)的邏輯應(yīng)為: 4個(gè)實(shí)例分別處理text、image、radio、video類型的文件。

          通過對任務(wù)的合理分片化,從而達(dá)到任務(wù)并行處理的效果,他的好處是:

          1. 分片項(xiàng)與業(yè)務(wù)處理解耦:Elastic-Job并不直接提供數(shù)據(jù)處理的功能,框架只會(huì)將分片項(xiàng)分配至各個(gè)運(yùn)行中的作業(yè)服務(wù)器,開發(fā)者需要自行處理分片項(xiàng)與真實(shí)數(shù)據(jù)的對應(yīng)關(guān)系。

          2. 最大限度利用資源:將分片項(xiàng)設(shè)置大于服務(wù)器的數(shù)據(jù),最好是大于服務(wù)器倍數(shù)的數(shù)量,作業(yè)將會(huì)合理利用分布式資源,動(dòng)態(tài)的分配分片項(xiàng)。例如:3臺(tái)服務(wù)器,分成10片,則分片項(xiàng)結(jié)果為服務(wù)器A=0、1、2。服務(wù)器B=3、4、5。服務(wù)器C=6、7、8、9。如果   服務(wù)器C奔潰,則分片項(xiàng)分配結(jié)果為服務(wù)器A=0、1、2、3、4。服務(wù)器B=5、6、7、8、9。在不丟失分片項(xiàng)的情況下,最大限度利用現(xiàn)有的資源提高吞吐量。

          4.2.2、配置類修改

          如果想將單機(jī)版本改為集群版本,我們首先需要在任務(wù)配置類中增加分片個(gè)數(shù)以及分片參數(shù)。

          @Bean(initMethod = "init")
          public SpringJobScheduler initFileCustomElasticJob(FileCustomElasticJob fileCustomElasticJob){
          SpringJobScheduler springJobScheduler = new
          //第一個(gè)參數(shù)表示自定義任務(wù)類,第二個(gè)參數(shù)是corn表達(dá)式,第三個(gè)參數(shù)是分片個(gè)數(shù),第四個(gè)參數(shù)是分片的名稱,第一個(gè)分片作用是查詢類型為test的,以此類推
          SpringJobScheduler(fileCustomElasticJob,registryCenter,createJobConfiguration(XiaoLinJob.class,"0/3 * * * * ?",4,"0=text,1=image,2=radio,3=vedio"));
          return springJobScheduler;
          }
          復(fù)制代碼

          4.2.3、 新增作業(yè)分片邏輯

          @Slf4j
          @Component
          public class FileCustomElasticJob implements SimpleJob {

          @Autowired
          FileCopyMapper fileCopyMapper;

          @Override
          public void execute(ShardingContext shardingContext) {
          // 獲取到指定分片的類型
          doWork(shardingContext.getShardingParameter());
          }

          private void doWork(String fileType) {
          List<FileCustom> fileCustoms = fileCopyMapper.selectByType(fileType);
          if (fileCustoms.size() == 0){
          log.info("備份完成");
          return;
          }
          log.info("需要備份的文件類型是:"+fileType+"文件個(gè)數(shù)為:"+fileCustoms.size());
          for (FileCustom fileCustom : fileCustoms) {
          backUpFile(fileCustom);
          }
          }

          private void backUpFile(FileCustom fileCustom) {
          try {
          Thread.sleep(2000);
          log.info("執(zhí)行備份文件:"+fileCustom);
          fileCopyMapper.backUpFile(fileCustom.getId());

          } catch (InterruptedException e) {
          e.printStackTrace();
          }
          }
          }
          復(fù)制代碼

          4.2.4、Mapper類修改

          @Mapper
          public interface FileCopyMapper {

          @Select("select * from t_file_custom where backedUp = 0")
          List<FileCustom> selectAll();

          @Update("update t_file_custom set backedUp = 1 where id = #{id}")
          void backUpFile(Long id);

          @Select("select * from t_file_custom where backedUp = 0 and type = #{fileType}")
          List<FileCustom> selectByType(String fileType);
          }
          復(fù)制代碼

          4.2.5、測試

          4.2.5.1、一臺(tái)機(jī)器

          一臺(tái)機(jī)器啟動(dòng)四個(gè)線程直接跑完。

          4.2.5.2、四臺(tái)機(jī)器

          當(dāng)四臺(tái)機(jī)器啟動(dòng)的時(shí)候,每臺(tái)機(jī)器分得一個(gè)線程,查詢并備份一種類型的數(shù)據(jù)。

          ----------------------------------------------------------我是分割線----------------------------------------------------------

          ----------------------------------------------------------我是分割線----------------------------------------------------------

          ----------------------------------------------------------我是分割線----------------------------------------------------------


          作者:XiaoLin_Java
          鏈接:https://juejin.cn/post/7007058861379190821
          來源:掘金
          著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。



          瀏覽 27
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  韩国av三级片麻豆 | 中文字幕第59页 | 天堂a | 91丝袜| 免费的黄色A片 |