From 55588b89a347c1aa04099bc152b912a1bd17845a Mon Sep 17 00:00:00 2001 From: yanglin Date: Thu, 11 Jul 2024 11:20:22 +0800 Subject: [PATCH 1/7] =?UTF-8?q?REQ-2599:=20=E6=8E=A5=E5=85=A5arthas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- inside-notices/pom.xml | 4 ++++ pom.xml | 5 +++++ start/src/main/resources/application.yml | 5 ++++- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/inside-notices/pom.xml b/inside-notices/pom.xml index 3917ba4c..8a06e915 100644 --- a/inside-notices/pom.xml +++ b/inside-notices/pom.xml @@ -21,6 +21,10 @@ + + com.taobao.arthas + arthas-spring-boot-starter + cn.axzo.trade trade-web-spring-boot-starter diff --git a/pom.xml b/pom.xml index ded73cda..e4be8be4 100644 --- a/pom.xml +++ b/pom.xml @@ -95,6 +95,11 @@ + + com.taobao.arthas + arthas-spring-boot-starter + 3.7.1 + org.projectlombok diff --git a/start/src/main/resources/application.yml b/start/src/main/resources/application.yml index 46b20548..6ad3fa98 100644 --- a/start/src/main/resources/application.yml +++ b/start/src/main/resources/application.yml @@ -17,7 +17,10 @@ spring: web: resources: add-mappings: false - +arthas: + app-name: ${spring.application.name} + agent-id: ${ARTHAS_AGENT_ID:${spring.profiles.active}-${spring.application.name}} + tunnel-server: ${ARTHAS_TUNNEL_SERVER:ws://localhost:7777/ws} # redis: # #外网地址和端口 禁止使用外网地址,会导致jenkins 部署 服务起不来 # #host: 123.249.44.111 From dcb5bc0a84f25ef64f06bef8d0043ffa8b79714c Mon Sep 17 00:00:00 2001 From: yanglin Date: Thu, 11 Jul 2024 13:44:03 +0800 Subject: [PATCH 2/7] REQ-2599: cache path for better performance --- .../message/service/group/NodeWrapper.java | 7 ++++ .../service/group/RootNodeWrapper.java | 36 ++++++++----------- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/group/NodeWrapper.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/group/NodeWrapper.java index 2d9b1537..30b841c5 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/group/NodeWrapper.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/group/NodeWrapper.java @@ -3,7 +3,10 @@ package cn.axzo.msg.center.message.service.group; import cn.axzo.maokai.api.vo.response.tree.NodeValue; import cn.axzo.msg.center.domain.entity.MessageGroupNode; import cn.axzo.msg.center.utils.TreeHelperUtil; +import lombok.AccessLevel; +import lombok.Getter; import lombok.RequiredArgsConstructor; +import lombok.Setter; import org.apache.commons.lang3.StringUtils; import java.util.Map; @@ -16,6 +19,10 @@ public class NodeWrapper implements NodeValue { private final MessageGroupNode node; private final Map code2Id; + // cache path for better performance + @Setter(AccessLevel.PACKAGE) + @Getter(AccessLevel.PACKAGE) + private String pathCache; @Override public Long id() { diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/group/RootNodeWrapper.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/group/RootNodeWrapper.java index 32eda67a..157f9766 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/group/RootNodeWrapper.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/group/RootNodeWrapper.java @@ -1,11 +1,9 @@ package cn.axzo.msg.center.message.service.group; -import cn.axzo.maokai.api.util.Ref; import cn.axzo.maokai.api.vo.response.tree.Node; import cn.axzo.maokai.api.vo.response.tree.RootNode; import cn.axzo.maokai.api.vo.response.tree.ValueNode; import cn.axzo.msg.center.common.utils.BizAssertions; -import cn.axzo.msg.center.domain.entity.MessageGroupNode; import com.alibaba.fastjson.JSON; import java.util.ArrayList; @@ -15,8 +13,8 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; -import java.util.function.Function; +import static java.util.function.Function.identity; import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toMap; @@ -25,13 +23,14 @@ import static java.util.stream.Collectors.toMap; */ public class RootNodeWrapper { - private final RootNode root; private final Map> code2Node; + private final Map> id2Node; - public RootNodeWrapper(RootNode root) { - this.root = root; + RootNodeWrapper(RootNode root) { this.code2Node = root.getValueNodes().stream() - .collect(toMap(node -> node.getValue().getNodeCode(), Function.identity())); + .collect(toMap(node -> node.getValue().getNodeCode(), identity())); + this.id2Node = root.getValueNodes().stream() + .collect(toMap(node -> node.getValue().unwrap().getId(), identity())); } public Optional> findValueNode(String groupNodeCode) { @@ -39,18 +38,7 @@ public class RootNodeWrapper { } public Optional> findValueNode(Long id) { - Ref> ref = Ref.create(); - unwrap().walkDown(node -> { - //noinspection unchecked - ValueNode valueNode = node.tryCast(ValueNode.class); - if (valueNode == null) - return true; - MessageGroupNode groupNode = valueNode.getValue().unwrap(); - if (id.equals(groupNode.getId())) - ref.set(valueNode); - return ref.isNull(); - }); - return Optional.ofNullable(ref.get()); + return Optional.ofNullable(id2Node.get(id)); } public List> getNodes(Collection groupNodeCodes) { @@ -62,6 +50,13 @@ public class RootNodeWrapper { } public String getPath(ValueNode node) { + NodeWrapper wrapper = node.getValue(); + if (wrapper.getPathCache() == null) + wrapper.setPathCache(getPathImpl(node)); + return wrapper.getPathCache(); + } + + private static String getPathImpl(ValueNode node) { ArrayList paths = new ArrayList<>(); Node current = node; int stack = 0; @@ -79,7 +74,4 @@ public class RootNodeWrapper { return String.join(":", paths); } - public RootNode unwrap() { - return root; - } } \ No newline at end of file From ecc7a16122bcc80cc0f4ee345a2d3cf5c51420d1 Mon Sep 17 00:00:00 2001 From: yanglin Date: Thu, 11 Jul 2024 13:44:52 +0800 Subject: [PATCH 3/7] REQ-2599: cache path for better performance --- .../axzo/msg/center/message/service/group/NodeWrapper.java | 2 +- .../msg/center/message/service/group/RootNodeWrapper.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/group/NodeWrapper.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/group/NodeWrapper.java index 30b841c5..6bd4fead 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/group/NodeWrapper.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/group/NodeWrapper.java @@ -22,7 +22,7 @@ public class NodeWrapper implements NodeValue { // cache path for better performance @Setter(AccessLevel.PACKAGE) @Getter(AccessLevel.PACKAGE) - private String pathCache; + private String cachedPath; @Override public Long id() { diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/group/RootNodeWrapper.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/group/RootNodeWrapper.java index 157f9766..e885c893 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/group/RootNodeWrapper.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/group/RootNodeWrapper.java @@ -51,9 +51,9 @@ public class RootNodeWrapper { public String getPath(ValueNode node) { NodeWrapper wrapper = node.getValue(); - if (wrapper.getPathCache() == null) - wrapper.setPathCache(getPathImpl(node)); - return wrapper.getPathCache(); + if (wrapper.getCachedPath() == null) + wrapper.setCachedPath(getPathImpl(node)); + return wrapper.getCachedPath(); } private static String getPathImpl(ValueNode node) { From 1d4e1c2e224df5d9ecac0ec8ef0d274d7803dd0f Mon Sep 17 00:00:00 2001 From: yanglin Date: Thu, 11 Jul 2024 13:52:13 +0800 Subject: [PATCH 4/7] REQ-2599: cache path for better performance --- .../service/group/RootNodeWrapper.java | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/group/RootNodeWrapper.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/group/RootNodeWrapper.java index e885c893..c2f0d10c 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/group/RootNodeWrapper.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/group/RootNodeWrapper.java @@ -4,11 +4,8 @@ import cn.axzo.maokai.api.vo.response.tree.Node; import cn.axzo.maokai.api.vo.response.tree.RootNode; import cn.axzo.maokai.api.vo.response.tree.ValueNode; import cn.axzo.msg.center.common.utils.BizAssertions; -import com.alibaba.fastjson.JSON; -import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Objects; @@ -56,22 +53,26 @@ public class RootNodeWrapper { return wrapper.getCachedPath(); } - private static String getPathImpl(ValueNode node) { - ArrayList paths = new ArrayList<>(); + private String getPathImpl(ValueNode node) { + // code是uuid去掉-, 一般层级为3, 通过冒号分割, 所有长度为: 32 * 3 + 2 = 98 + // 初始长度直接设置为98, 避免频繁扩容 + StringBuilder builder = new StringBuilder(98); Node current = node; int stack = 0; while (current != null) { - BizAssertions.assertTrue(stack <= 500, String.format( - "分类层级过多或者数据错误, 最大层级: %s", JSON.toJSONString(current))); + // Assuming a reasonable maximum depth to avoid frequent resizing + BizAssertions.assertTrue(stack <= 500, "分类层级过多或者数据错误"); stack++; - //noinspection unchecked + @SuppressWarnings("unchecked") ValueNode valueNode = current.tryCast(ValueNode.class); - if (valueNode != null) - paths.add(valueNode.getValue().getNodeCode()); + if (valueNode != null) { + if (builder.length() > 0) + builder.insert(0, ":"); + builder.insert(0, valueNode.getValue().getNodeCode()); + } current = current.getParent(); } - Collections.reverse(paths); - return String.join(":", paths); + return builder.toString(); } } \ No newline at end of file From b312e86d025f6ac3a8e848392908d970b10ad477 Mon Sep 17 00:00:00 2001 From: yanglin Date: Thu, 11 Jul 2024 14:11:13 +0800 Subject: [PATCH 5/7] REQ-2599: cache path for better performance --- .../message/service/todo/LeafNodeStats.java | 41 ++++++++----------- .../service/todo/TodoRangeQueryService.java | 6 ++- 2 files changed, 21 insertions(+), 26 deletions(-) diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/todo/LeafNodeStats.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/todo/LeafNodeStats.java index b26b88e9..19cf3f50 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/todo/LeafNodeStats.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/todo/LeafNodeStats.java @@ -7,8 +7,9 @@ import cn.axzo.msg.center.message.service.group.NodeWrapper; import cn.axzo.msg.center.service.enums.TodoType; import lombok.RequiredArgsConstructor; -import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * @author yanglin @@ -20,32 +21,24 @@ class LeafNodeStats { private final List stats; private final GroupTemplates groupTemplates; - int getCount(ValueNode node, TodoType todoType) { - return getCount(Collections.singletonList(node), todoType); - } - - int getCount(List> nodes, TodoType todoType) { - int count = 0; + Map collectStat(ValueNode node) { + HashMap type2Count = new HashMap<>(); for (Todo stat : stats) { - if (stat.getType() != todoType) - continue; // 只统计叶子节点的数据, 显示列表不关心中间节点 - boolean leafNodeContainsTemplate = nodes.stream() - .map(ValueNode::getValue) - .filter(NodeWrapper::isLeaf) - .anyMatch(node -> groupTemplates - .groupContainsTemplate(node.getNodeCode(), stat.getTemplateCode())); - if (leafNodeContainsTemplate) - count += stat.getCount(); + boolean leafNodeContainsTemplate = groupTemplates.groupContainsTemplate( + node.getValue().getNodeCode(), stat.getTemplateCode()); + if (leafNodeContainsTemplate) { + Integer prevCount = type2Count.get(stat.getType()); + if (prevCount == null) prevCount = 0; + Integer currentCount = prevCount + stat.getCount(); + type2Count.put(stat.getType(), currentCount); + } } - return count; - } - - int getCount(TodoType todoType) { - return stats.stream() - .filter(s -> s.getType() == todoType) - .mapToInt(Todo::getCount) - .sum(); + for (TodoType type : TodoType.values()) { + if (!type2Count.containsKey(type)) + type2Count.put(type, 0); + } + return type2Count; } } diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/todo/TodoRangeQueryService.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/todo/TodoRangeQueryService.java index 17c89afe..673fdb65 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/todo/TodoRangeQueryService.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/todo/TodoRangeQueryService.java @@ -58,6 +58,7 @@ import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.function.Supplier; import static cn.axzo.msg.center.inside.notices.utils.Queries.query; @@ -272,9 +273,10 @@ public class TodoRangeQueryService { groupStat.setGroupCode(node.getCode()); groupStat.setGroupName(node.getName()); groupStat.setGroupIcon(node.getIcon()); + Map type2Count = nodeStats.collectStat(valueNode); groupStat.setStat(new Stat( - nodeStats.getCount(valueNode, TodoType.EXECUTABLE), - nodeStats.getCount(valueNode, TodoType.COPIED_TO_ME))); + type2Count.get(TodoType.EXECUTABLE), + type2Count.get(TodoType.COPIED_TO_ME))); } PendingMessageStatisticResponseV2 resp = new PendingMessageStatisticResponseV2(); resp.addGroupStats(stats); From 1f12fd534804f1578fc5ad5be1faa0962d0fa8d5 Mon Sep 17 00:00:00 2001 From: yanglin Date: Thu, 11 Jul 2024 14:18:38 +0800 Subject: [PATCH 6/7] REQ-2599: cache path for better performance --- .../axzo/msg/center/message/service/group/NodeWrapper.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/group/NodeWrapper.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/group/NodeWrapper.java index 6bd4fead..b0ed0148 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/group/NodeWrapper.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/group/NodeWrapper.java @@ -19,7 +19,10 @@ public class NodeWrapper implements NodeValue { private final MessageGroupNode node; private final Map code2Id; - // cache path for better performance + /** + * cache path for better performance + * visit via {@link RootNodeWrapper#getPath} + */ @Setter(AccessLevel.PACKAGE) @Getter(AccessLevel.PACKAGE) private String cachedPath; From 647bd1c10ef3dd2d540c0f125267772e847ca189 Mon Sep 17 00:00:00 2001 From: yanglin Date: Thu, 11 Jul 2024 14:19:42 +0800 Subject: [PATCH 7/7] REQ-2599: cache path for better performance --- .../axzo/msg/center/message/service/group/RootNodeWrapper.java | 1 + 1 file changed, 1 insertion(+) diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/group/RootNodeWrapper.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/group/RootNodeWrapper.java index c2f0d10c..745384cf 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/group/RootNodeWrapper.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/group/RootNodeWrapper.java @@ -54,6 +54,7 @@ public class RootNodeWrapper { } private String getPathImpl(ValueNode node) { + // a1912618861c4dab8aaee954069762a0:a1912618861c4dab8aaee954069762a1:a1912618861c4dab8aaee954069762a2 // code是uuid去掉-, 一般层级为3, 通过冒号分割, 所有长度为: 32 * 3 + 2 = 98 // 初始长度直接设置为98, 避免频繁扩容 StringBuilder builder = new StringBuilder(98);