enhancement #ID8XF9 对QLExpress4的支持

This commit is contained in:
everywhere.z
2025-12-05 17:26:45 +08:00
parent bfb794aa17
commit 6206697c82
15 changed files with 276 additions and 12 deletions

View File

@@ -1,8 +1,10 @@
package com.yomahub.liteflow.benchmark; package com.yomahub.liteflow.benchmark;
import cn.hutool.core.io.resource.ResourceUtil; import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.util.StrUtil;
import com.yomahub.liteflow.benchmark.bean.PriceCalcReqVO; import com.yomahub.liteflow.benchmark.bean.PriceCalcReqVO;
import com.yomahub.liteflow.benchmark.context.PriceContext; import com.yomahub.liteflow.benchmark.context.PriceContext;
import com.yomahub.liteflow.builder.el.LiteFlowChainELBuilder;
import com.yomahub.liteflow.core.FlowExecutor; import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.util.JsonUtil; import com.yomahub.liteflow.util.JsonUtil;
import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.annotations.*;
@@ -43,7 +45,8 @@ public class CommonExampleBenchmark {
applicationContext.close(); applicationContext.close();
} }
@Benchmark //执行阶段测试
//@Benchmark
public void test1(){ public void test1(){
flowExecutor.execute2Resp("mainChain", req, PriceContext.class); flowExecutor.execute2Resp("mainChain", req, PriceContext.class);
} }
@@ -52,7 +55,7 @@ public class CommonExampleBenchmark {
Options opt = new OptionsBuilder() Options opt = new OptionsBuilder()
.include(CommonExampleBenchmark.class.getSimpleName()) .include(CommonExampleBenchmark.class.getSimpleName())
.mode(Mode.Throughput) .mode(Mode.Throughput)
.warmupIterations(1)//预热次数 .warmupIterations(2)//预热次数
.measurementIterations(3)//执行次数 .measurementIterations(3)//执行次数
.measurementTime(new TimeValue(10, TimeUnit.SECONDS))//每次执行多少时间 .measurementTime(new TimeValue(10, TimeUnit.SECONDS))//每次执行多少时间
.threads(100)//多少个线程 .threads(100)//多少个线程

View File

@@ -1,9 +1,13 @@
package com.yomahub.liteflow.benchmark; package com.yomahub.liteflow.benchmark;
import cn.hutool.core.date.StopWatch;
import cn.hutool.core.io.resource.ResourceUtil; import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.util.StrUtil;
import com.yomahub.liteflow.benchmark.bean.PriceCalcReqVO; import com.yomahub.liteflow.benchmark.bean.PriceCalcReqVO;
import com.yomahub.liteflow.benchmark.context.PriceContext; import com.yomahub.liteflow.benchmark.context.PriceContext;
import com.yomahub.liteflow.builder.el.LiteFlowChainELBuilder;
import com.yomahub.liteflow.core.FlowExecutor; import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.flow.FlowBus;
import com.yomahub.liteflow.flow.LiteflowResponse; import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.util.JsonUtil; import com.yomahub.liteflow.util.JsonUtil;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@@ -28,10 +32,53 @@ public class CommonExampleTest {
@Test @Test
public void test1() throws Exception { public void test1() throws Exception {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
PriceCalcReqVO req = JsonUtil.parseObject(ResourceUtil.readUtf8Str("reqData.json"), PriceCalcReqVO.class); PriceCalcReqVO req = JsonUtil.parseObject(ResourceUtil.readUtf8Str("reqData.json"), PriceCalcReqVO.class);
LiteflowResponse response = flowExecutor.execute2Resp("mainChain", req, PriceContext.class); for (int i = 0; i < 60000; i++) {
if (!response.isSuccess()){ LiteflowResponse response = flowExecutor.execute2Resp("mainChain", req, PriceContext.class);
throw response.getCause(); if (!response.isSuccess()){
throw response.getCause();
}
} }
stopWatch.stop();
System.out.println(StrUtil.format("耗时:{}",stopWatch.getTotalTimeMillis()));
}
@Test
public void test2() throws Exception {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
String el = "THEN(\n" +
" checkCmp, slotInitCmp, priceStepInitCmp,\n" +
" promotionConvertCmp, s_memberDiscountCmp,\n" +
" promotionChain, s_couponCmp,\n" +
" SWITCH(postageCondCmp).to(postageCmp, overseaPostageCmp),\n" +
" priceResultCmp, stepPrintCmp\n" +
" );";
for (int i = 0; i < 20000; i++) {
LiteFlowChainELBuilder.createChain().setChainId("chain_build_" + i).setEL(el).build();
}
stopWatch.stop();
System.out.println(StrUtil.format("耗时:{}",stopWatch.getTotalTimeMillis()));
}
@Test
public void test3() throws Exception {
String el = "THEN(\n" +
" checkCmp.tag(\"{}\"), slotInitCmp, priceStepInitCmp,\n" +
" promotionConvertCmp, s_memberDiscountCmp,\n" +
" promotionChain, s_couponCmp,\n" +
" SWITCH(postageCondCmp).to(postageCmp, overseaPostageCmp),\n" +
" priceResultCmp, stepPrintCmp\n" +
" );";
StopWatch stopWatch = new StopWatch();
stopWatch.start();
for (int i = 0; i < 20000; i++) {
LiteFlowChainELBuilder.createChain().setChainId("chain_build_" + i).setEL(StrUtil.format(el, i)).build();
}
stopWatch.stop();
System.out.println(StrUtil.format("耗时:{},加载规则总数:{}",stopWatch.getTotalTimeMillis(), FlowBus.getChainMap().size()));
} }
} }

