日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

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

瀏覽:73日期:2023-08-14 14:35:11

1 前言

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

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

(2)MQ模式:worker是一個常駐進程,Manager和Worker通過消息隊列來傳遞參數;網上有不少相關示例代碼。

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

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

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

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

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

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

2 代碼講解

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

2.1 項目準備

2.1.1 數據庫

首先我們需要準備一個數據庫,因為Manager和Worker都需要同步狀態到DB上,不能直接使用嵌入式的內存數據庫了,需要一個外部可共同訪問的數據庫。這里我使用的是H2 Database,安裝可參考:把H2數據庫從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,非常關鍵;其它就是Spring Batch和Task相關的依賴;以及數據庫連接。

2.1.3 主類入口

Springboot的主類入口如下:

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

在Springboot的基礎上,添加了Spring Batch和Spring Cloud Task的支持。

2.2 關鍵代碼編寫

前面的數據庫搭建和其它代碼沒有太多可講的,接下來就開始關鍵代碼的編寫。

2.2.1 分區管理Partitioner

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

具體代碼如下:

private static final int GRID_SIZE = 4;@Beanpublic 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個區,程序會啟動4個worker來處理;給worker傳遞的參數是partitionNumber。

2.2.2 分區處理器PartitionHandler

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

@Beanpublic 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;}

上面代碼中:

resource是worker的jar包地址,表示將啟動該程序;

workerStep是worker將要執行的step;

commandLineArgs定義了啟動worker的jvm參數,如--spring.profiles.active=worker;

environment是manager的系統環境變量,可以傳遞給worker,當然也可以選擇不傳遞;

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

2.2.3 Manager和Worker的Batch定義

完成了分區相關的代碼,剩下的就只是如何定義Manager和Worker的業務代碼了。

Manager作為管理者,不用太多業務邏輯,代碼如下:

@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();}@Beanpublic Step step1(PartitionHandler partitionHandler) throws Exception { return this.stepBuilderFactory.get('step1') .partitioner(workerStep().getName(), partitioner()) .step(workerStep()) .partitionHandler(partitionHandler) .build();}

Worker主要作用是處理數據,是我們的業務代碼,這里就演示一下如何獲取Manager傳遞過來的partitionNumber:

@Beanpublic Step workerStep() { return this.stepBuilderFactory.get('workerStep') .tasklet(workerTasklet(null, null)) .build();}@Bean@StepScopepublic 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 程序運行

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

spring.datasource.url=jdbc:h2:tcp://localhost:9092/testspring.datasource.username=pkslowspring.datasource.password=pkslowspring.datasource.driver-class-name=org.h2.Driverpkslow.worker.resource=file://pkslow/target/remote-partitioning-jar-1.0-SNAPSHOT.jar

執行程序如下:

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

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

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

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

4 復雜變量傳遞

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

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 總結

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

