Przeglądaj źródła

1. SQL 同步最新
2. 优化 trace 相关的逻辑

YunaiV 3 lat temu
rodzic
commit
6f6e8777e7

+ 2 - 1
README.md

@@ -56,7 +56,8 @@
 |  | MySQL 监控 | 监视当前系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈 |
 |  | Redis 监控 |监控 Redis 数据库的使用情况,使用的 Redis Key 管理 |
 | 🚀 |Java 监控 | 基于 Spring Boot Admin 实现 Java 应用的监控 |
-| 🚀 | 链路追踪 | 基于 SkyWalking 实现性能监控,特别是链路的追踪 |
+| 🚀 | 链路追踪 | 接入 SkyWalking 组件,实现链路追踪 |
+| 🚀 | 日志中心 | 接入 SkyWalking 组件,实现日志中心 |
 | 🚀 | 分布式锁 | 基于 Redis 实现分布式锁,满足并发场景 |
 | 🚀 | 幂等组件 | 基于 Redis 实现幂等组件,解决重复请求问题 |
 | 🚀 | 服务保障 | 基于 Resilience4j 实现服务的稳定性,包括限流、熔断等功能 |

Plik diff jest za duży
+ 254 - 2
sql/ruoyi-vue-pro.sql


+ 8 - 3
src/main/java/cn/iocoder/dashboard/framework/tracer/core/aop/BizTraceAspect.java

@@ -1,8 +1,9 @@
 package cn.iocoder.dashboard.framework.tracer.core.aop;
 
+import cn.hutool.core.map.MapUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.iocoder.dashboard.framework.tracer.core.annotation.BizTrace;
-import cn.iocoder.dashboard.util.sping.SpElUtil;
+import cn.iocoder.dashboard.util.sping.SpringExpressionUtils;
 import io.opentracing.Span;
 import io.opentracing.Tracer;
 import lombok.extern.slf4j.Slf4j;
@@ -11,6 +12,9 @@ import org.aspectj.lang.annotation.Around;
 import org.aspectj.lang.annotation.Aspect;
 
 import javax.annotation.Resource;
+import java.util.Map;
+
+import static java.util.Arrays.asList;
 
 /**
  * {@link BizTrace} 切面,记录业务链路
@@ -55,8 +59,9 @@ public class BizTraceAspect {
 
     private void setBizTag(Span span, ProceedingJoinPoint joinPoint, BizTrace trace) {
         try {
-            span.setTag(BizTrace.TYPE_TAG, StrUtil.toString(SpElUtil.analysisSpEl(trace.type(), joinPoint)));
-            span.setTag(BizTrace.ID_TAG, StrUtil.toString(SpElUtil.analysisSpEl(trace.id(), joinPoint)));
+            Map<String, Object> result = SpringExpressionUtils.parseExpressions(joinPoint, asList(trace.type(), trace.id()));
+            span.setTag(BizTrace.TYPE_TAG, MapUtil.getStr(result, trace.type()));
+            span.setTag(BizTrace.ID_TAG, MapUtil.getStr(result, trace.id()));
         } catch (Exception ex) {
             log.error("[setBizTag][解析 bizType 与 bizId 发生异常]", ex);
         }

+ 1 - 1
src/main/java/cn/iocoder/dashboard/modules/tool/controller/test/ToolTestDemoController.java

@@ -79,7 +79,7 @@ public class ToolTestDemoController {
     @ApiImplicitParam(name = "ids", value = "编号列表", required = true, dataTypeClass = List.class)
     @PreAuthorize("@ss.hasPermission('tool:test-demo:query')")
 //    @RateLimiter(name = "backendA")
-    @BizTrace(id = "1", type = "'user'")
+    @BizTrace(id = "#ids", type = "'user'")
     public CommonResult<List<ToolTestDemoRespVO>> getTestDemoList(@RequestParam("ids") Collection<Long> ids) {
         List<ToolTestDemoDO> list = testDemoService.getTestDemoList(ids);
         return success(ToolTestDemoConvert.INSTANCE.convertList(list));

+ 0 - 70
src/main/java/cn/iocoder/dashboard/util/sping/SpElUtil.java

@@ -1,70 +0,0 @@
-package cn.iocoder.dashboard.util.sping;
-
-import org.aspectj.lang.ProceedingJoinPoint;
-import org.aspectj.lang.reflect.MethodSignature;
-import org.springframework.core.DefaultParameterNameDiscoverer;
-import org.springframework.expression.EvaluationContext;
-import org.springframework.expression.Expression;
-import org.springframework.expression.spel.standard.SpelExpressionParser;
-import org.springframework.expression.spel.support.StandardEvaluationContext;
-
-import java.lang.reflect.Method;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * SpEl解析类
- *
- * @author mashu
- */
-public class SpElUtil {
-
-    private static SpelExpressionParser parser = new SpelExpressionParser();
-    private static DefaultParameterNameDiscoverer nameDiscoverer = new DefaultParameterNameDiscoverer();
-
-    private SpElUtil() {
-    }
-
-    /**
-     * 解析切面SpEL
-     *
-     * @param spElString 表达式
-     * @param joinPoint  切面点
-     * @return 执行界面
-     */
-    public static Object analysisSpEl(String spElString, ProceedingJoinPoint joinPoint) {
-        // 通过joinPoint获取被注解方法
-        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
-        Method method = methodSignature.getMethod();
-        // 使用spring的DefaultParameterNameDiscoverer获取方法形参名数组
-        String[] paramNames = nameDiscoverer.getParameterNames(method);
-        // 解析过后的Spring表达式对象
-        Expression expression = parser.parseExpression(spElString);
-        // spring的表达式上下文对象
-        EvaluationContext context = new StandardEvaluationContext();
-        // 通过joinPoint获取被注解方法的形参
-        Object[] args = joinPoint.getArgs();
-        // 给上下文赋值
-        for (int i = 0; i < args.length; i++) {
-            context.setVariable(paramNames[i], args[i]);
-        }
-        return expression.getValue(context);
-    }
-
-    /**
-     * 批量解析切面SpEL
-     *
-     * @param spElStrings 表达式
-     * @param joinPoint   切面点
-     * @return 执行界面
-     */
-    public static Map<String, Object> analysisSpEls(List<String> spElStrings, ProceedingJoinPoint joinPoint) {
-        if (null == spElStrings) {
-            return null;
-        }
-        Map<String, Object> resultMap = new HashMap<>(spElStrings.size());
-        spElStrings.forEach(expression -> resultMap.put(expression, analysisSpEl(expression, joinPoint)));
-        return resultMap;
-    }
-}