View File

@@ -1,2 +1,3 @@
liteflow.rule-source=flow*.xml liteflow.rule-source=flow*.xml
liteflow.fast-load=true
liteflow.print-execution-log=false liteflow.print-execution-log=false

View File

@@ -57,7 +57,7 @@ public class CommonBenchmark {
Options opt = new OptionsBuilder() Options opt = new OptionsBuilder()
.include(CommonBenchmark.class.getSimpleName()) .include(CommonBenchmark.class.getSimpleName())
.mode(Mode.Throughput) .mode(Mode.Throughput)
.warmupIterations(1)//预热次数 .warmupIterations(2)//预热次数
.measurementIterations(3)//执行次数 .measurementIterations(3)//执行次数
.measurementTime(new TimeValue(10, TimeUnit.SECONDS))//每次执行多少时间 .measurementTime(new TimeValue(10, TimeUnit.SECONDS))//每次执行多少时间
.threads(100)//多少个线程 .threads(100)//多少个线程

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>liteflow-benchmark</artifactId>
<groupId>com.yomahub</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>liteflow-benchmark-script-qlexpress</artifactId>
<dependencies>
<dependency>
<groupId>com.yomahub</groupId>
<artifactId>liteflow-script-qlexpress</artifactId>
<version>${liteflow-version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,59 @@
package com.yomahub.liteflow.benchmark;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.slot.DefaultContext;
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import org.openjdk.jmh.runner.options.TimeValue;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.PropertySource;
import java.util.concurrent.TimeUnit;
@State(Scope.Benchmark)
@EnableAutoConfiguration
@PropertySource(value = "classpath:application.properties")
@ComponentScan("com.yomahub.liteflow.benchmark.cmp")
public class ScriptQLExpressBenchmark {
private ConfigurableApplicationContext applicationContext;
private FlowExecutor flowExecutor;
@Setup
public void setup() {
applicationContext = SpringApplication.run(ScriptQLExpressBenchmark.class);
flowExecutor = applicationContext.getBean(FlowExecutor.class);
}
@TearDown
public void tearDown() {
applicationContext.close();
}
//执行阶段测试
@Benchmark
public void test1(){
flowExecutor.execute2Resp("chain1", null, DefaultContext.class);
}
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(ScriptQLExpressBenchmark.class.getSimpleName())
.mode(Mode.Throughput)
.warmupIterations(1)//预热次数
.measurementIterations(3)//执行次数
.measurementTime(new TimeValue(10, TimeUnit.SECONDS))//每次执行多少时间
.threads(100)//多少个线程
.forks(1)//多少个进程
.timeUnit(TimeUnit.SECONDS)
.build();
new Runner(opt).run();
}
}

View File

@@ -0,0 +1,29 @@
package com.yomahub.liteflow.benchmark;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.slot.DefaultContext;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import javax.annotation.Resource;
@ExtendWith(SpringExtension.class)
@TestPropertySource(value = "classpath:application.properties")
@SpringBootTest(classes = ScriptQLExpressTest.class)
@EnableAutoConfiguration
@ComponentScan({ "com.yomahub.liteflow.benchmark.cmp" })
public class ScriptQLExpressTest {
@Resource
private FlowExecutor flowExecutor;
@Test
public void test1() throws Exception {
flowExecutor.execute2Resp("chain1", null, DefaultContext.class);
}
}

View File

@@ -0,0 +1,20 @@
/**
* <p>Title: liteflow</p>
* <p>Description: 轻量级的组件式流程框架</p>
* @author Bryan.Zhang
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.benchmark.cmp;
import com.yomahub.liteflow.annotation.LiteflowComponent;
import com.yomahub.liteflow.core.NodeComponent;
@LiteflowComponent("a")
public class ACmp extends NodeComponent {
@Override
public void process() {
}
}

View File

@@ -0,0 +1,20 @@
/**
* <p>Title: liteflow</p>
* <p>Description: 轻量级的组件式流程框架</p>
* @author Bryan.Zhang
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.benchmark.cmp;
import com.yomahub.liteflow.annotation.LiteflowComponent;
import com.yomahub.liteflow.core.NodeComponent;
@LiteflowComponent("b")
public class BCmp extends NodeComponent {
@Override
public void process() {
}
}

View File

@@ -0,0 +1,20 @@
/**
* <p>Title: liteflow</p>
* <p>Description: 轻量级的组件式流程框架</p>
* @author Bryan.Zhang
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.benchmark.cmp;
import com.yomahub.liteflow.annotation.LiteflowComponent;
import com.yomahub.liteflow.core.NodeComponent;
@LiteflowComponent("c")
public class CCmp extends NodeComponent {
@Override
public void process() {
}
}

View File

@@ -0,0 +1,23 @@
/**
* <p>Title: liteflow</p>
* <p>Description: 轻量级的组件式流程框架</p>
* @author Bryan.Zhang
* @email weenyc31@163.com
* @Date 2020/4/1
*/
package com.yomahub.liteflow.benchmark.cmp;
import com.yomahub.liteflow.annotation.LiteflowComponent;
import com.yomahub.liteflow.core.NodeComponent;
import com.yomahub.liteflow.slot.DefaultContext;
@LiteflowComponent("d")
public class DCmp extends NodeComponent {
@Override
public void process() {
DefaultContext context = this.getFirstContextBean();
context.setData("count", 97);
}
}

View File

@@ -0,0 +1,2 @@
liteflow.rule-source=flow.xml
liteflow.print-execution-log=false

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow>
<nodes>
<node id="s1" name="普通脚本" type="script">
<![CDATA[
a=3;
b=2;
defaultContext.setData("s1",a*b);
]]>
</node>
</nodes>
<chain name="chain1">
THEN(s1);
</chain>
</flow>

View File

@@ -16,7 +16,7 @@
<properties> <properties>
<jmh.version>1.37</jmh.version> <jmh.version>1.37</jmh.version>
<liteflow-version>${revision}</liteflow-version> <liteflow-version>2.15.1</liteflow-version>
</properties> </properties>
<dependencies> <dependencies>
@@ -50,5 +50,6 @@
<module>liteflow-benchmark-common</module> <module>liteflow-benchmark-common</module>
<module>liteflow-benchmark-common-example</module> <module>liteflow-benchmark-common-example</module>
<module>liteflow-benchmark-compile</module> <module>liteflow-benchmark-compile</module>
<module>liteflow-benchmark-script-qlexpress</module>
</modules> </modules>
</project> </project>

View File

@@ -76,16 +76,15 @@ public class FlowBus {
static { static {
LiteflowConfig liteflowConfig = LiteflowConfigGetter.get(); LiteflowConfig liteflowConfig = LiteflowConfigGetter.get();
if (liteflowConfig.getFastLoad()){ if (liteflowConfig.getFastLoad()){
chainMap = new HashMap<>(); chainMap = new ConcurrentHashMap<>();
nodeMap = new HashMap<>(); nodeMap = new ConcurrentHashMap<>();
fallbackNodeMap = new HashMap<>(); fallbackNodeMap = new ConcurrentHashMap<>();
elMd5Map = new HashMap<>();
} else { } else {
chainMap = new CopyOnWriteHashMap<>(); chainMap = new CopyOnWriteHashMap<>();
nodeMap = new CopyOnWriteHashMap<>(); nodeMap = new CopyOnWriteHashMap<>();
fallbackNodeMap = new CopyOnWriteHashMap<>(); fallbackNodeMap = new CopyOnWriteHashMap<>();
elMd5Map = new ConcurrentHashMap<>();
} }
elMd5Map = new ConcurrentHashMap<>();
} }
public static Chain getChain(String id) { public static Chain getChain(String id) {