標簽: Spring
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
蘑菇福利视频一区播放| 国产精品115| 欧美日韩一区二区三区在线电影| 色狠狠一区二区三区| 国产精品久久久久av蜜臀| 丝袜诱惑一区二区| 欧美日韩激情| 亚洲欧美久久久| 日韩成人a**站| 91精品观看| 国产亚洲人成a在线v网站| 欧美精品99| 久久国产直播| 欧美天堂一区| 欧美日韩免费看片| 在线视频精品| 欧美一区精品| 99综合视频| 国产精品资源| 亚洲高清毛片| 91成人小视频| 日韩精品国产精品| 日本aⅴ免费视频一区二区三区| 日韩在线一区二区| 免费观看在线综合| 蜜桃视频免费观看一区| 亚洲精品日韩久久| 青草综合视频| 欧美黑人做爰爽爽爽| 国产福利资源一区| 欧美偷窥清纯综合图区| 麻豆精品在线观看| 在线日韩欧美| 亚洲在线观看| 蜜桃一区二区三区在线观看| 69精品国产久热在线观看| 国产粉嫩在线观看| 日韩精品1区2区3区| 国产精品久久国产愉拍| 麻豆久久一区| 欧美日韩亚洲一区二区三区在线| 国产精品扒开腿做爽爽爽软件| 久久亚洲黄色| 欧美手机在线| 91成人小视频| 国产一区二区三区亚洲| 久久国产小视频| 日韩精品a在线观看91| 日韩在线短视频| 日本精品国产| 黄色在线网站噜噜噜| 欧美精品一区二区三区精品| 欧美日韩亚洲三区| 国产精品av久久久久久麻豆网| 在线亚洲精品| 亚洲tv在线| 国产精品麻豆成人av电影艾秋| 精品中文字幕一区二区三区 | 欧美久久香蕉| 欧美综合另类| 97精品一区二区| 日韩av资源网| 蜜桃一区二区三区在线观看| 国产h片在线观看| 国产欧美一区二区三区国产幕精品 | 国产免费播放一区二区| 92国产精品| 日韩精品视频网站| 久久人人99| 美女福利一区二区三区| 91福利精品在线观看| 亚洲一区二区成人| 久久久人人人| av资源亚洲| 精品一区二区三区视频在线播放| 亚洲欧洲美洲国产香蕉| 欧美日韩国产综合网| 国产一区观看| 日韩精品久久理论片| 国产精品一区二区三区av| 国产福利片在线观看| 国产a亚洲精品| 精品91福利视频| 日韩久久电影| 欧美日韩精品一本二本三本| 一区二区精品| 中文字幕色婷婷在线视频| 欧美日韩精品免费观看视频完整| 亚洲精品女人| 91亚洲自偷观看高清| 免费国产自久久久久三四区久久| 国产精品chinese| 中文字幕在线免费观看视频| 亚洲欧美日韩在线观看a三区 | 欧美aa在线观看| 精品一区亚洲| 日韩精品三区四区| 国产精品久久久免费| 国产精品二区不卡| 蜜桃一区二区三区| 老鸭窝毛片一区二区三区| 国产视频欧美| 精品一区二区三区中文字幕在线| 国产伦精品一区二区三区千人斩| 粉嫩av一区二区三区四区五区 | 国产国产精品| 一区二区亚洲视频| 精品亚洲二区| 水蜜桃久久夜色精品一区的特点| 国产激情综合| 久久国产高清| 亚洲在线一区| 欧美日韩亚洲一区二区三区在线| 国产亚洲电影| 青青久久av| 欧美亚洲综合视频| 少妇精品久久久一区二区| 日韩精品一级| 亚洲欧美在线专区| 五月精品视频| 亚洲播播91| 国产精品一区二区美女视频免费看 | 91精品韩国| 久久伊人国产| 欧美精品aa| 日本在线一区二区三区| 久久亚洲精精品中文字幕| 青青在线精品| 欧美亚洲色图校园春色| 国产精品亚洲综合色区韩国| 亚洲a在线视频| 日韩av一区二区三区| 精品一区毛片| 欧美精选视频一区二区| 欧美综合精品| 亚洲专区一区| 婷婷成人综合| 91一区二区| 精品视频亚洲| 欧美日一区二区在线观看| 欧美日韩视频一区二区三区| 88xx成人免费观看视频库| 麻豆久久久久久久| 国产精品国产一区| 欧洲亚洲一区二区三区| 国产激情精品一区二区三区| 在线综合亚洲| 噜噜噜久久亚洲精品国产品小说| 欧洲在线一区| 欧美日韩四区| 国产91精品对白在线播放| 国产精品xx| 免费黄色成人| 日韩综合一区二区| 欧美日本不卡| 日韩在线高清| 另类亚洲自拍| 一区二区精品| 精品视频亚洲| 亚洲综合不卡| 国产亚洲欧美日韩精品一区二区三区| 69堂精品视频在线播放| 色婷婷久久久| 国产欧美一区| 三级小说欧洲区亚洲区| 在线免费观看亚洲| 久久精品国内一区二区三区水蜜桃| 亚洲欧美日韩综合国产aⅴ| 天堂av一区| 欧美亚洲国产激情| 日本精品久久| 成人在线观看免费视频| 欧美午夜精彩| 蜜桃精品视频| 美女久久一区| 亚洲婷婷在线| 国产无遮挡裸体免费久久| 免费看av不卡| 日韩动漫一区| 亚洲自拍另类| 色婷婷久久久| 国产精品videossex久久发布| 欧美+亚洲+精品+三区| 欧美国产中文高清| 婷婷综合福利| 欧美另类专区| 日本欧美不卡| 日本午夜精品久久久| 少妇久久久久| 麻豆精品在线观看| 久久av导航| 国产精久久久| 国产欧美三级| 国产一卡不卡| 欧美日韩91| 久久国产婷婷国产香蕉| 最新亚洲国产| 亚洲欧洲免费| 欧美日一区二区三区在线观看国产免| 一区二区三区国产在线|