最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Batch遠程分區(qū)的本地Jar包模式的代碼詳解

 更新時間:2020年09月15日 08:41:53   作者:南瓜慢說  
這篇文章主要介紹了Spring Batch遠程分區(qū)的本地Jar包模式,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下

1 前言

Spring Batch遠程分區(qū)對于大量數(shù)據(jù)的處理非常擅長,它的實現(xiàn)有多種方式,如本地Jar包模式、MQ模式、Kubernetes模式。這三種模式的如下:

(1)本地Jar包模式:分區(qū)處理的worker為一個Java進程,從jar包啟動,通過jvm參數(shù)和數(shù)據(jù)庫傳遞參數(shù);官方提供示例代碼。

(2)MQ模式worker是一個常駐進程,ManagerWorker通過消息隊列來傳遞參數(shù);網(wǎng)上有不少相關(guān)示例代碼。

(3)Kubernetes模式workerK8s中的Pod,Manager直接啟動Pod來處理;網(wǎng)上并沒有找到任何示例代碼。

本文將通過代碼來講解第一種模式(本地Jar包模式),其它后續(xù)再介紹。

建議先看下面文章了解一下:

Spring Batch入門:Spring Batch入門教程篇

Spring Batch并行處理介紹:詳解SpringBoot和SpringBatch 使用

2 代碼講解

本文代碼中,ManagerWorker是放在一起的,在同一個項目里,也只會打一個jar包而已;我們通過profile來區(qū)別是manager還是worker,也就是通過Spring Profile實現(xiàn)一份代碼,兩份邏輯。實際上也可以拆成兩份代碼,但放一起更方便測試,而且代碼量不大,就沒有必要了。

2.1 項目準(zhǔn)備

2.1.1 數(shù)據(jù)庫

首先我們需要準(zhǔn)備一個數(shù)據(jù)庫,因為ManagerWorker都需要同步狀態(tài)到DB上,不能直接使用嵌入式的內(nèi)存數(shù)據(jù)庫了,需要一個外部可共同訪問的數(shù)據(jù)庫。這里我使用的是H2 Database,安裝可參考:把H2數(shù)據(jù)庫從jar包部署到Kubernetes,并解決Ingress不支持TCP的問題。

2.1.2 引入依賴

maven引入依賴如下所示:

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-batch</artifactId>
</dependency>
<dependency>
 <groupId>org.springframework.cloud</groupId>
 <artifactId>spring-cloud-starter-task</artifactId>
</dependency>
<dependency>
 <groupId>com.h2database</groupId>
 <artifactId>h2</artifactId>
 <scope>runtime</scope>
</dependency>

<dependency>
 <groupId>org.springframework.cloud</groupId>
 <artifactId>spring-cloud-deployer-local</artifactId>
 <version>2.4.1</version>
</dependency>

<dependency>
 <groupId>org.springframework.batch</groupId>
 <artifactId>spring-batch-integration</artifactId>
</dependency>

spring-cloud-deployer-local用于部署和啟動worker,非常關(guān)鍵;其它就是Spring BatchTask相關(guān)的依賴;以及數(shù)據(jù)庫連接。

2.1.3 主類入口

Springboot的主類入口如下:

@EnableTask
@SpringBootApplication
@EnableBatchProcessing
public class PkslowRemotePartitionJar {
 public static void main(String[] args) {
 SpringApplication.run(PkslowRemotePartitionJar.class, args);
 }
}

Springboot的基礎(chǔ)上,添加了Spring BatchSpring Cloud Task的支持。

2.2 關(guān)鍵代碼編寫

前面的數(shù)據(jù)庫搭建和其它代碼沒有太多可講的,接下來就開始關(guān)鍵代碼的編寫。

2.2.1 分區(qū)管理Partitioner

Partitioner是遠程分區(qū)中的核心bean,它定義了分成多少個區(qū)、怎么分區(qū),要把什么變量傳遞給worker。它會返回一組<分區(qū)名,執(zhí)行上下文>的鍵值對,即返回Map<String, ExecutionContext>。把要傳遞給worker的變量放在ExecutionContext中去,支持多種類型的變量,如String、intlong等。實際上,我們不建議通過ExecutionContext來傳遞太多數(shù)據(jù);可以傳遞一些標(biāo)識或主鍵,然后worker自己去拿數(shù)據(jù)即可。

具體代碼如下:

private static final int GRID_SIZE = 4;
@Bean
public Partitioner partitioner() {
 return new Partitioner() {
 @Override
 public Map<String, ExecutionContext> partition(int gridSize) {

 Map<String, ExecutionContext> partitions = new HashMap<>(gridSize);

 for (int i = 0; i < GRID_SIZE; i++) {
 ExecutionContext executionContext = new ExecutionContext();
 executionContext.put("partitionNumber", i);
 partitions.put("partition" + i, executionContext);
 }

 return partitions;
 }
 };
}

