基於LadybugFlow的微服務編排(1.SpringBoot整合)

2022-08-04 15:01:29

前言

前面的系列文章裡,介紹了ladybugflow的業務視覺化的設計以及常見場景的使用方法。

感謝大家對專案的關注。

本篇文章介紹一下基於ladybugflow的微服務編排場景及使用方法。

1. 業務場景

上一篇文章使用同樣的酒店預定業務場景,本篇文章我們將它繼承到SpringBoot中。

如下圖所示:

不同的是,這裡我們將【查詢使用者資訊】和【查詢酒店資訊】業務作為遠端微服務呼叫,專案架構如下圖所示:

  • 查詢酒店資訊節點呼叫遠端微服務App2的查詢酒店資訊介面
  • 查詢使用者資訊節點呼叫遠端微服務App3的查詢使用者資訊介面
  • 在下單節點中將使用者資訊和酒店資訊輸出到紀錄檔中。

2. 與SpringBoot的整合

接下來我們將微服務App1,App2,App3做成3個SpringBoot工程。

App2:酒店資訊查詢微服務

我們建立一個SpringBoot專案,新增如下介面:

http://localhost:8082/getHotel?hotel_id=XXX

@Controller
public class HotelInfoController {

	@RequestMapping(method = RequestMethod.GET, value = "/getHotel")
	@ResponseBody
	public String getHotelInfo(@RequestParam("hotel_id") int hotelId) {
		return "HOTEL:"+hotelId;
	}
}

 

App3:使用者資訊查詢微服務

我們建立一個SpringBoot專案,新增如下介面:

http://localhost:8083/getUser?user_id=XXX

@Controller
public class UserInfoController {

	@RequestMapping(method = RequestMethod.GET, value = "/getUser")
	@ResponseBody
	public String getUserInfo(@RequestParam("user_id") int userId) {
		return "USER:"+userId;
	}
}

 

App1:酒店預定微服務

我們建立一個SpringBoot專案,工程結構如下:

加入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()
}

ext {
	set('springCloudVersion', "2021.0.3")
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-web'
	implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
	implementation 'io.github.nobuglady:ladybugflow:0.0.6'
}

dependencyManagement {
	imports {
		mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
	}
}

tasks.named('test') {
	useJUnitPlatform()
}

然後分別實現酒店預定的Controler,Service和Flow層程式碼,如下:

LadybugflowDemoMicroservice1Application.java

@SpringBootApplication
@EnableFeignClients
public class LadybugflowDemoMicroservice1Application {

	public static void main(String[] args) {
		SpringApplication.run(LadybugflowDemoMicroservice1Application.class, args);
	}

	@PreDestroy
	public void onExit() {
		FlowStarter.shutdown();
	}
}

 

BookHotelController.java

@Controller
public class BookHotelController {

	@Autowired
	private BookHotelService bookHotelService;
	
	@RequestMapping(value = "/book_hotel", method = RequestMethod.GET)
	@ResponseBody
	public String bookHotel() {
		
		bookHotelService.bookHotel();
		
		return "ok";
	}
}

 

BookHotelService.java

@Service
public class BookHotelService {

	@Autowired
	private BookHotelFlow bookHotelFlow;
	
	public void bookHotel() {
		bookHotelFlow.startFlow(false);
	}

}

 

BookHotelFlow.java


@Component
public class BookHotelFlow extends FlowRunner{
	
	@Autowired
	private HotelInfoNode hotelInfoNode;
	
	@Autowired 
	private UserInfoNode userInfoNode;
	
	private String userInfo;
	private String hotelInfo;
	
	@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秒)");
		userInfo = userInfoNode.getUser(456);
		System.out.println("查詢使用者資訊結束");
	}

	@Node(label = "查詢酒店資訊")
	public void processSearchHotel() throws InterruptedException {
		System.out.println("查詢酒店資訊開始 (模擬業務等待3秒)");
		hotelInfo = hotelInfoNode.getHotel(123);
		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("下單成功結束");

        System.out.println("userInfo:"+userInfo);
        System.out.println("hotelInfo:"+hotelInfo);
	}
}

 

BookHotelFlow.json

{
	"flowId": "your flow id",
	"nodes": [
		{
			"id": "1",
			"label": "start"
		},
		{
			"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"
		}
	]
}

 

HotelInfoNode.java

@FeignClient(name = "hotelInfo", url = "localhost:8082")
public interface HotelInfoNode {
	@RequestMapping(method = RequestMethod.GET, value = "/getHotel")
	public String getHotel(@RequestParam("hotel_id") int hotelId);

}

 

UserInfoNode.java

@FeignClient(name = "userInfo", url = "localhost:8083")
public interface UserInfoNode {
	
	@RequestMapping(method = RequestMethod.GET, value = "/getUser")
	public String getUser(@RequestParam("user_id") int userId);
}

 

3. 執行

啟動微服務App1,App2,App3,

然後再瀏覽器輸入 http://localhost:8080/book_hotel

可以看到正常結束紀錄檔

.   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.7.2)

2022-08-03 19:31:54.203  INFO 17856 --- [           main] .LadybugflowDemoMicroservice1Application : No active profile set, falling back to 1 default profile: "default"
2022-08-03 19:31:54.854  INFO 17856 --- [           main] o.s.cloud.context.scope.GenericScope     : BeanFactory id=c8301046-975c-3f5d-a827-434b9d12c7f5
2022-08-03 19:31:55.145  INFO 17856 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2022-08-03 19:31:55.155  INFO 17856 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2022-08-03 19:31:55.155  INFO 17856 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.65]
2022-08-03 19:31:55.313  INFO 17856 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2022-08-03 19:31:55.314  INFO 17856 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1069 ms
2022-08-03 19:31:56.432  INFO 17856 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2022-08-03 19:31:56.982  INFO 17856 --- [           main] .LadybugflowDemoMicroservice1Application : Started LadybugflowDemoMicroservice1Application in 3.676 seconds (JVM running for 4.615)
2022-08-03 19:32:02.853  INFO 17856 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2022-08-03 19:32:02.853  INFO 17856 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2022-08-03 19:32:02.854  INFO 17856 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
[I]2022/08/03 19:32:02.877  http-nio-8080-exec-1:ladybugflow.properties in root path not found, use default configuration
[I]2022/08/03 19:32:02.879  http-nio-8080-exec-1:NodePool started.
[I]2022/08/03 19:32:02.880  http-nio-8080-exec-1:Ready queue consumer thread started.
[I]2022/08/03 19:32:02.881  http-nio-8080-exec-1:Complete queue consumer thread started.
[I]2022/08/03 19:32:02.962 [your flow id][ae83277a-e7db-4787-9826-cfb44512a020] http-nio-8080-exec-1:json:
{"flowId":"your flow id","nodes":[{"id":"1","label":"start","readyCheck":0},{"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","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/03 19:32:02.964 [your flow id][ae83277a-e7db-4787-9826-cfb44512a020] pool-1-thread-1:execute node id:1
[I]2022/08/03 19:32:02.964 [your flow id][ae83277a-e7db-4787-9826-cfb44512a020] pool-1-thread-1:execute node name:start
啟動開始 (模擬業務等待3秒)
啟動結束
[I]2022/08/03 19:32:05.980 [your flow id][ae83277a-e7db-4787-9826-cfb44512a020] pool-1-thread-1:execute node id:a1a38c2e-0e05-4c68-bd49-f12aea070876
[I]2022/08/03 19:32:05.980 [your flow id][ae83277a-e7db-4787-9826-cfb44512a020] pool-1-thread-1:execute node name:查詢使用者資訊
查詢使用者資訊開始 (模擬業務等待3秒)
[I]2022/08/03 19:32:05.980 [your flow id][ae83277a-e7db-4787-9826-cfb44512a020] pool-1-thread-2:execute node id:1a90a997-4390-470a-ae7c-626a725438d2
[I]2022/08/03 19:32:05.981 [your flow id][ae83277a-e7db-4787-9826-cfb44512a020] pool-1-thread-2:execute node name:查詢酒店資訊
查詢酒店資訊開始 (模擬業務等待3秒)
查詢酒店資訊結束
查詢使用者資訊結束
[I]2022/08/03 19:32:06.109 [your flow id][ae83277a-e7db-4787-9826-cfb44512a020] pool-1-thread-1:execute node id:52289e99-363d-4453-8077-ca8bdc6d35bf
[I]2022/08/03 19:32:06.109 [your flow id][ae83277a-e7db-4787-9826-cfb44512a020] pool-1-thread-1:execute node name:下單
下單開始 (模擬業務等待3秒)
下單結束
[I]2022/08/03 19:32:09.118 [your flow id][ae83277a-e7db-4787-9826-cfb44512a020] pool-1-thread-1:execute node id:16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2
[I]2022/08/03 19:32:09.118 [your flow id][ae83277a-e7db-4787-9826-cfb44512a020] pool-1-thread-1:execute node name:下單成功
下單成功開始 (模擬業務等待3秒)
下單成功結束
userInfo:USER:456
hotelInfo:HOTEL:123
[I]2022/08/03 19:32:12.132 [your flow id][ae83277a-e7db-4787-9826-cfb44512a020] Thread-6:Complete success.
[I]2022/08/03 19:32:12.133 [your flow id][ae83277a-e7db-4787-9826-cfb44512a020] Thread-6: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"}]}

我們將紀錄檔中的結束節點json複製到視覺化工具中

 

4. 業務流程變更

ladybugflow的優點是將業務流程與業務程式碼分開管理,從而可以輕鬆的應對業務流程變更而不需要修改程式碼。

比如將業務流程修改為如下圖所示的序列執行的時候

步驟1:將json檔案拷貝到視覺化工具中,生成流程圖

步驟2:修改流程圖

步驟3:更新json

步驟4:將更新後的json替換到工程中

{
	"flowId": "your flow id",
	"nodes": [
		{
			"id": "1",
			"label": "start"
		},
		{
			"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": "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": "a1a38c2e-0e05-4c68-bd49-f12aea070876",
			"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"
		}
	]
}

執行結果:

[I]2022/08/03 19:40:30.625 [your flow id][f15f25c8-7bfd-4df8-8c74-9b5f2c5c9257] http-nio-8080-exec-4:json:
{"flowId":"your flow id","nodes":[{"id":"1","label":"start","readyCheck":0},{"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","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":"a1a38c2e-0e05-4c68-bd49-f12aea070876","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/03 19:40:30.626 [your flow id][f15f25c8-7bfd-4df8-8c74-9b5f2c5c9257] pool-1-thread-3:execute node id:1
[I]2022/08/03 19:40:30.626 [your flow id][f15f25c8-7bfd-4df8-8c74-9b5f2c5c9257] pool-1-thread-3:execute node name:start
啟動開始 (模擬業務等待3秒)
啟動結束
[I]2022/08/03 19:40:33.640 [your flow id][f15f25c8-7bfd-4df8-8c74-9b5f2c5c9257] pool-1-thread-3:execute node id:1a90a997-4390-470a-ae7c-626a725438d2
[I]2022/08/03 19:40:33.640 [your flow id][f15f25c8-7bfd-4df8-8c74-9b5f2c5c9257] pool-1-thread-3:execute node name:查詢酒店資訊
查詢酒店資訊開始 (模擬業務等待3秒)
查詢酒店資訊結束
[I]2022/08/03 19:40:33.647 [your flow id][f15f25c8-7bfd-4df8-8c74-9b5f2c5c9257] pool-1-thread-3:execute node id:a1a38c2e-0e05-4c68-bd49-f12aea070876
[I]2022/08/03 19:40:33.647 [your flow id][f15f25c8-7bfd-4df8-8c74-9b5f2c5c9257] pool-1-thread-3:execute node name:查詢使用者資訊
查詢使用者資訊開始 (模擬業務等待3秒)
查詢使用者資訊結束
[I]2022/08/03 19:40:33.651 [your flow id][f15f25c8-7bfd-4df8-8c74-9b5f2c5c9257] pool-1-thread-3:execute node id:52289e99-363d-4453-8077-ca8bdc6d35bf
[I]2022/08/03 19:40:33.651 [your flow id][f15f25c8-7bfd-4df8-8c74-9b5f2c5c9257] pool-1-thread-3:execute node name:下單
下單開始 (模擬業務等待3秒)
下單結束
[I]2022/08/03 19:40:36.662 [your flow id][f15f25c8-7bfd-4df8-8c74-9b5f2c5c9257] pool-1-thread-3:execute node id:16422cbb-ccb0-4fe2-952b-e3ad5c3acbb2
[I]2022/08/03 19:40:36.662 [your flow id][f15f25c8-7bfd-4df8-8c74-9b5f2c5c9257] pool-1-thread-3:execute node name:下單成功
下單成功開始 (模擬業務等待3秒)
下單成功結束
userInfo:USER:456
hotelInfo:HOTEL:123
[I]2022/08/03 19:40:39.676 [your flow id][f15f25c8-7bfd-4df8-8c74-9b5f2c5c9257] Thread-6:Complete success.
[I]2022/08/03 19:40:39.676 [your flow id][f15f25c8-7bfd-4df8-8c74-9b5f2c5c9257] Thread-6: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": "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": "a1a38c2e-0e05-4c68-bd49-f12aea070876","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"}]}

 

感謝您讀文章到這裡。

3. 最後

原始碼:https://github.com/nobuglady/ladybugflow

執行例原始碼:https://github.com/nobuglady/ladybugflow-demo-microservice

設計資料和詳細的使用方法可以參照上一篇文章:https://www.cnblogs.com/nobuglady/p/16474433.html