+ 46 - 46
src/test/java/cn/iocoder/dashboard/util/AopTargetUtils.java → src/main/java/cn/iocoder/dashboard/util/sping/SpringAopUtils.java

@@ -1,46 +1,46 @@
-package cn.iocoder.dashboard.util;
-
-import cn.hutool.core.bean.BeanUtil;
-import org.springframework.aop.framework.AdvisedSupport;
-import org.springframework.aop.framework.AopProxy;
-import org.springframework.aop.support.AopUtils;
-
-/**
- * Spring AOP 工具类
- *
- * 参考波克尔 http://www.bubuko.com/infodetail-3471885.html 实现
- */
-public class AopTargetUtils {
-
-    /**
-     * 获取代理的目标对象
-     *
-     * @param proxy 代理对象
-     * @return 目标对象
-     */
-    public static Object getTarget(Object proxy) throws Exception {
-        // 不是代理对象
-        if (!AopUtils.isAopProxy(proxy)) {
-            return proxy;
-        }
-        // Jdk 代理
-        if (AopUtils.isJdkDynamicProxy(proxy)) {
-            return getJdkDynamicProxyTargetObject(proxy);
-        }
-        // Cglib 代理
-        return getCglibProxyTargetObject(proxy);
-    }
-
-    private static Object getCglibProxyTargetObject(Object proxy) throws Exception {
-        Object dynamicAdvisedInterceptor = BeanUtil.getFieldValue(proxy, "CGLIB$CALLBACK_0");
-        AdvisedSupport advisedSupport = (AdvisedSupport) BeanUtil.getFieldValue(dynamicAdvisedInterceptor, "advised");
-        return advisedSupport.getTargetSource().getTarget();
-    }
-
-    private static Object getJdkDynamicProxyTargetObject(Object proxy) throws Exception {
-        AopProxy aopProxy = (AopProxy) BeanUtil.getFieldValue(proxy, "h");
-        AdvisedSupport advisedSupport = (AdvisedSupport) BeanUtil.getFieldValue(aopProxy, "advised");
-        return advisedSupport.getTargetSource().getTarget();
-    }
-
-}
+package cn.iocoder.dashboard.util.sping;
+
+import cn.hutool.core.bean.BeanUtil;
+import org.springframework.aop.framework.AdvisedSupport;
+import org.springframework.aop.framework.AopProxy;
+import org.springframework.aop.support.AopUtils;
+
+/**
+ * Spring AOP 工具类
+ *
+ * 参考波克尔 http://www.bubuko.com/infodetail-3471885.html 实现
+ */
+public class SpringAopUtils {
+
+    /**
+     * 获取代理的目标对象
+     *
+     * @param proxy 代理对象
+     * @return 目标对象
+     */
+    public static Object getTarget(Object proxy) throws Exception {
+        // 不是代理对象
+        if (!AopUtils.isAopProxy(proxy)) {
+            return proxy;
+        }
+        // Jdk 代理
+        if (AopUtils.isJdkDynamicProxy(proxy)) {
+            return getJdkDynamicProxyTargetObject(proxy);
+        }
+        // Cglib 代理
+        return getCglibProxyTargetObject(proxy);
+    }
+
+    private static Object getCglibProxyTargetObject(Object proxy) throws Exception {
+        Object dynamicAdvisedInterceptor = BeanUtil.getFieldValue(proxy, "CGLIB$CALLBACK_0");
+        AdvisedSupport advisedSupport = (AdvisedSupport) BeanUtil.getFieldValue(dynamicAdvisedInterceptor, "advised");
+        return advisedSupport.getTargetSource().getTarget();
+    }
+
+    private static Object getJdkDynamicProxyTargetObject(Object proxy) throws Exception {
+        AopProxy aopProxy = (AopProxy) BeanUtil.getFieldValue(proxy, "h");
+        AdvisedSupport advisedSupport = (AdvisedSupport) BeanUtil.getFieldValue(aopProxy, "advised");
+        return advisedSupport.getTargetSource().getTarget();
+    }
+
+}