上面分成4個區(qū),程序會啟動4個worker來處理;給worker傳遞的參數(shù)是partitionNumber。

2.2.2 分區(qū)處理器PartitionHandler

PartitionHandler也是核心的bean,它決定了怎么去啟動worker,給它們傳遞什么jvm參數(shù)(跟之前的ExecutionContext傳遞不一樣)。

@Bean
public PartitionHandler partitionHandler(TaskLauncher taskLauncher, JobExplorer jobExplorer, TaskRepository taskRepository) throws Exception {

 Resource resource = this.resourceLoader.getResource(workerResource);

 DeployerPartitionHandler partitionHandler =
 new DeployerPartitionHandler(taskLauncher, jobExplorer, resource, "workerStep", taskRepository);

 List<String> commandLineArgs = new ArrayList<>(3);
 commandLineArgs.add("--spring.profiles.active=worker");
 commandLineArgs.add("--spring.cloud.task.initialize-enabled=false");
 commandLineArgs.add("--spring.batch.initializer.enabled=false");

 partitionHandler
 .setCommandLineArgsProvider(new PassThroughCommandLineArgsProvider(commandLineArgs));
 partitionHandler
 .setEnvironmentVariablesProvider(new SimpleEnvironmentVariablesProvider(this.environment));
 partitionHandler.setMaxWorkers(2);
 partitionHandler.setApplicationName("PkslowWorkerJob");

 return partitionHandler;
}

上面代碼中:

resourceworkerjar包地址,表示將啟動該程序;

workerStepworker將要執(zhí)行的step;

commandLineArgs定義了啟動workerjvm參數(shù),如--spring.profiles.active=worker;

environmentmanager的系統(tǒng)環(huán)境變量,可以傳遞給worker,當(dāng)然也可以選擇不傳遞;

MaxWorkers是最多能同時啟動多少個worker,類似于線程池大??;設(shè)置為2,表示最多同時有2個worker來處理4個分區(qū)。

2.2.3 Manager和Worker的Batch定義

完成了分區(qū)相關(guān)的代碼,剩下的就只是如何定義ManagerWorker的業(yè)務(wù)代碼了。

Manager作為管理者,不用太多業(yè)務(wù)邏輯,代碼如下:

@Bean
@Profile("!worker")
public Job partitionedJob(PartitionHandler partitionHandler) throws Exception {
 Random random = new Random();
 return this.jobBuilderFactory.get("partitionedJob" + random.nextInt())
 .start(step1(partitionHandler))
 .build();
}

@Bean
public Step step1(PartitionHandler partitionHandler) throws Exception {
 return this.stepBuilderFactory.get("step1")
 .partitioner(workerStep().getName(), partitioner())
 .step(workerStep())
 .partitionHandler(partitionHandler)
 .build();
}

Worker主要作用是處理數(shù)據(jù),是我們的業(yè)務(wù)代碼,這里就演示一下如何獲取Manager傳遞過來的partitionNumber

@Bean
public Step workerStep() {
 return this.stepBuilderFactory.get("workerStep")
 .tasklet(workerTasklet(null, null))
 .build();
}

@Bean
@StepScope
public Tasklet workerTasklet(final @Value("#{stepExecutionContext['partitionNumber']}") Integer partitionNumber) {
 return new Tasklet() {
 @Override
 public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
 Thread.sleep(6000); //增加延時,查看效果,通過jps:在jar情況下會新起java進程
 System.out.println("This tasklet ran partition: " + partitionNumber);
 
 return RepeatStatus.FINISHED;
 }
 };
}

通過表達式@Value("#{stepExecutionContext['partitionNumber']}") 獲取Manager傳遞過來的變量;注意要加注解@StepScope

3 程序運行

因為我們分為ManagerWorker,但都是同一份代碼,所以我們先打包一個jar出來,不然manager無法啟動。配置數(shù)據(jù)庫和Workerjar包地址如下:

spring.datasource.url=jdbc:h2:tcp://localhost:9092/test
spring.datasource.username=pkslow
spring.datasource.password=pkslow
spring.datasource.driver-class-name=org.h2.Driver

pkslow.worker.resource=file://pkslow/target/remote-partitioning-jar-1.0-SNAPSHOT.jar

執(zhí)行程序如下:

可以看到啟動了4次Java程序,還給出日志路徑。

通過jps命令查看,能看到一個Manager進程,還有兩個worker進程:

4 復(fù)雜變量傳遞

前面講了Manager可以通過ExecutionContext傳遞變量,如簡單的String、long等。但其實它也是可以傳遞復(fù)雜的Java對象的,但對應(yīng)的類需要可序列化,如:

import java.io.Serializable;

public class Person implements Serializable {
 private Integer age;
 private String name;
 private String webSite;
 //getter and setter
}

Manager傳遞:

executionContext.put("person", new Person(0, "pkslow", "www.pkslow.com"));

Worker接收:

@Value("#{stepExecutionContext['person']}") Person person

5 總結(jié)

本文介紹了Spring Batch遠程分區(qū)的本地Jar包模式,只能在一臺機器上運行,所以也是無法真正發(fā)揮出遠程分區(qū)的作用。但它對我們后續(xù)理解更復(fù)雜的模式是有很大幫助的;同時,我們也可以使用本地模式進行開發(fā)測試,畢竟它只需要一個數(shù)據(jù)庫就行了,依賴很少。

相關(guān)文章

  • springboot中server.ssl.key-store配置路徑的問題小結(jié)

    springboot中server.ssl.key-store配置路徑的問題小結(jié)

    這篇文章主要介紹了springboot中server.ssl.key-store配置路徑的問題,文中還記錄了Spring Boot SSL(https)實例,介紹在web程序中使用自簽名的SSL(HTTPS)證書及創(chuàng)建SSL認證,感興趣的朋友跟隨小編一起看看吧
    2024-02-02
  • java如何根據(jù)模板導(dǎo)出數(shù)據(jù)到word文檔中(表格、自定義標(biāo)簽等)

    java如何根據(jù)模板導(dǎo)出數(shù)據(jù)到word文檔中(表格、自定義標(biāo)簽等)

    這篇文章主要介紹了關(guān)于java如何根據(jù)模板導(dǎo)出數(shù)據(jù)到word文檔中(表格、自定義標(biāo)簽等)的相關(guān)資料,主要包括創(chuàng)建docx文檔,配置模板信息,以及利用XDocReport+FreeMarker技術(shù)進行實現(xiàn),詳細介紹了在Word模板中如何設(shè)置字段以及如何通過代碼填充這些字段,需要的朋友可以參考下
    2024-11-11
  • SpringBoot項目中出現(xiàn)不同端口跨域問題的解決方法

    SpringBoot項目中出現(xiàn)不同端口跨域問題的解決方法

    這篇文章主要介紹了SpringBoot項目中出現(xiàn)不同端口跨域問題的解決方法,文中介紹了兩種解決方法,并給出了詳細的代碼供大家參考,具有一定的參考價值,需要的朋友可以參考下
    2024-03-03
  • 一道Java集合框架題 多種解題思路

    一道Java集合框架題 多種解題思路

    這篇文章主要介紹了一道Java集合框架題,多種解題思路,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • Java設(shè)計模式之監(jiān)聽器模式實例詳解

    Java設(shè)計模式之監(jiān)聽器模式實例詳解

    這篇文章主要介紹了Java設(shè)計模式之監(jiān)聽器模式,結(jié)合實例形式較為詳細的分析了java設(shè)計模式中監(jiān)聽器模式的概念、原理及相關(guān)實現(xiàn)與使用技巧,需要的朋友可以參考下
    2018-02-02
  • Mybatis返回單個實體或者返回List的實現(xiàn)

    Mybatis返回單個實體或者返回List的實現(xiàn)

    這篇文章主要介紹了Mybatis返回單個實體或者返回List的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • 如何在Eclipse中設(shè)置Oracle的JDBC

    如何在Eclipse中設(shè)置Oracle的JDBC

    以下是對在Eclipse中設(shè)置Oracle的JDBC的具體操作方法進行了詳細的分析介紹,需要的朋友可以過來參考下
    2013-08-08
  • Java中Scanner類基礎(chǔ)使用、可能遇到的問題及注意事項

    Java中Scanner類基礎(chǔ)使用、可能遇到的問題及注意事項

    Scanner類是一個用于Scanner指的是java.util包下的Scanner類,可以接收控制臺輸入的數(shù)據(jù),這篇文章主要介紹了Java中Scanner類基礎(chǔ)使用、可能遇到的問題及注意事項的相關(guān)資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2025-04-04
  • Mybatis如何構(gòu)建SQL語句

    Mybatis如何構(gòu)建SQL語句

    這篇文章主要介紹了Mybatis如何構(gòu)建SQL語句問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • Redisson 分布式延時隊列 RedissonDelayedQueue 運行流程

    Redisson 分布式延時隊列 RedissonDelayedQueue 運行流程

    這篇文章主要介紹了Redisson分布式延時隊列 RedissonDelayedQueue運行流程,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-09-09

最新評論

上饶县| 霍邱县| 香港 | 乌兰浩特市| 潜山县| 湘西| 工布江达县| 林西县| 武义县| 大冶市| 天等县| 浦城县| 遂昌县| 襄汾县| 科技| 洪湖市| 内乡县| 沙河市| 内江市| 桑植县| 新绛县| 永寿县| 株洲县| 锦屏县| 尤溪县| 木里| 凤翔县| 尚志市| 安康市| 石门县| 甘谷县| 泽州县| 泰兴市| 温州市| 余姚市| 新余市| 商水县| 新蔡县| 福州市| 虹口区| 双辽市|