分享一下近期我对这个项目的一些改进。
在项目中,经常会有一些批处理的定时任务需要配置,目前的java项目一般采用Spring-Batch来作为批处理的平台。
但是Spring-Batch在对Job流程(并行,分支,条件分支,合并等)的支持略显复杂臃肿。
尤其是流程可视化这方面几乎不支持。
所以,最近对ladybugflow做了改进,在天然支持可视化流程的基础上,追加了对定时任务的支持。
本篇文章介绍ladybugflow定时任务的配置,和与SpringBatch相结合完成批处理的可视化操作的例子。
对于流程的执行,前面文章介绍了流程的启动方法,如下:
Flow1 testFlow = new Flow1(); testFlow.startFlow(true);
这样只能完成流程的一次启动,如果需要定时启动流程,ladybugflow提供了在启动节点中设置cron表达式的方法来实现定时启动流程。
我们首先简单的了解一下cron表达式
Cron表达式是有六个空格分隔的时间和日期字段(域)组成的字符串。
┌───────────── second (0-59)
│ ┌───────────── minute (0 - 59)
│ │ ┌───────────── hour (0 - 23)
│ │ │ ┌───────────── day of the month (1 - 31)
│ │ │ │ ┌───────────── month (1 - 12) (or JAN-DEC)
│ │ │ │ │ ┌───────────── day of the week (0 - 7)
│ │ │ │ │ │ (0 or 7 is Sunday, or MON-SUN)
│ │ │ │ │ │
* * * * * *
比如:
“0 0 * * * *” = 每天 00:00。
"*/10 * * * * *" = 每 10 秒。
“0 0 8-10 * * *” = 每天 8、9 和 10 个小时。
"0 0 6,19 * * *" = 每天早上 6:00 和晚上 7:00。
“0 0/30 8-10 * * *” = 每天 8:00、8:30、9:00、9:30、10:00 和 10:30。
"0 0 9-17 * * MON-FRI" = 工作日 9 到 5
“0 0 0 25 12 ?” = 圣诞节午夜
"0 0 0 L * *" = 每个月的午夜
"0 0 0 L-3 * *" = 每月第三天到最后一天午夜
"0 0 0 1W * *" = 每月第一个工作日午夜
"0 0 0 LW * *" = 每月最后一个工作日的午夜
"0 0 0 * * 5L" = 每月最后一个星期五的午夜
"0 0 0 * * THUL" = 每月最后一个星期四的午夜
"0 0 0 ? * 5#2" = 每月第二个星期五的午夜
"0 0 0 ? * MON#1" = 每月第一个星期一的午夜
在流程编辑器中,将流程的首节点的启动类型设置成Timer,然后输入cron表达式,如下图所示
点击更新,更新json,
将json字符串拷贝到工程里,
启动工程,如下:
运行结果
[I]2022/08/09 18:23:35.547 main:ladybugflow.properties in root path not found, use default configuration [I]2022/08/09 18:23:35.558 main:NodePool started. [I]2022/08/09 18:23:35.559 main:Ready queue consumer thread started. [I]2022/08/09 18:23:35.610 main:Complete queue consumer thread started. [I]2022/08/09 18:23:36.230 [your flow id][283eb8de-e12c-4de0-9484-51da87538032] main:json: {"flowId":"your flow id","nodes":[{"id":"1","label":"start","readyCheck":0,"startType":3,"startCron":"0 0/1 * * * ?"},{"id":"a1a38c2e-0e05-4c68-bd49-f12aea070876","label":"查询用户信息","readyCheck":0,"startType":0,"startCron":null},{"id":"1a90a997-4390-470a-ae7c-626a725438d2","label":"查询酒店信息","readyCheck":0,"startType":0,"startCron":null},{"id":"52289e99-363d-4453-8077-ca8bdc6d35bf","label":"下单","readyCheck":0,"startType":0,"startCron":null},{"id":"16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2","label":"下单成功","readyCheck":0,"startType":0,"startCron":null}],"edges":[{"id":"1","from":"1","to":"2","condition":null,"arrows":"to"},{"id":"b3ad7ab3-8fb6-4527-8cae-6845e03da3e4","from":"1","to":"a1a38c2e-0e05-4c68-bd49-f12aea070876","condition":null,"arrows":"to"},{"id":"001375c7-19e7-436b-bbcd-68e36c8f23b7","from":"1","to":"1a90a997-4390-470a-ae7c-626a725438d2","condition":null,"arrows":"to"},{"id":"dd830043-c7a7-4c71-b91c-10c007b7b19c","from":"1a90a997-4390-470a-ae7c-626a725438d2","to":"52289e99-363d-4453-8077-ca8bdc6d35bf","condition":null,"arrows":"to"},{"id":"21c2c69d-0050-4eca-8283-5a2bcbdc6c37","from":"52289e99-363d-4453-8077-ca8bdc6d35bf","to":"16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2","condition":null,"arrows":"to"},{"id":"19f2f329-8163-4dc6-a353-800df79d18a6","from":"a1a38c2e-0e05-4c68-bd49-f12aea070876","to":"52289e99-363d-4453-8077-ca8bdc6d35bf","condition":null,"arrows":"to"}]} [your flow id] next execute time:2022/08/09 18:24:00 [I]2022/08/09 18:24:00.027 [your flow id][cef59351-e2b5-4e81-b85a-5c751e35d8c4] ThreadPoolTaskScheduler-1:json: {"flowId":"your flow id","nodes":[{"id":"1","label":"start","readyCheck":0,"startType":3,"startCron":"0 0/1 * * * ?"},{"id":"a1a38c2e-0e05-4c68-bd49-f12aea070876","label":"查询用户信息","readyCheck":0,"startType":0,"startCron":null},{"id":"1a90a997-4390-470a-ae7c-626a725438d2","label":"查询酒店信息","readyCheck":0,"startType":0,"startCron":null},{"id":"52289e99-363d-4453-8077-ca8bdc6d35bf","label":"下单","readyCheck":0,"startType":0,"startCron":null},{"id":"16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2","label":"下单成功","readyCheck":0,"startType":0,"startCron":null}],"edges":[{"id":"1","from":"1","to":"2","condition":null,"arrows":"to"},{"id":"b3ad7ab3-8fb6-4527-8cae-6845e03da3e4","from":"1","to":"a1a38c2e-0e05-4c68-bd49-f12aea070876","condition":null,"arrows":"to"},{"id":"001375c7-19e7-436b-bbcd-68e36c8f23b7","from":"1","to":"1a90a997-4390-470a-ae7c-626a725438d2","condition":null,"arrows":"to"},{"id":"dd830043-c7a7-4c71-b91c-10c007b7b19c","from":"1a90a997-4390-470a-ae7c-626a725438d2","to":"52289e99-363d-4453-8077-ca8bdc6d35bf","condition":null,"arrows":"to"},{"id":"21c2c69d-0050-4eca-8283-5a2bcbdc6c37","from":"52289e99-363d-4453-8077-ca8bdc6d35bf","to":"16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2","condition":null,"arrows":"to"},{"id":"19f2f329-8163-4dc6-a353-800df79d18a6","from":"a1a38c2e-0e05-4c68-bd49-f12aea070876","to":"52289e99-363d-4453-8077-ca8bdc6d35bf","condition":null,"arrows":"to"}]} [I]2022/08/09 18:24:00.032 [your flow id][cef59351-e2b5-4e81-b85a-5c751e35d8c4] pool-1-thread-1:execute node id:1 [I]2022/08/09 18:24:00.032 [your flow id][cef59351-e2b5-4e81-b85a-5c751e35d8c4] pool-1-thread-1:execute node name:start 启动开始 (模拟业务等待3秒) 启动结束 [I]2022/08/09 18:24:03.055 [your flow id][cef59351-e2b5-4e81-b85a-5c751e35d8c4] pool-1-thread-1:execute node id:a1a38c2e-0e05-4c68-bd49-f12aea070876 [I]2022/08/09 18:24:03.055 [your flow id][cef59351-e2b5-4e81-b85a-5c751e35d8c4] pool-1-thread-1:execute node name:查询用户信息 [I]2022/08/09 18:24:03.055 [your flow id][cef59351-e2b5-4e81-b85a-5c751e35d8c4] pool-1-thread-2:execute node id:1a90a997-4390-470a-ae7c-626a725438d2 查询用户信息开始 (模拟业务等待3秒) [I]2022/08/09 18:24:03.055 [your flow id][cef59351-e2b5-4e81-b85a-5c751e35d8c4] pool-1-thread-2:execute node name:查询酒店信息 查询酒店信息开始 (模拟业务等待3秒) 查询用户信息结束 查询酒店信息结束 [I]2022/08/09 18:24:06.071 [your flow id][cef59351-e2b5-4e81-b85a-5c751e35d8c4] pool-1-thread-2:execute node id:52289e99-363d-4453-8077-ca8bdc6d35bf [I]2022/08/09 18:24:06.071 [your flow id][cef59351-e2b5-4e81-b85a-5c751e35d8c4] pool-1-thread-2:execute node name:下单 下单开始 (模拟业务等待3秒) 下单结束 [I]2022/08/09 18:24:09.074 [your flow id][cef59351-e2b5-4e81-b85a-5c751e35d8c4] pool-1-thread-2:execute node id:16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2 [I]2022/08/09 18:24:09.074 [your flow id][cef59351-e2b5-4e81-b85a-5c751e35d8c4] pool-1-thread-2:execute node name:下单成功 下单成功开始 (模拟业务等待3秒) 下单成功结束 [I]2022/08/09 18:24:12.083 [your flow id][cef59351-e2b5-4e81-b85a-5c751e35d8c4] Thread-1:Complete success. [I]2022/08/09 18:24:12.087 [your flow id][cef59351-e2b5-4e81-b85a-5c751e35d8c4] Thread-1:json: {"nodes":[{"id": "1","label": "start" ,"color": "#36AE7C"},{"id": "a1a38c2e-0e05-4c68-bd49-f12aea070876","label": "查询用户信息" ,"color": "#36AE7C"},{"id": "1a90a997-4390-470a-ae7c-626a725438d2","label": "查询酒店信息" ,"color": "#36AE7C"},{"id": "52289e99-363d-4453-8077-ca8bdc6d35bf","label": "下单" ,"color": "#36AE7C"},{"id": "16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2","label": "下单成功" ,"color": "#36AE7C"}],"edges":[{"id": "1","from": "1","to": "2","arrows": "to"},{"id": "b3ad7ab3-8fb6-4527-8cae-6845e03da3e4","from": "1","to": "a1a38c2e-0e05-4c68-bd49-f12aea070876","arrows": "to"},{"id": "001375c7-19e7-436b-bbcd-68e36c8f23b7","from": "1","to": "1a90a997-4390-470a-ae7c-626a725438d2","arrows": "to"},{"id": "dd830043-c7a7-4c71-b91c-10c007b7b19c","from": "1a90a997-4390-470a-ae7c-626a725438d2","to": "52289e99-363d-4453-8077-ca8bdc6d35bf","arrows": "to"},{"id": "21c2c69d-0050-4eca-8283-5a2bcbdc6c37","from": "52289e99-363d-4453-8077-ca8bdc6d35bf","to": "16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2","arrows": "to"},{"id": "19f2f329-8163-4dc6-a353-800df79d18a6","from": "a1a38c2e-0e05-4c68-bd49-f12aea070876","to": "52289e99-363d-4453-8077-ca8bdc6d35bf","arrows": "to"}]}
ladybugflow采用spring的scheduling来实现对cron表达式的解析,
流程启动后,如果首节点类型是Timer,则会根据cron表达式来向ThreadPoolTaskScheduler中注册一个定时任务。
taskScheduler.schedule(new Runnable() { @Override public void run() { try { FlowRunner flowRunnerNew = flowRunner.getClass().newInstance(); String flowPath = flowRunnerNew.getClass().getName(); if (StringUtil.isNotEmpty(jsonFileName)) { flowPath = jsonFileName.replace(".json", ""); } FlowEntity flow = createHistory(flowPath); String flowId = flow.flowEntity.getFlowId(); String historyId = flow.flowEntity.getHistoryId(); FlowContainer.flowRunnerMap.put(flowId + "," + historyId, flowRunnerNew); HistoryNodeEntity firstNode = FlowContainer.selectNodeByKey(flowId, nodeId, historyId); firstNode.setNodeStatus(NodeStatus.READY); startNode(flowId, historyId, nodeId); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } }, new CronTrigger(cron));
1.新建一个Spring-Batch工程,并且导入ladybugflow。
build.gradle
plugins { id 'org.springframework.boot' version '2.7.2' id 'io.spring.dependency-management' version '1.0.12.RELEASE' id 'java' } group = 'nobuglady' version = '0.0.1-SNAPSHOT' sourceCompatibility = '1.8' repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-batch' implementation 'io.github.nobuglady:ladybugflow:0.0.8' testImplementation 'org.springframework.boot:spring-boot-starter-test' } tasks.named('test') { useJUnitPlatform() }
将生成的Json文件和对应的Flow.java文件放在同一个目录下:
Flow1.java
package io.github.nobuglady.network.demo.batch.ladybugflow; import org.springframework.stereotype.Component; import io.github.nobuglady.network.fw.FlowRunner; import io.github.nobuglady.network.fw.annotation.Node; /** * * @author NoBugLady * */ @Component public class Flow1 extends FlowRunner { private String result; public String getResult() { return result; } @Node(label = "start") public void processStart() throws InterruptedException { System.out.println("启动开始 (模拟业务等待3秒)"); Thread.sleep(3000); System.out.println("启动结束"); } @Node(label = "查询用户信息") public void processSearchUser() throws InterruptedException { System.out.println("查询用户信息开始 (模拟业务等待3秒)"); Thread.sleep(3000); System.out.println("查询用户信息结束"); } @Node(label = "查询酒店信息") public void processSearchHotel() throws InterruptedException { System.out.println("查询酒店信息开始 (模拟业务等待3秒)"); Thread.sleep(3000); System.out.println("查询酒店信息结束"); } @Node(label = "下单") public void processOrder() throws InterruptedException { System.out.println("下单开始 (模拟业务等待3秒)"); Thread.sleep(3000); System.out.println("下单结束"); } @Node(label = "下单成功") public void processSuccess() throws InterruptedException { System.out.println("下单成功开始 (模拟业务等待3秒)"); Thread.sleep(3000); System.out.println("下单成功结束"); result = "success"; } }
Flow1.json
{ "flowId": "your flow id", "nodes": [ { "id": "1", "label": "start", "readyCheck": 0, "startType": 3, "startCron": "0 0/1 * * * ?" }, { "id": "a1a38c2e-0e05-4c68-bd49-f12aea070876", "label": "查询用户信息", "readyCheck": 0 }, { "id": "1a90a997-4390-470a-ae7c-626a725438d2", "label": "查询酒店信息", "readyCheck": 0 }, { "id": "52289e99-363d-4453-8077-ca8bdc6d35bf", "label": "下单", "readyCheck": 0 }, { "id": "16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2", "label": "下单成功", "readyCheck": 0 } ], "edges": [ { "id": "1", "from": "1", "to": "2", "arrows": "to" }, { "id": "b3ad7ab3-8fb6-4527-8cae-6845e03da3e4", "from": "1", "to": "a1a38c2e-0e05-4c68-bd49-f12aea070876", "arrows": "to" }, { "id": "001375c7-19e7-436b-bbcd-68e36c8f23b7", "from": "1", "to": "1a90a997-4390-470a-ae7c-626a725438d2", "arrows": "to" }, { "id": "dd830043-c7a7-4c71-b91c-10c007b7b19c", "from": "1a90a997-4390-470a-ae7c-626a725438d2", "to": "52289e99-363d-4453-8077-ca8bdc6d35bf", "arrows": "to" }, { "id": "21c2c69d-0050-4eca-8283-5a2bcbdc6c37", "from": "52289e99-363d-4453-8077-ca8bdc6d35bf", "to": "16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2", "arrows": "to" }, { "id": "19f2f329-8163-4dc6-a353-800df79d18a6", "from": "a1a38c2e-0e05-4c68-bd49-f12aea070876", "to": "52289e99-363d-4453-8077-ca8bdc6d35bf", "arrows": "to" } ] }
在启动的类中启动流程
LadybugflowDemoBatchApplication.java
package io.github.nobuglady.network.demo.batch; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import io.github.nobuglady.network.demo.batch.ladybugflow.Flow1; @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) public class LadybugflowDemoBatchApplication implements ApplicationRunner { @Autowired private Flow1 flow1; public static void main(String[] args) { SpringApplication.run(LadybugflowDemoBatchApplication.class, args); } @Override public void run(ApplicationArguments args) throws Exception { flow1.startFlow(true); System.out.println(flow1.getResult()); } }
运行结果:
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.7.2) 2022-08-09 18:21:04.166 INFO 3208 --- [ main] .n.n.d.b.LadybugflowDemoBatchApplication : No active profile set, falling back to 1 default profile: "default" 2022-08-09 18:21:04.769 INFO 3208 --- [ main] .n.n.d.b.LadybugflowDemoBatchApplication : Started LadybugflowDemoBatchApplication in 0.907 seconds (JVM running for 1.78) [I]2022/08/09 18:21:04.772 main:ladybugflow.properties in root path not found, use default configuration [I]2022/08/09 18:21:04.773 main:NodePool started. [I]2022/08/09 18:21:04.774 main:Ready queue consumer thread started. [I]2022/08/09 18:21:04.779 main:Complete queue consumer thread started. [I]2022/08/09 18:21:04.961 [your flow id][a31bb47d-be78-491d-9ecd-7d59302b565a] main:json: {"flowId":"your flow id","nodes":[{"id":"1","label":"start","readyCheck":0,"startType":3,"startCron":"0 0/1 * * * ?"},{"id":"a1a38c2e-0e05-4c68-bd49-f12aea070876","label":"查询用户信息","readyCheck":0,"startType":0,"startCron":null},{"id":"1a90a997-4390-470a-ae7c-626a725438d2","label":"查询酒店信息","readyCheck":0,"startType":0,"startCron":null},{"id":"52289e99-363d-4453-8077-ca8bdc6d35bf","label":"下单","readyCheck":0,"startType":0,"startCron":null},{"id":"16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2","label":"下单成功","readyCheck":0,"startType":0,"startCron":null}],"edges":[{"id":"1","from":"1","to":"2","condition":null,"arrows":"to"},{"id":"b3ad7ab3-8fb6-4527-8cae-6845e03da3e4","from":"1","to":"a1a38c2e-0e05-4c68-bd49-f12aea070876","condition":null,"arrows":"to"},{"id":"001375c7-19e7-436b-bbcd-68e36c8f23b7","from":"1","to":"1a90a997-4390-470a-ae7c-626a725438d2","condition":null,"arrows":"to"},{"id":"dd830043-c7a7-4c71-b91c-10c007b7b19c","from":"1a90a997-4390-470a-ae7c-626a725438d2","to":"52289e99-363d-4453-8077-ca8bdc6d35bf","condition":null,"arrows":"to"},{"id":"21c2c69d-0050-4eca-8283-5a2bcbdc6c37","from":"52289e99-363d-4453-8077-ca8bdc6d35bf","to":"16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2","condition":null,"arrows":"to"},{"id":"19f2f329-8163-4dc6-a353-800df79d18a6","from":"a1a38c2e-0e05-4c68-bd49-f12aea070876","to":"52289e99-363d-4453-8077-ca8bdc6d35bf","condition":null,"arrows":"to"}]} [your flow id] next execute time:2022/08/09 18:22:00 [I]2022/08/09 18:22:00.020 [your flow id][d343ba1a-a367-4f63-aaa4-32b1d31b5edb] ThreadPoolTaskScheduler-1:json: {"flowId":"your flow id","nodes":[{"id":"1","label":"start","readyCheck":0,"startType":3,"startCron":"0 0/1 * * * ?"},{"id":"a1a38c2e-0e05-4c68-bd49-f12aea070876","label":"查询用户信息","readyCheck":0,"startType":0,"startCron":null},{"id":"1a90a997-4390-470a-ae7c-626a725438d2","label":"查询酒店信息","readyCheck":0,"startType":0,"startCron":null},{"id":"52289e99-363d-4453-8077-ca8bdc6d35bf","label":"下单","readyCheck":0,"startType":0,"startCron":null},{"id":"16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2","label":"下单成功","readyCheck":0,"startType":0,"startCron":null}],"edges":[{"id":"1","from":"1","to":"2","condition":null,"arrows":"to"},{"id":"b3ad7ab3-8fb6-4527-8cae-6845e03da3e4","from":"1","to":"a1a38c2e-0e05-4c68-bd49-f12aea070876","condition":null,"arrows":"to"},{"id":"001375c7-19e7-436b-bbcd-68e36c8f23b7","from":"1","to":"1a90a997-4390-470a-ae7c-626a725438d2","condition":null,"arrows":"to"},{"id":"dd830043-c7a7-4c71-b91c-10c007b7b19c","from":"1a90a997-4390-470a-ae7c-626a725438d2","to":"52289e99-363d-4453-8077-ca8bdc6d35bf","condition":null,"arrows":"to"},{"id":"21c2c69d-0050-4eca-8283-5a2bcbdc6c37","from":"52289e99-363d-4453-8077-ca8bdc6d35bf","to":"16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2","condition":null,"arrows":"to"},{"id":"19f2f329-8163-4dc6-a353-800df79d18a6","from":"a1a38c2e-0e05-4c68-bd49-f12aea070876","to":"52289e99-363d-4453-8077-ca8bdc6d35bf","condition":null,"arrows":"to"}]} [I]2022/08/09 18:22:00.023 [your flow id][d343ba1a-a367-4f63-aaa4-32b1d31b5edb] pool-1-thread-1:execute node id:1 [I]2022/08/09 18:22:00.024 [your flow id][d343ba1a-a367-4f63-aaa4-32b1d31b5edb] pool-1-thread-1:execute node name:start 启动开始 (模拟业务等待3秒) 启动结束 [I]2022/08/09 18:22:03.028 [your flow id][d343ba1a-a367-4f63-aaa4-32b1d31b5edb] pool-1-thread-1:execute node id:a1a38c2e-0e05-4c68-bd49-f12aea070876 [I]2022/08/09 18:22:03.028 [your flow id][d343ba1a-a367-4f63-aaa4-32b1d31b5edb] pool-1-thread-1:execute node name:查询用户信息 查询用户信息开始 (模拟业务等待3秒) [I]2022/08/09 18:22:03.028 [your flow id][d343ba1a-a367-4f63-aaa4-32b1d31b5edb] pool-1-thread-2:execute node id:1a90a997-4390-470a-ae7c-626a725438d2 [I]2022/08/09 18:22:03.028 [your flow id][d343ba1a-a367-4f63-aaa4-32b1d31b5edb] pool-1-thread-2:execute node name:查询酒店信息 查询酒店信息开始 (模拟业务等待3秒) 查询酒店信息结束 查询用户信息结束 [I]2022/08/09 18:22:06.034 [your flow id][d343ba1a-a367-4f63-aaa4-32b1d31b5edb] pool-1-thread-1:execute node id:52289e99-363d-4453-8077-ca8bdc6d35bf [I]2022/08/09 18:22:06.034 [your flow id][d343ba1a-a367-4f63-aaa4-32b1d31b5edb] pool-1-thread-1:execute node name:下单 下单开始 (模拟业务等待3秒) 下单结束 [I]2022/08/09 18:22:09.043 [your flow id][d343ba1a-a367-4f63-aaa4-32b1d31b5edb] pool-1-thread-1:execute node id:16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2 [I]2022/08/09 18:22:09.044 [your flow id][d343ba1a-a367-4f63-aaa4-32b1d31b5edb] pool-1-thread-1:execute node name:下单成功 下单成功开始 (模拟业务等待3秒) 下单成功结束 [I]2022/08/09 18:22:12.053 [your flow id][d343ba1a-a367-4f63-aaa4-32b1d31b5edb] Thread-4:Complete success. [I]2022/08/09 18:22:12.055 [your flow id][d343ba1a-a367-4f63-aaa4-32b1d31b5edb] Thread-4:json: {"nodes":[{"id": "1","label": "start" ,"color": "#36AE7C"},{"id": "a1a38c2e-0e05-4c68-bd49-f12aea070876","label": "查询用户信息" ,"color": "#36AE7C"},{"id": "1a90a997-4390-470a-ae7c-626a725438d2","label": "查询酒店信息" ,"color": "#36AE7C"},{"id": "52289e99-363d-4453-8077-ca8bdc6d35bf","label": "下单" ,"color": "#36AE7C"},{"id": "16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2","label": "下单成功" ,"color": "#36AE7C"}],"edges":[{"id": "1","from": "1","to": "2","arrows": "to"},{"id": "b3ad7ab3-8fb6-4527-8cae-6845e03da3e4","from": "1","to": "a1a38c2e-0e05-4c68-bd49-f12aea070876","arrows": "to"},{"id": "001375c7-19e7-436b-bbcd-68e36c8f23b7","from": "1","to": "1a90a997-4390-470a-ae7c-626a725438d2","arrows": "to"},{"id": "dd830043-c7a7-4c71-b91c-10c007b7b19c","from": "1a90a997-4390-470a-ae7c-626a725438d2","to": "52289e99-363d-4453-8077-ca8bdc6d35bf","arrows": "to"},{"id": "21c2c69d-0050-4eca-8283-5a2bcbdc6c37","from": "52289e99-363d-4453-8077-ca8bdc6d35bf","to": "16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2","arrows": "to"},{"id": "19f2f329-8163-4dc6-a353-800df79d18a6","from": "a1a38c2e-0e05-4c68-bd49-f12aea070876","to": "52289e99-363d-4453-8077-ca8bdc6d35bf","arrows": "to"}]}
感谢您阅读到这里。
源码: GitHub - nobuglady/ladybugflow
本章实例源码: ladybugflow-demo/ladybugflow-demo-batch at main · nobuglady/ladybugflow-demo · GitHub