+ 82 - 0
src/main/java/cn/iocoder/dashboard/util/sping/SpringExpressionUtils.java

@@ -0,0 +1,82 @@
+package cn.iocoder.dashboard.util.sping;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.map.MapUtil;
+import cn.hutool.core.util.ArrayUtil;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.springframework.core.DefaultParameterNameDiscoverer;
+import org.springframework.core.ParameterNameDiscoverer;
+import org.springframework.expression.EvaluationContext;
+import org.springframework.expression.ExpressionParser;
+import org.springframework.expression.spel.standard.SpelExpressionParser;
+import org.springframework.expression.spel.support.StandardEvaluationContext;
+
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Spring EL 表达式的工具类
+ *
+ * @author mashu
+ */
+public class SpringExpressionUtils {
+
+    private static final ExpressionParser EXPRESSION_PARSER = new SpelExpressionParser();
+    private static final ParameterNameDiscoverer PARAMETER_NAME_DISCOVERER = new DefaultParameterNameDiscoverer();
+
+    private SpringExpressionUtils() {
+    }
+
+    /**
+     * 从切面中,单个解析 EL 表达式的结果
+     *
+     * @param joinPoint  切面点
+     * @param expressionString EL 表达式数组
+     * @return 执行界面
+     */
+    public static Object parseExpression(ProceedingJoinPoint joinPoint, String expressionString) {
+        Map<String, Object> result = parseExpressions(joinPoint, Collections.singletonList(expressionString));
+        return result.get(expressionString);
+    }
+
+    /**
+     * 从切面中,批量解析 EL 表达式的结果
+     *
+     * @param joinPoint   切面点
+     * @param expressionStrings EL 表达式数组
+     * @return 结果,key 为表达式,value 为对应值
+     */
+    public static Map<String, Object> parseExpressions(ProceedingJoinPoint joinPoint, List<String> expressionStrings) {
+        // 如果为空,则不进行解析
+        if (CollUtil.isEmpty(expressionStrings)) {
+            return MapUtil.newHashMap();
+        }
+
+        // 第一步,构建解析的上下文 EvaluationContext
+        // 通过 joinPoint 获取被注解方法
+        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
+        Method method = methodSignature.getMethod();
+        // 使用 spring 的 ParameterNameDiscoverer 获取方法形参名数组
+        String[] paramNames = PARAMETER_NAME_DISCOVERER.getParameterNames(method);
+        // Spring 的表达式上下文对象
+        EvaluationContext context = new StandardEvaluationContext();
+        // 给上下文赋值
+        if (ArrayUtil.isNotEmpty(paramNames)) {
+            Object[] args = joinPoint.getArgs();
+            for (int i = 0; i < paramNames.length; i++) {
+                context.setVariable(paramNames[i], args[i]);
+            }
+        }
+
+        // 第二步,逐个参数解析
+        Map<String, Object> result = MapUtil.newHashMap(expressionStrings.size(), true);
+        expressionStrings.forEach(key -> {
+            Object value = EXPRESSION_PARSER.parseExpression(key).getValue(context);
+            result.put(key, value);
+        });
+        return result;
+    }
+}

