#IB0SJ1 调优代码

This commit is contained in:
jay li
2024-11-25 19:57:05 +08:00
parent 54ec21ca7d
commit 541d574fcc
12 changed files with 171 additions and 144 deletions

View File

@@ -2,9 +2,7 @@ package com.yomahub.liteflow.builder.el;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.*;
import cn.hutool.crypto.digest.MD5;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ql.util.express.DefaultContext;
import com.ql.util.express.ExpressRunner;
@@ -22,22 +20,14 @@ import com.yomahub.liteflow.flow.element.Executable;
import com.yomahub.liteflow.flow.element.Node;
import com.yomahub.liteflow.flow.element.condition.AndOrCondition;
import com.yomahub.liteflow.flow.element.condition.NotCondition;
import com.yomahub.liteflow.flow.instanceId.InstanceIdGeneratorHolder;
import com.yomahub.liteflow.flow.instanceId.InstanceIdGeneratorSpi;
import com.yomahub.liteflow.flow.instanceId.NodeInstanceIdManageSpi;
import com.yomahub.liteflow.log.LFLog;
import com.yomahub.liteflow.log.LFLoggerManager;
import com.yomahub.liteflow.property.LiteflowConfig;
import com.yomahub.liteflow.property.LiteflowConfigGetter;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import static com.yomahub.liteflow.util.JsonUtil.*;
import static com.yomahub.liteflow.common.ChainConstant.NODE_INSTANCE_PATH;
import static com.yomahub.liteflow.common.ChainConstant.USER_DIR;
import static com.yomahub.liteflow.util.JsonUtil.parseObject;
import static com.yomahub.liteflow.util.JsonUtil.toJsonString;
import static com.yomahub.liteflow.util.SerialsUtil.generateShortUUID;
/**
@@ -251,71 +241,11 @@ public class LiteFlowChainELBuilder {
// 往condition里设置instanceId
private void setNodesInstanceId(Condition condition) {
InstanceIdGeneratorSpi instanceIdGenerator = InstanceIdGeneratorHolder.getInstance().getInstanceIdGenerator();
InstanceIdGeneratorSpi instanceIdGenerator = NodeInstanceIdManageSpi.getInstance().getInstanceIdGenerator();
String elMd5 = MD5.create().digestHex(chain.getEl());
List<String> instanceIdFile = instanceIdGenerator.readInstanceIdFile(chain.getChainId());
// 如果文件不存在或者文件内容不是当前el则写入
if (CollUtil.isEmpty(instanceIdFile) || !instanceIdFile.get(0).equals(elMd5)) {
instanceIdGenerator.writeInstanceIdFile(writeNodeInstanceId(condition, elMd5), chain.getChainId());
} else {
// 文件存在,则直接读取
Map<String, List<String>> executableMap = new HashMap<>();
for (int i = 1; i < instanceIdFile.size(); i++) {
JsonNode groupKeyAndInstanceIds = parseObject(instanceIdFile.get(i));
if (groupKeyAndInstanceIds == null) {
continue;
}
Iterator<String> fieldNames = groupKeyAndInstanceIds.fieldNames();
while (fieldNames.hasNext()) {
String key = fieldNames.next();
JsonNode valueNode = groupKeyAndInstanceIds.get(key);
if (valueNode.isArray()) {
List<String> valueList = new ArrayList<>();
for (int j = 1; j < valueNode.size(); j+=2) {
valueList.add(valueNode.get(j).asText());
}
executableMap.put(key, valueList);
}
}
}
condition.getExecutableGroup().forEach((key, executables) -> {
AtomicInteger index = new AtomicInteger(0);
executables.forEach(executable -> {
if (executableMap.containsKey(key)) {
if (executable instanceof Node) {
((Node) executable).setInstanceId((executableMap.get(key).get(index.getAndIncrement())));
}
}
});
});
}
instanceIdGenerator.setNodesInstanceId(condition, chain);
}
// 写入时第一行为el的md5第二行为json格式的groupKey和对应的nodeId 和实例id
private List<String> writeNodeInstanceId(Condition condition, String elMd5) {
ArrayList<String> writeList = new ArrayList<>();
writeList.add(elMd5);
Map<String, List<String>> groupKeyAndInstanceIds = new HashMap<>();
condition.getExecutableGroup().forEach((key, executables) -> {
List<String> instanceIds = new ArrayList<>();
executables.forEach(executable -> {
if (executable instanceof Node) {
((Node) executable).setInstanceId(generateShortUUID());
instanceIds.add(executable.getId());
instanceIds.add(((Node) executable).getInstanceId());
}
});
groupKeyAndInstanceIds.put(key, instanceIds);
});
writeList.add(toJsonString(groupKeyAndInstanceIds));
return writeList;
}
public LiteFlowChainELBuilder setNamespace(String nameSpace){
if (StrUtil.isBlank(nameSpace)) {

View File

@@ -0,0 +1,129 @@
package com.yomahub.liteflow.flow.instanceId;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.crypto.digest.MD5;
import com.fasterxml.jackson.databind.JsonNode;
import com.yomahub.liteflow.flow.element.Chain;
import com.yomahub.liteflow.flow.element.Condition;
import com.yomahub.liteflow.flow.element.Node;
import org.apache.commons.lang.StringUtils;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import static com.yomahub.liteflow.util.JsonUtil.parseObject;
import static com.yomahub.liteflow.util.JsonUtil.toJsonString;
import static com.yomahub.liteflow.util.SerialsUtil.generateShortUUID;
/**
* @author lhh
* @since 2.13.0
*/
public abstract class BaseInstanceIdGeneratorSpi implements InstanceIdGeneratorSpi {
// 根据实例id获取 节点实例定位
@Override
public String getNodeInstanceId(String chainId, String instanceId) {
if (StringUtils.isBlank(chainId) || StringUtils.isBlank(instanceId)) {
return "";
}
List<String> instanceIdFile = readInstanceIdFile(chainId);
for (int i = 1; i < instanceIdFile.size(); i++) {
JsonNode groupKeyAndInstanceIds = parseObject(instanceIdFile.get(i));
if (groupKeyAndInstanceIds == null) {
continue;
}
Iterator<String> fieldNames = groupKeyAndInstanceIds.fieldNames();
while (fieldNames.hasNext()) {
String key = fieldNames.next();
JsonNode valueNode = groupKeyAndInstanceIds.get(key);
if (valueNode.isArray()) {
Map<String, Integer> map = new HashMap<>();
for (int j = 1; j < valueNode.size(); j+=2) {
String nodeId = valueNode.get(j - 1).asText();
map.put(nodeId, map.getOrDefault(nodeId, -1)+1);
if (instanceId.equals(valueNode.get(j).asText())) {
return nodeId + "(" + (map.get(nodeId)) + ")";
}
}
}
}
}
return "";
}
// 往condition里设置instanceId
@Override
public void setNodesInstanceId(Condition condition, Chain chain) {
InstanceIdGeneratorSpi instanceIdGenerator = NodeInstanceIdManageSpi.getInstance().getInstanceIdGenerator();
String elMd5 = MD5.create().digestHex(chain.getEl());
List<String> instanceIdFile = instanceIdGenerator.readInstanceIdFile(chain.getChainId());
// 如果文件不存在或者文件内容不是当前el则写入
if (CollUtil.isEmpty(instanceIdFile) || !instanceIdFile.get(0).equals(elMd5)) {
instanceIdGenerator.writeInstanceIdFile(writeNodeInstanceId(condition, elMd5), chain.getChainId());
} else {
// 文件存在,则直接读取
Map<String, List<String>> executableMap = new HashMap<>();
for (int i = 1; i < instanceIdFile.size(); i++) {
JsonNode groupKeyAndInstanceIds = parseObject(instanceIdFile.get(i));
if (groupKeyAndInstanceIds == null) {
continue;
}
Iterator<String> fieldNames = groupKeyAndInstanceIds.fieldNames();
while (fieldNames.hasNext()) {
String key = fieldNames.next();
JsonNode valueNode = groupKeyAndInstanceIds.get(key);
if (valueNode.isArray()) {
List<String> valueList = new ArrayList<>();
for (int j = 1; j < valueNode.size(); j+=2) {
valueList.add(valueNode.get(j).asText());
}
executableMap.put(key, valueList);
}
}
}
condition.getExecutableGroup().forEach((key, executables) -> {
AtomicInteger index = new AtomicInteger(0);
executables.forEach(executable -> {
if (executableMap.containsKey(key)) {
if (executable instanceof Node) {
((Node) executable).setInstanceId((executableMap.get(key).get(index.getAndIncrement())));
}
}
});
});
}
}
// 写入时第一行为el的md5第二行为json格式的groupKey和对应的nodeId 和实例id
private List<String> writeNodeInstanceId(Condition condition, String elMd5) {
ArrayList<String> writeList = new ArrayList<>();
writeList.add(elMd5);
Map<String, List<String>> groupKeyAndInstanceIds = new HashMap<>();
condition.getExecutableGroup().forEach((key, executables) -> {
List<String> instanceIds = new ArrayList<>();
executables.forEach(executable -> {
if (executable instanceof Node) {
((Node) executable).setInstanceId(generateShortUUID());
instanceIds.add(executable.getId());
instanceIds.add(((Node) executable).getInstanceId());
}
});
groupKeyAndInstanceIds.put(key, instanceIds);
});
writeList.add(toJsonString(groupKeyAndInstanceIds));
return writeList;
}
}

View File

@@ -13,9 +13,9 @@ import static com.yomahub.liteflow.common.ChainConstant.USER_DIR;
/**
* @author Jay li
* @since 2.12.4
* @since 2.13.0
*/
public class DefaultInstanceIdGeneratorSpi implements InstanceIdGeneratorSpi {
public class DefaultInstanceIdGeneratorSpi extends BaseInstanceIdGeneratorSpi {
private final String basePath = System.getProperty(USER_DIR) + File.separator + NODE_INSTANCE_PATH + File.separator;

View File

@@ -1,18 +1,14 @@
package com.yomahub.liteflow.flow.instanceId;
import com.fasterxml.jackson.databind.JsonNode;
import org.apache.commons.lang.StringUtils;
import com.yomahub.liteflow.flow.element.Chain;
import com.yomahub.liteflow.flow.element.Condition;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import static com.yomahub.liteflow.util.JsonUtil.parseObject;
/**
* @author Jay li
* @since 2.12.4
* @since 2.13.0
*/
public interface InstanceIdGeneratorSpi {
// 拿文件保存路径, 不同插件不同实现
@@ -20,40 +16,12 @@ public interface InstanceIdGeneratorSpi {
List<String> readInstanceIdFile(String chainId);
// 写入文件保存
void writeInstanceIdFile(List<String> instanceIdList,String chainId);
void writeInstanceIdFile(List<String> instanceIdList, String chainId);
// 根据实例id获取 节点实例定位
default String getNodeInstanceId(String chainId, String instanceId) {
if (StringUtils.isBlank(chainId) || StringUtils.isBlank(instanceId)) {
return "";
}
String getNodeInstanceId(String chainId, String instanceId);
List<String> instanceIdFile = readInstanceIdFile(chainId);
// 设置node节点的实例id
void setNodesInstanceId(Condition condition, Chain chain);
for (int i = 1; i < instanceIdFile.size(); i++) {
JsonNode groupKeyAndInstanceIds = parseObject(instanceIdFile.get(i));
if (groupKeyAndInstanceIds == null) {
continue;
}
Iterator<String> fieldNames = groupKeyAndInstanceIds.fieldNames();
while (fieldNames.hasNext()) {
String key = fieldNames.next();
JsonNode valueNode = groupKeyAndInstanceIds.get(key);
if (valueNode.isArray()) {
Map<String, Integer> map = new HashMap<>();
for (int j = 1; j < valueNode.size(); j+=2) {
String nodeId = valueNode.get(j - 1).asText();
map.put(nodeId, map.getOrDefault(nodeId, -1)+1);
if (instanceId.equals(valueNode.get(j).asText())) {
return nodeId + "(" + (map.get(nodeId)) + ")";
}
}
}
}
}
return "";
}
}
}

View File

@@ -7,12 +7,12 @@ import java.util.ServiceLoader;
/**
* @author Jay li
* @since 2.12.4
* @since 2.13.0
*/
public class InstanceIdGeneratorHolder {
public class NodeInstanceIdManageSpi {
private InstanceIdGeneratorSpi instanceIdGenerator;
private static final InstanceIdGeneratorHolder INSTANCE = new InstanceIdGeneratorHolder();
private static final NodeInstanceIdManageSpi INSTANCE = new NodeInstanceIdManageSpi();
public static void init() {
ServiceLoader<InstanceIdGeneratorSpi> loader = ServiceLoader.load(InstanceIdGeneratorSpi.class);
@@ -24,7 +24,7 @@ public class InstanceIdGeneratorHolder {
}
}
public static InstanceIdGeneratorHolder getInstance() {
public static NodeInstanceIdManageSpi getInstance() {
return INSTANCE;
}

View File

@@ -2,7 +2,7 @@ package com.yomahub.liteflow.parser.spi.instanceId;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.yomahub.liteflow.flow.instanceId.InstanceIdGeneratorSpi;
import com.yomahub.liteflow.flow.instanceId.BaseInstanceIdGeneratorSpi;
import com.yomahub.liteflow.parser.constant.ReadType;
import com.yomahub.liteflow.parser.constant.SqlReadConstant;
import com.yomahub.liteflow.parser.sql.read.SqlRead;
@@ -22,7 +22,8 @@ import java.util.List;
* @since 2.12.4
*/
public class SqlInstanceIdGeneratorSpi implements InstanceIdGeneratorSpi {
public class SqlInstanceIdGeneratorSpi extends BaseInstanceIdGeneratorSpi {
@Override
public List<String> readInstanceIdFile(String chainId) {
SqlRead<InstanceIdVO> insIdRead = SqlReadFactory.getSqlRead(ReadType.INSTANCE_ID);
@@ -41,11 +42,11 @@ public class SqlInstanceIdGeneratorSpi implements InstanceIdGeneratorSpi {
SQLParserVO conf = jdbcHelper.getSqlParserVO();
String insertSql = StrUtil.format(SqlReadConstant.INSTANT_INSERT_SQL, conf.getInstanceIdTableName(), conf.getInstanceIdApplicationNameField(),
conf.getGroupKeyInstanceIdField(), conf.getElDataMd5Field(), conf.getInstanceChainNameField(), conf.getApplicationName(), instanceIdList.get(1),
conf.getGroupKeyInstanceIdField(), conf.getElDataMd5Field(), conf.getInstanceChainIdField(), conf.getApplicationName(), instanceIdList.get(1),
instanceIdList.get(0), chainId);
String updateSql = StrUtil.format(SqlReadConstant.INSTANT_UPDATE_SQL, conf.getInstanceIdTableName(), conf.getElDataMd5Field(), instanceIdList.get(0),
conf.getGroupKeyInstanceIdField(), instanceIdList.get(1), conf.getChainNameField(), chainId, conf.getInstanceIdApplicationNameField(), conf.getApplicationName());
String selectSql = StrUtil.format(SqlReadConstant.INSTANT_SELECT_SQL, conf.getInstanceIdTableName(), conf.getInstanceChainNameField(), chainId,
String selectSql = StrUtil.format(SqlReadConstant.INSTANT_SELECT_SQL, conf.getInstanceIdTableName(), conf.getInstanceChainIdField(), chainId,
conf.getInstanceIdApplicationNameField(), conf.getApplicationName());
jdbcHelper.executeUpsert(selectSql, insertSql, updateSql);

View File

@@ -26,7 +26,7 @@ public class InstanceIdRead extends AbstractSqlRead<InstanceIdVO> {
@Override
protected InstanceIdVO parse(ResultSet rs) throws SQLException {
InstanceIdVO idVO = new InstanceIdVO();
idVO.setChainName(getStringFromRsWithCheck(rs, super.config.getInstanceChainNameField()));
idVO.setChainId(getStringFromRsWithCheck(rs, super.config.getInstanceChainIdField()));
idVO.setElDataMd5(getStringFromRsWithCheck(rs, super.config.getElDataMd5Field()));
idVO.setGroupKeyInstanceId(getStringFromRsWithCheck(rs, super.config.getGroupKeyInstanceIdField()));
return idVO;
@@ -45,7 +45,7 @@ public class InstanceIdRead extends AbstractSqlRead<InstanceIdVO> {
@Override
public String buildQuerySql(String... exceptions) {
String tableName = super.config.getInstanceIdTableName();
String chainNameField = super.config.getInstanceChainNameField();
String chainNameField = super.config.getInstanceChainIdField();
if (ArrayUtil.isEmpty(exceptions)) {
throw new IllegalArgumentException("You did not define the chainName");
@@ -56,7 +56,7 @@ public class InstanceIdRead extends AbstractSqlRead<InstanceIdVO> {
@Override
public void checkConfig() {
String tableName = super.config.getInstanceIdTableName();
String chainNameField = super.config.getInstanceChainNameField();
String chainNameField = super.config.getInstanceChainIdField();
if (StrUtil.isBlank(tableName)) {
throw new ELSQLException("You did not define the tableName property");
}

View File

@@ -7,18 +7,18 @@ package com.yomahub.liteflow.parser.sql.read.vo;
public class InstanceIdVO {
private String chainName;
private String chainId;
private String elDataMd5;
private String groupKeyInstanceId;
public String getChainName() {
return chainName;
public String getChainId() {
return chainId;
}
public void setChainName(String chainName) {
this.chainName = chainName;
public void setChainId(String chainId) {
this.chainId = chainId;
}
public String getElDataMd5() {

View File

@@ -67,9 +67,9 @@ public class SQLParserVO {
*/
private String instanceIdApplicationNameField = "application_name";
/**
* instanceId 里的 chainName 字段
* instanceId 里的 chainId 字段
*/
private String instanceChainNameField = "chain_name";
private String instanceChainIdField = "chain_id";
/**
* el md5
@@ -423,12 +423,12 @@ public class SQLParserVO {
return instanceIdTableName;
}
public String getInstanceChainNameField() {
return instanceChainNameField;
public String getInstanceChainIdField() {
return instanceChainIdField;
}
public void setInstanceChainNameField(String instanceChainNameField) {
this.instanceChainNameField = instanceChainNameField;
public void setInstanceChainIdField(String instanceChainIdField) {
this.instanceChainIdField = instanceChainIdField;
}
public void setInstanceIdTableName(String instanceIdTableName) {

View File

@@ -2,8 +2,8 @@ package com.yomahub.liteflow.test.instanceIds;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.flow.instanceId.InstanceIdGeneratorHolder;
import com.yomahub.liteflow.flow.instanceId.InstanceIdGeneratorSpi;
import com.yomahub.liteflow.flow.instanceId.NodeInstanceIdManageSpi;
import com.yomahub.liteflow.test.BaseTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@@ -80,7 +80,7 @@ public class InstanceIdELSpringTest extends BaseTest {
String executeStepStrWithInstanceId = response.getExecuteStepStrWithInstanceId();
List<String> strings = extractValuesList(executeStepStrWithInstanceId);
InstanceIdGeneratorSpi instanceIdGenerator = InstanceIdGeneratorHolder.getInstance().getInstanceIdGenerator();
InstanceIdGeneratorSpi instanceIdGenerator = NodeInstanceIdManageSpi.getInstance().getInstanceIdGenerator();
for (int i = 0; i < strings.size(); i++) {
Assertions.assertEquals(instanceIdGenerator.getNodeInstanceId("chain2", strings.get(i)), "a(" + i + ")");

View File

@@ -2,8 +2,8 @@ package com.yomahub.liteflow.test.sqlInstanceId;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.flow.instanceId.InstanceIdGeneratorHolder;
import com.yomahub.liteflow.flow.instanceId.InstanceIdGeneratorSpi;
import com.yomahub.liteflow.flow.instanceId.NodeInstanceIdManageSpi;
import com.yomahub.liteflow.parser.sql.exception.ELSQLException;
import com.yomahub.liteflow.parser.sql.vo.SQLParserVO;
import com.yomahub.liteflow.property.LiteflowConfig;
@@ -28,7 +28,6 @@ import java.sql.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -83,7 +82,7 @@ public class SQLWithXmlELInstanceIdSpringbootTest extends BaseTest {
String executeStepStrWithInstanceId = response.getExecuteStepStrWithInstanceId();
List<String> strings = extractValuesList(executeStepStrWithInstanceId);
InstanceIdGeneratorSpi instanceIdGenerator = InstanceIdGeneratorHolder.getInstance().getInstanceIdGenerator();
InstanceIdGeneratorSpi instanceIdGenerator = NodeInstanceIdManageSpi.getInstance().getInstanceIdGenerator();
String[] nodes = new String[]{"c", "b", "a"};
for (int i = 0; i < strings.size(); i++) {
@@ -114,7 +113,7 @@ public class SQLWithXmlELInstanceIdSpringbootTest extends BaseTest {
sqlParserVO.getPassword());
Statement statement = connection.createStatement();
ResultSet rs = statement.executeQuery("select * from NODE_INSTANCE_ID_TABLE where APPLICATION_NAME = 'demo' " +
"and CHAIN_NAME = '" + chainId + "' ");
"and chain_id = '" + chainId + "' ");
String res = "";
while (rs.next()) {

View File

@@ -26,7 +26,7 @@ create table IF NOT EXISTS `node_instance_id_table`
(
`id` bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
`application_name` varchar(32) NOT NULL,
`chain_name` varchar(32) NOT NULL,
`chain_id` varchar(32) NOT NULL,
`el_data_md5` varchar(128) NOT NULL,
`group_key_instance_id` varchar(1024) NOT NULL,
PRIMARY KEY (`id`)