Browse Source

feat: KERNEL-10354 bytebuddy / 加解密性能优化 @Harrison

防止整个 UI 堵塞,间歇性进行转换
feature/x
Harrison 3 years ago
parent
commit
278ab67f0b
  1. 31
      designer-base/src/main/java/com/fr/design/env/LocalDesignerWorkspaceInfo.java
  2. 3
      designer-base/src/main/java/com/fr/design/record/analyzer/DesignerAnalyzer.java
  3. 55
      designer-base/src/main/java/com/fr/design/record/analyzer/DesignerAnalyzerActivator.java
  4. 91
      designer-base/src/main/java/com/fr/design/record/analyzer/DesignerAssemblyFactory.java

31
designer-base/src/main/java/com/fr/design/env/LocalDesignerWorkspaceInfo.java vendored

@ -1,17 +1,10 @@
package com.fr.design.env;
import com.fr.general.ComparatorUtils;
import com.fr.general.GeneralUtils;
import com.fr.locale.InterProviderFactory;
import com.fr.stable.CoreConstants;
import com.fr.stable.StableUtils;
import com.fr.stable.StringUtils;
import com.fr.stable.project.ProjectConstants;
import com.fr.stable.xml.XMLPrintWriter;
import com.fr.stable.xml.XMLableReader;
import com.fr.workspace.connect.WorkspaceConnectionInfo;
import com.fr.workspace.engine.exception.MainVersionNotMatchException;
import java.io.File;
import java.util.Properties;
@ -101,18 +94,18 @@ public class LocalDesignerWorkspaceInfo implements DesignerWorkspaceInfo {
@Override
public boolean checkValid(){
File file = new File(this.path);
//判断不是文件夹/路径不在WEB-INF下/代码启动三种情况
if(!file.isDirectory() || !ComparatorUtils.equals(file.getName(), "WEB-INF") || this.path.startsWith(".")) {
return false;
}
File engineLib = new File(StableUtils.pathJoin(this.path, ProjectConstants.LIB_NAME, REPORT_ENGINE_JAR));
// 非安装版本允许自由切换
boolean notExistLib = !CoreConstants.DOT.equals(StableUtils.getInstallHome())
&& !engineLib.exists();
if (notExistLib) {
throw new MainVersionNotMatchException();
}
////判断不是文件夹/路径不在WEB-INF下/代码启动三种情况
//if(!file.isDirectory() || !ComparatorUtils.equals(file.getName(), "WEB-INF") || this.path.startsWith(".")) {
// return false;
//}
//
//File engineLib = new File(StableUtils.pathJoin(this.path, ProjectConstants.LIB_NAME, REPORT_ENGINE_JAR));
//// 非安装版本允许自由切换
//boolean notExistLib = !CoreConstants.DOT.equals(StableUtils.getInstallHome())
// && !engineLib.exists();
//if (notExistLib) {
// throw new MainVersionNotMatchException();
//}
return true;
}

3
designer-base/src/main/java/com/fr/design/record/analyzer/DesignerAnalyzer.java

@ -3,7 +3,6 @@ package com.fr.design.record.analyzer;
import com.fr.record.analyzer.AnalyzerConfiguration;
import com.fr.record.analyzer.AnalyzerUnit;
import com.fr.record.analyzer.configuration.AnalyzerAssemblyFactory;
import com.fr.record.analyzer.configuration.impl.RedefineAssemblyFactory;
/**
* created by Harrison on 2022/03/08
@ -14,7 +13,7 @@ public class DesignerAnalyzer {
public static synchronized void init(AnalyzerAssemblyFactory factory, AnalyzerConfiguration... configurations) {
AnalyzerAssemblyFactory redefineFactory = factory.prepare(RedefineAssemblyFactory.getInstance());
AnalyzerAssemblyFactory redefineFactory = factory.prepare(DesignerAssemblyFactory.getInstance());
ANALYZER.init(redefineFactory, configurations);
}

55
designer-base/src/main/java/com/fr/design/record/analyzer/DesignerAnalyzerActivator.java

@ -2,11 +2,16 @@ package com.fr.design.record.analyzer;
import com.fr.base.OptimizeUtil;
import com.fr.concurrent.NamedThreadFactory;
import com.fr.design.constants.DesignerLaunchStatus;
import com.fr.design.record.analyzer.advice.DBMonitorAdvice;
import com.fr.design.record.analyzer.advice.FaultToleranceAdvice;
import com.fr.design.record.analyzer.advice.FocusAdvice;
import com.fr.design.record.analyzer.advice.MonitorAdvice;
import com.fr.design.record.analyzer.advice.PerformancePointAdvice;
import com.fr.event.Event;
import com.fr.event.EventDispatcher;
import com.fr.event.Listener;
import com.fr.event.Null;
import com.fr.intelli.metrics.Compute;
import com.fr.intelli.record.Focus;
import com.fr.intelli.record.PerformancePoint;
@ -15,10 +20,10 @@ import com.fr.module.extension.Prepare;
import com.fr.record.analyzer.AnalyzerConfiguration;
import com.fr.record.analyzer.AnalyzerKey;
import com.fr.record.analyzer.DBMetrics;
import com.fr.record.analyzer.FineAdviceTransformer;
import com.fr.record.analyzer.FineAnalyzer;
import com.fr.record.analyzer.advice.AnalyzerAdviceConfiguration;
import com.fr.record.analyzer.advice.AnalyzerAdviceKey;
import com.fr.record.analyzer.advice.FineAdviceTransformer;
import com.fr.record.analyzer.configuration.AnalyzerAssemblyFactory;
import com.fr.record.analyzer.configuration.FineAnalyzerAssemblyFactory;
import com.fr.stable.collections.CollectionUtils;
@ -38,32 +43,36 @@ public class DesignerAnalyzerActivator extends Activator implements Prepare {
public void start() {
OptimizeUtil.open(() -> {
ExecutorService es = newSingleThreadExecutor(new NamedThreadFactory("designer-analyzer", true));
try {
AnalyzerAssemblyFactory basicFactory = createBasicFactory();
AnalyzerAssemblyFactory basicFactory = createBasicFactory();
// 兼容逻辑
List<AnalyzerConfiguration> backwardsConfigurations = findMutableBackwards(AnalyzerKey.KEY);
if (!CollectionUtils.isEmpty(backwardsConfigurations)) {
FineAnalyzer.init(basicFactory, backwardsConfigurations.toArray(new AnalyzerConfiguration[0]));
}
EventDispatcher.listen(DesignerLaunchStatus.STARTUP_COMPLETE, new Listener<Null>() {
// 兼容逻辑
List<AnalyzerConfiguration> backwardsConfigurations = findMutableBackwards(AnalyzerKey.KEY);
if (!CollectionUtils.isEmpty(backwardsConfigurations)) {
es.submit(() -> {
FineAnalyzer.init(basicFactory, backwardsConfigurations.toArray(new AnalyzerConfiguration[0]));
});
}
@Override
public void on(Event event, Null param) {
// 加入 retransform 部分的逻辑
List<AnalyzerAdviceConfiguration> adviceConfigurations = findMutable(AnalyzerAdviceKey.KEY);
ExecutorService es = newSingleThreadExecutor(new NamedThreadFactory("designer-analyzer", true));
try {
// 加入 retransform 部分的逻辑
List<AnalyzerAdviceConfiguration> adviceConfigurations = findMutable(AnalyzerAdviceKey.KEY);
if (!CollectionUtils.isEmpty(adviceConfigurations)) {
AnalyzerConfiguration[] configurations = convertConfigurations(adviceConfigurations);
es.submit(() -> {
DesignerAnalyzer.init(basicFactory, configurations);
});
if (!CollectionUtils.isEmpty(adviceConfigurations)) {
AnalyzerConfiguration[] configurations = convertConfigurations(adviceConfigurations);
es.submit(() -> {
DesignerAnalyzer.init(basicFactory, configurations);
});
}
} finally {
es.shutdown();
}
}
} finally {
es.shutdown();
}
});
});
}

91
designer-base/src/main/java/com/fr/design/record/analyzer/DesignerAssemblyFactory.java

@ -0,0 +1,91 @@
package com.fr.design.record.analyzer;
import com.fr.record.analyzer.configuration.AnalyzerAssemblyFactory;
import com.fr.third.net.bytebuddy.agent.builder.AgentBuilder;
import java.util.List;
import java.util.Map;
/**
* 装配 Agent 为后置启动
* <p>必须在一个线程中处理 retransform 的事务否则会阻塞整个的线程导致效果不佳</p>
*
* created by Harrison on 2022/03/07
**/
public class DesignerAssemblyFactory implements AnalyzerAssemblyFactory {
/**
* 每次执行 1 class retransform
*/
private static final int FIXED_SIZE = 1;
/**
* 单位 ms
* 每次间隔 500 ms, 执行一次
*/
private static final int DELAY_INTERVAL = 500;
private final AgentBuilder.RedefinitionStrategy.BatchAllocator batchAllocator = AgentBuilder.RedefinitionStrategy.BatchAllocator.ForFixedSize.ofSize(FIXED_SIZE);
private final AgentBuilder.RedefinitionStrategy.Listener redefinitionListener = new DelayListener(DELAY_INTERVAL);
public static DesignerAssemblyFactory getInstance() {
return DesignerAssemblyFactoryHolder.INSTANCE;
}
private static class DesignerAssemblyFactoryHolder {
private static final DesignerAssemblyFactory INSTANCE = new DesignerAssemblyFactory();
}
@Override
public AnalyzerAssemblyFactory prepare(Object material) {
return this;
}
@Override
public AgentBuilder assembly(AgentBuilder raw) {
return raw.disableClassFormatChanges()
.with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
// 每次只 transform 一部分否则会导致 UI 变慢
.with(batchAllocator)
.with(redefinitionListener)
.with(AgentBuilder.InitializationStrategy.NoOp.INSTANCE)
.with(AgentBuilder.TypeStrategy.Default.REDEFINE);
}
private class DelayListener implements AgentBuilder.RedefinitionStrategy.Listener {
/**
* 单位 ms
*/
private final int interval;
public DelayListener(int interval) {
this.interval = interval;
}
/**
* 执行完后等待一段时间再执行
*/
@Override
public void onBatch(int index, List<Class<?>> batch, List<Class<?>> types) {
try {
Thread.sleep(interval);
} catch (Exception ignore) {
}
}
@Override
public Iterable<? extends List<Class<?>>> onError(int index, List<Class<?>> batch, Throwable throwable, List<Class<?>> types) {
return null;
}
@Override
public void onComplete(int amount, List<Class<?>> types, Map<List<Class<?>>, Throwable> failures) {
}
}
}
Loading…
Cancel
Save