+ 4 - 4
src/test/java/cn/iocoder/dashboard/modules/system/service/permission/SysMenuServiceTest.java

@@ -12,7 +12,7 @@ import cn.iocoder.dashboard.modules.system.dal.mysql.permission.SysMenuMapper;
 import cn.iocoder.dashboard.modules.system.enums.permission.MenuTypeEnum;
 import cn.iocoder.dashboard.modules.system.mq.producer.permission.SysMenuProducer;
 import cn.iocoder.dashboard.modules.system.service.permission.impl.SysMenuServiceImpl;
-import cn.iocoder.dashboard.util.AopTargetUtils;
+import cn.iocoder.dashboard.util.sping.SpringAopUtils;
 import cn.iocoder.dashboard.util.RandomUtils;
 import cn.iocoder.dashboard.util.object.ObjectUtils;
 import com.google.common.collect.Multimap;
@@ -57,7 +57,7 @@ public class SysMenuServiceTest extends BaseDbUnitTest {
         sysMenuService.initLocalCache();
 
         // 获取代理对象
-        SysMenuServiceImpl target = (SysMenuServiceImpl) AopTargetUtils.getTarget(sysMenuService);
+        SysMenuServiceImpl target = (SysMenuServiceImpl) SpringAopUtils.getTarget(sysMenuService);
 
         Map<Long, SysMenuDO> menuCache =
                 (Map<Long, SysMenuDO>) BeanUtil.getFieldValue(target, "menuCache");
@@ -227,7 +227,7 @@ public class SysMenuServiceTest extends BaseDbUnitTest {
     public void testListMenusFromCache_success() throws Exception {
         Map<Long, SysMenuDO> mockCacheMap = new HashMap<>();
         //获取代理对象
-        SysMenuServiceImpl target = (SysMenuServiceImpl) AopTargetUtils.getTarget(sysMenuService);
+        SysMenuServiceImpl target = (SysMenuServiceImpl) SpringAopUtils.getTarget(sysMenuService);
         BeanUtil.setFieldValue(target, "menuCache", mockCacheMap);
 
         Map<Long, SysMenuDO> idMenuMap = new HashMap<>();
@@ -256,7 +256,7 @@ public class SysMenuServiceTest extends BaseDbUnitTest {
     public void testListMenusFromCache2_success() throws Exception {
         Map<Long, SysMenuDO> mockCacheMap = new HashMap<>();
         //获取代理对象
-        SysMenuServiceImpl target = (SysMenuServiceImpl) AopTargetUtils.getTarget(sysMenuService);
+        SysMenuServiceImpl target = (SysMenuServiceImpl) SpringAopUtils.getTarget(sysMenuService);
         BeanUtil.setFieldValue(target, "menuCache", mockCacheMap);
 
         Map<Long, SysMenuDO> idMenuMap = new HashMap<>();

+ 2 - 8
src/test/java/cn/iocoder/dashboard/modules/system/service/permission/SysRoleServiceTest.java

@@ -13,14 +13,8 @@ import cn.iocoder.dashboard.modules.system.dal.mysql.permission.SysRoleMapper;
 import cn.iocoder.dashboard.modules.system.enums.permission.SysRoleTypeEnum;
 import cn.iocoder.dashboard.modules.system.mq.producer.permission.SysRoleProducer;
 import cn.iocoder.dashboard.modules.system.service.permission.impl.SysRoleServiceImpl;
-import cn.iocoder.dashboard.util.AopTargetUtils;
-import cn.iocoder.dashboard.util.AssertUtils;
-import cn.iocoder.dashboard.util.RandomUtils;
-import cn.iocoder.dashboard.util.object.ObjectUtils;
-import com.google.common.collect.Sets;
-import org.junit.jupiter.api.Assertions;
+import cn.iocoder.dashboard.util.sping.SpringAopUtils;
 import org.junit.jupiter.api.Test;
-import org.mockito.Mockito;
 import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.context.annotation.Import;
 
@@ -63,7 +57,7 @@ public class SysRoleServiceTest extends BaseDbUnitTest {
 
         //断言
         //获取代理对象
-        SysRoleServiceImpl target = (SysRoleServiceImpl) AopTargetUtils.getTarget(sysRoleService);
+        SysRoleServiceImpl target = (SysRoleServiceImpl) SpringAopUtils.getTarget(sysRoleService);
 
         Map<Long, SysRoleDO> roleCache = (Map<Long, SysRoleDO>) BeanUtil.getFieldValue(target, "roleCache");
         assertPojoEquals(roleDO1, roleCache.get(roleDO1.getId()));

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików