├── README.md ├── src └── main │ ├── resources │ ├── application.properties │ └── config │ │ └── flow.el.xml │ └── java │ └── com │ └── example │ └── demo │ ├── MessageDemoApplication.java │ ├── cmp │ ├── Biz1Cmp.java │ ├── PackageDataCmp.java │ ├── Channel1Cmp.java │ ├── Channel2Cmp.java │ ├── Channel3Cmp.java │ ├── Channel4Cmp.java │ ├── Channel5Cmp.java │ ├── Channel6Cmp.java │ ├── IF2SwitchCmp.java │ ├── IF3SwitchCmp.java │ ├── IF1SwitchCmp.java │ ├── Channel1QueryCmp.java │ ├── Channel2QueryCmp.java │ ├── Channel3QueryCmp.java │ ├── Channel4QueryCmp.java │ ├── Channel5QueryCmp.java │ ├── Channel6QueryCmp.java │ ├── BatchSenderCmp.java │ └── ChannelSelectorCmp.java │ ├── vo │ └── QueryVO.java │ ├── context │ └── BatchMessageResultContext.java │ └── ChainExecute.java ├── .gitignore ├── pom.xml └── images └── 1.svg /README.md: -------------------------------------------------------------------------------- 1 | ![](images/1.svg) -------------------------------------------------------------------------------- /src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | liteflow.rule-source=config/flow.el.xml 2 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/MessageDemoApplication.java: -------------------------------------------------------------------------------- 1 | package com.example.demo; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class MessageDemoApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(MessageDemoApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/cmp/Biz1Cmp.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.cmp; 2 | 3 | import com.yomahub.liteflow.annotation.LiteflowComponent; 4 | import com.yomahub.liteflow.core.NodeComponent; 5 | 6 | import java.util.Random; 7 | 8 | @LiteflowComponent(id = "biz1", name = "获取业务动态值") 9 | public class Biz1Cmp extends NodeComponent { 10 | @Override 11 | public void process() throws Exception { 12 | //模拟业务耗时 13 | int time = new Random().nextInt(1500); 14 | Thread.sleep(time); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/cmp/PackageDataCmp.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.cmp; 2 | 3 | import com.yomahub.liteflow.annotation.LiteflowComponent; 4 | import com.yomahub.liteflow.core.NodeComponent; 5 | 6 | import java.util.Random; 7 | 8 | @LiteflowComponent(id = "packageData", name = "组装数据") 9 | public class PackageDataCmp extends NodeComponent { 10 | @Override 11 | public void process() throws Exception { 12 | //模拟业务耗时 13 | int time = new Random().nextInt(1500); 14 | Thread.sleep(time); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/cmp/Channel1Cmp.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.cmp; 2 | 3 | import com.example.demo.context.BatchMessageResultContext; 4 | import com.yomahub.liteflow.annotation.LiteflowComponent; 5 | import com.yomahub.liteflow.core.NodeComponent; 6 | 7 | @LiteflowComponent(id = "channel1", name = "返回渠道1") 8 | public class Channel1Cmp extends NodeComponent { 9 | @Override 10 | public void process() throws Exception { 11 | BatchMessageResultContext context = this.getFirstContextBean(); 12 | context.setFinalResultChannel("channel1"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/cmp/Channel2Cmp.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.cmp; 2 | 3 | import com.example.demo.context.BatchMessageResultContext; 4 | import com.yomahub.liteflow.annotation.LiteflowComponent; 5 | import com.yomahub.liteflow.core.NodeComponent; 6 | 7 | @LiteflowComponent(id = "channel2", name = "返回渠道2") 8 | public class Channel2Cmp extends NodeComponent { 9 | @Override 10 | public void process() throws Exception { 11 | BatchMessageResultContext context = this.getFirstContextBean(); 12 | context.setFinalResultChannel("channel2"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/cmp/Channel3Cmp.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.cmp; 2 | 3 | import com.example.demo.context.BatchMessageResultContext; 4 | import com.yomahub.liteflow.annotation.LiteflowComponent; 5 | import com.yomahub.liteflow.core.NodeComponent; 6 | 7 | @LiteflowComponent(id = "channel3", name = "返回渠道3") 8 | public class Channel3Cmp extends NodeComponent { 9 | @Override 10 | public void process() throws Exception { 11 | BatchMessageResultContext context = this.getFirstContextBean(); 12 | context.setFinalResultChannel("channel3"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/cmp/Channel4Cmp.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.cmp; 2 | 3 | import com.example.demo.context.BatchMessageResultContext; 4 | import com.yomahub.liteflow.annotation.LiteflowComponent; 5 | import com.yomahub.liteflow.core.NodeComponent; 6 | 7 | @LiteflowComponent(id = "channel4", name = "返回渠道4") 8 | public class Channel4Cmp extends NodeComponent { 9 | @Override 10 | public void process() throws Exception { 11 | BatchMessageResultContext context = this.getFirstContextBean(); 12 | context.setFinalResultChannel("channel4"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/cmp/Channel5Cmp.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.cmp; 2 | 3 | import com.example.demo.context.BatchMessageResultContext; 4 | import com.yomahub.liteflow.annotation.LiteflowComponent; 5 | import com.yomahub.liteflow.core.NodeComponent; 6 | 7 | @LiteflowComponent(id = "channel5", name = "返回渠道5") 8 | public class Channel5Cmp extends NodeComponent { 9 | @Override 10 | public void process() throws Exception { 11 | BatchMessageResultContext context = this.getFirstContextBean(); 12 | context.setFinalResultChannel("channel5"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/cmp/Channel6Cmp.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.cmp; 2 | 3 | import com.example.demo.context.BatchMessageResultContext; 4 | import com.yomahub.liteflow.annotation.LiteflowComponent; 5 | import com.yomahub.liteflow.core.NodeComponent; 6 | 7 | @LiteflowComponent(id = "channel6", name = "返回渠道6") 8 | public class Channel6Cmp extends NodeComponent { 9 | @Override 10 | public void process() throws Exception { 11 | BatchMessageResultContext context = this.getFirstContextBean(); 12 | context.setFinalResultChannel("channel6"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/cmp/IF2SwitchCmp.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.cmp; 2 | 3 | import com.yomahub.liteflow.annotation.LiteflowComponent; 4 | import com.yomahub.liteflow.core.NodeSwitchComponent; 5 | 6 | import java.util.Random; 7 | 8 | @LiteflowComponent(id = "if_2", name = "业务判断2") 9 | public class IF2SwitchCmp extends NodeSwitchComponent { 10 | @Override 11 | public String processSwitch() throws Exception { 12 | //模拟业务耗时 13 | int time = new Random().nextInt(1000); 14 | Thread.sleep(time); 15 | 16 | //这里写死,你可以改成其他分支 17 | return "s3"; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/cmp/IF3SwitchCmp.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.cmp; 2 | 3 | import com.yomahub.liteflow.annotation.LiteflowComponent; 4 | import com.yomahub.liteflow.core.NodeSwitchComponent; 5 | 6 | import java.util.Random; 7 | 8 | @LiteflowComponent(id = "if_3", name = "业务判断3") 9 | public class IF3SwitchCmp extends NodeSwitchComponent { 10 | @Override 11 | public String processSwitch() throws Exception { 12 | //模拟业务耗时 13 | int time = new Random().nextInt(1000); 14 | Thread.sleep(time); 15 | 16 | //这里写死,你可以改成其他 17 | return "channel5"; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/cmp/IF1SwitchCmp.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.cmp; 2 | 3 | import com.yomahub.liteflow.annotation.LiteflowComponent; 4 | import com.yomahub.liteflow.core.NodeSwitchComponent; 5 | 6 | import java.util.Random; 7 | 8 | @LiteflowComponent(id = "if_1", name = "业务判断1") 9 | public class IF1SwitchCmp extends NodeSwitchComponent { 10 | @Override 11 | public String processSwitch() throws Exception { 12 | //模拟业务耗时 13 | int time = new Random().nextInt(1000); 14 | Thread.sleep(time); 15 | 16 | //这里写死跳到并行获取剩余量那条分支,你可以改成其他分支测试 17 | return "branch1"; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/vo/QueryVO.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.vo; 2 | 3 | public class QueryVO { 4 | 5 | //渠道名称 6 | private String channel; 7 | 8 | //剩余短信包数量 9 | private int availCount; 10 | 11 | public QueryVO(String channel, int availCount) { 12 | this.channel = channel; 13 | this.availCount = availCount; 14 | } 15 | 16 | public String getChannel() { 17 | return channel; 18 | } 19 | 20 | public void setChannel(String channel) { 21 | this.channel = channel; 22 | } 23 | 24 | public int getAvailCount() { 25 | return availCount; 26 | } 27 | 28 | public void setAvailCount(int availCount) { 29 | this.availCount = availCount; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/cmp/Channel1QueryCmp.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.cmp; 2 | 3 | import com.example.demo.context.BatchMessageResultContext; 4 | import com.example.demo.vo.QueryVO; 5 | import com.yomahub.liteflow.annotation.LiteflowComponent; 6 | import com.yomahub.liteflow.core.NodeComponent; 7 | 8 | import java.util.Random; 9 | 10 | @LiteflowComponent(id = "channel1Query", name = "获取渠道1剩余量") 11 | public class Channel1QueryCmp extends NodeComponent { 12 | @Override 13 | public void process() throws Exception { 14 | //模拟查询业务耗时 15 | int time = new Random().nextInt(1000); 16 | Thread.sleep(time); 17 | 18 | //mock下渠道1有2w条剩余量 19 | BatchMessageResultContext context = this.getFirstContextBean(); 20 | context.addQueryVO(new QueryVO("channel1", 20000)); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/cmp/Channel2QueryCmp.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.cmp; 2 | 3 | import com.example.demo.context.BatchMessageResultContext; 4 | import com.example.demo.vo.QueryVO; 5 | import com.yomahub.liteflow.annotation.LiteflowComponent; 6 | import com.yomahub.liteflow.core.NodeComponent; 7 | 8 | import java.util.Random; 9 | 10 | @LiteflowComponent(id = "channel2Query", name = "获取渠道2剩余量") 11 | public class Channel2QueryCmp extends NodeComponent { 12 | @Override 13 | public void process() throws Exception { 14 | //模拟查询业务耗时 15 | int time = new Random().nextInt(1000); 16 | Thread.sleep(time); 17 | 18 | //mock下渠道2有1w条剩余量 19 | BatchMessageResultContext context = this.getFirstContextBean(); 20 | context.addQueryVO(new QueryVO("channel2", 10000)); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/cmp/Channel3QueryCmp.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.cmp; 2 | 3 | import com.example.demo.context.BatchMessageResultContext; 4 | import com.example.demo.vo.QueryVO; 5 | import com.yomahub.liteflow.annotation.LiteflowComponent; 6 | import com.yomahub.liteflow.core.NodeComponent; 7 | 8 | import java.util.Random; 9 | 10 | @LiteflowComponent(id = "channel3Query", name = "获取渠道3剩余量") 11 | public class Channel3QueryCmp extends NodeComponent { 12 | @Override 13 | public void process() throws Exception { 14 | //模拟查询业务耗时 15 | int time = new Random().nextInt(1000); 16 | Thread.sleep(time); 17 | 18 | //mock下渠道3有10w条剩余量 19 | BatchMessageResultContext context = this.getFirstContextBean(); 20 | context.addQueryVO(new QueryVO("channel3", 100000)); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/cmp/Channel4QueryCmp.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.cmp; 2 | 3 | import com.example.demo.context.BatchMessageResultContext; 4 | import com.example.demo.vo.QueryVO; 5 | import com.yomahub.liteflow.annotation.LiteflowComponent; 6 | import com.yomahub.liteflow.core.NodeComponent; 7 | 8 | import java.util.Random; 9 | 10 | @LiteflowComponent(id = "channel4Query", name = "获取渠道4剩余量") 11 | public class Channel4QueryCmp extends NodeComponent { 12 | @Override 13 | public void process() throws Exception { 14 | //模拟查询业务耗时 15 | int time = new Random().nextInt(1000); 16 | Thread.sleep(time); 17 | 18 | //mock下渠道4有7w条剩余量 19 | BatchMessageResultContext context = this.getFirstContextBean(); 20 | context.addQueryVO(new QueryVO("channel4", 70000)); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/cmp/Channel5QueryCmp.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.cmp; 2 | 3 | import com.example.demo.context.BatchMessageResultContext; 4 | import com.example.demo.vo.QueryVO; 5 | import com.yomahub.liteflow.annotation.LiteflowComponent; 6 | import com.yomahub.liteflow.core.NodeComponent; 7 | 8 | import java.util.Random; 9 | 10 | @LiteflowComponent(id = "channel5Query", name = "获取渠道5剩余量") 11 | public class Channel5QueryCmp extends NodeComponent { 12 | @Override 13 | public void process() throws Exception { 14 | //模拟查询业务耗时 15 | int time = new Random().nextInt(1000); 16 | Thread.sleep(time); 17 | 18 | //mock下渠道5有5000条剩余量 19 | BatchMessageResultContext context = this.getFirstContextBean(); 20 | context.addQueryVO(new QueryVO("channel5", 5000)); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/cmp/Channel6QueryCmp.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.cmp; 2 | 3 | import com.example.demo.context.BatchMessageResultContext; 4 | import com.example.demo.vo.QueryVO; 5 | import com.yomahub.liteflow.annotation.LiteflowComponent; 6 | import com.yomahub.liteflow.core.NodeComponent; 7 | 8 | import java.util.Random; 9 | 10 | @LiteflowComponent(id = "channel6Query", name = "获取渠道6剩余量") 11 | public class Channel6QueryCmp extends NodeComponent { 12 | @Override 13 | public void process() throws Exception { 14 | //模拟查询业务耗时 15 | int time = new Random().nextInt(1000); 16 | Thread.sleep(time); 17 | 18 | //mock下渠道6有3w条剩余量 19 | BatchMessageResultContext context = this.getFirstContextBean(); 20 | context.addQueryVO(new QueryVO("channel6", 30000)); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/cmp/BatchSenderCmp.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.cmp; 2 | 3 | import com.example.demo.context.BatchMessageResultContext; 4 | import com.yomahub.liteflow.annotation.LiteflowComponent; 5 | import com.yomahub.liteflow.core.NodeComponent; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import java.util.Random; 10 | 11 | @LiteflowComponent(id = "batchSender", name = "批量发送器") 12 | public class BatchSenderCmp extends NodeComponent { 13 | 14 | private static final Logger log = LoggerFactory.getLogger(BatchSenderCmp.class); 15 | 16 | @Override 17 | public void process() throws Exception { 18 | BatchMessageResultContext context = this.getFirstContextBean(); 19 | log.info("最终获取到的渠道为:[{}]", context.getFinalResultChannel()); 20 | 21 | //模拟业务发送耗时 22 | int time = new Random().nextInt(2000); 23 | Thread.sleep(time); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/cmp/ChannelSelectorCmp.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.cmp; 2 | 3 | import com.example.demo.context.BatchMessageResultContext; 4 | import com.example.demo.vo.QueryVO; 5 | import com.yomahub.liteflow.annotation.LiteflowComponent; 6 | import com.yomahub.liteflow.core.NodeComponent; 7 | import java.util.List; 8 | 9 | @LiteflowComponent(id = "channelSelector", name = "渠道余量最大选择器") 10 | public class ChannelSelectorCmp extends NodeComponent { 11 | @Override 12 | public void process() throws Exception { 13 | BatchMessageResultContext context = this.getFirstContextBean(); 14 | 15 | List queryList = context.getQueryResultList(); 16 | 17 | //选择渠道余量最大的 18 | QueryVO vo = queryList.stream().min((o1, o2) -> o2.getAvailCount() - o1.getAvailCount()).orElse(null); 19 | 20 | assert vo != null; 21 | context.setFinalResultChannel(vo.getChannel()); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/context/BatchMessageResultContext.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.context; 2 | 3 | import com.example.demo.vo.QueryVO; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | public class BatchMessageResultContext { 9 | 10 | private List queryResultList; 11 | 12 | private String finalResultChannel; 13 | 14 | public List getQueryResultList() { 15 | return queryResultList; 16 | } 17 | 18 | public void setQueryResultList(List queryResultList) { 19 | this.queryResultList = queryResultList; 20 | } 21 | 22 | public String getFinalResultChannel() { 23 | return finalResultChannel; 24 | } 25 | 26 | public void setFinalResultChannel(String finalResultChannel) { 27 | this.finalResultChannel = finalResultChannel; 28 | } 29 | 30 | public void addQueryVO(QueryVO queryVO){ 31 | if (queryResultList == null){ 32 | queryResultList = new ArrayList<>(); 33 | } 34 | queryResultList.add(queryVO); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/resources/config/flow.el.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | selectBestChannel = THEN( 5 | WHEN( 6 | channel1Query, channel2Query, channel3Query, 7 | channel4Query, channel5Query, channel6Query 8 | ), 9 | channelSelector 10 | ).id("branch1"); 11 | 12 | selectBizChannel = THEN( 13 | biz1, 14 | SWITCH(if_2).to( 15 | channel3, 16 | channel4, 17 | SWITCH(if_3).to(channel5, channel6).id("s3") 18 | ).id("s2") 19 | ).id("branch2"); 20 | 21 | THEN( 22 | packageData, 23 | SWITCH(if_1).to( 24 | channel1, 25 | channel2, 26 | selectBestChannel, 27 | selectBizChannel 28 | ), 29 | batchSender 30 | ); 31 | 32 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/ChainExecute.java: -------------------------------------------------------------------------------- 1 | package com.example.demo; 2 | 3 | import com.example.demo.context.BatchMessageResultContext; 4 | import com.yomahub.liteflow.core.FlowExecutor; 5 | import com.yomahub.liteflow.flow.LiteflowResponse; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | import org.springframework.boot.CommandLineRunner; 9 | import org.springframework.stereotype.Component; 10 | 11 | import javax.annotation.Resource; 12 | 13 | @Component 14 | public class ChainExecute implements CommandLineRunner { 15 | 16 | private static final Logger log = LoggerFactory.getLogger(ChainExecute.class); 17 | 18 | @Resource 19 | private FlowExecutor flowExecutor; 20 | 21 | @Override 22 | public void run(String... args) throws Exception { 23 | //第二个参数为流程入参,示例中没用到,所以传null,实际业务是有值的 24 | LiteflowResponse response = flowExecutor.execute2Resp("channelSenderChain", null, BatchMessageResultContext.class); 25 | BatchMessageResultContext context = response.getFirstContextBean(); 26 | if (response.isSuccess()){ 27 | log.info("执行成功,最终选择的渠道是{}", context.getFinalResultChannel()); 28 | }else{ 29 | log.error("执行失败", response.getCause()); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.7.1 9 | 10 | 11 | com.example 12 | message-demo 13 | 0.0.1-SNAPSHOT 14 | message-demo 15 | message-demo 16 | 17 | 1.8 18 | 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter 23 | 24 | 25 | 26 | com.yomahub 27 | liteflow-spring-boot-starter 28 | 2.11.4-BETA1 29 | 30 | 31 | 32 | 33 | 34 | 35 | org.springframework.boot 36 | spring-boot-maven-plugin 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /images/1.svg: -------------------------------------------------------------------------------- 1 | packageData组装数据if_1判断1channel2供应商2channel1Query获取供应商1剩余量channel2Query获取供应商2剩余量channel3Query获取供应商3剩余量channel4Query获取供应商4剩余量channelSelector选出剩余量最多的那个供应商biz1获取业务动态值条件2,指定供应商channel1供应商1条件1,指定供应商channel5Query获取供应商5剩余量channel6Query获取供应商6剩余量if_2判断2channel3供应商3channel4供应商4if_3判断3channel5供应商5channel6供应商6batchSender批量发送消息条件3,并行获取供应商渠道剩余量条件4,各种复杂判断 --------------------------------------------------------------------------------