diff --git a/eden-components/eden-dependencies/pom.xml b/eden-components/eden-dependencies/pom.xml
index da637347..811e2173 100644
--- a/eden-components/eden-dependencies/pom.xml
+++ b/eden-components/eden-dependencies/pom.xml
@@ -113,9 +113,9 @@
8.0.32
3.1.1
3.42.0.0
- 3.5.6
- 2.0.3
- 2.1.1
+ 3.5.16
+ 2.1.2
+ 2.1.4
3.5.7
5.3.1
1.2.4
@@ -888,6 +888,16 @@
arthas-spring-boot-starter
${arthas.version}
+
+ com.taobao.arthas
+ arthas-spy
+ ${arthas.version}
+
+
+ com.taobao.arthas
+ arthas-agent-attach
+ ${arthas.version}
+
diff --git a/eden-components/eden-solutions/eden-distributed-uid/src/main/java/org/ylzl/eden/distributed/uid/integration/leaf/LeafSegmentGenerator.java b/eden-components/eden-solutions/eden-distributed-uid/src/main/java/org/ylzl/eden/distributed/uid/integration/leaf/LeafSegmentGenerator.java
index 85a73ca7..6e7a229d 100644
--- a/eden-components/eden-solutions/eden-distributed-uid/src/main/java/org/ylzl/eden/distributed/uid/integration/leaf/LeafSegmentGenerator.java
+++ b/eden-components/eden-solutions/eden-distributed-uid/src/main/java/org/ylzl/eden/distributed/uid/integration/leaf/LeafSegmentGenerator.java
@@ -135,7 +135,7 @@ private SpringLiquibase buildLiquibase(DataSource dataSource) {
}
private void updateCacheFromDb() {
- log.debug("Update cache from db");
+ log.debug("Leaf update cache from db");
try {
List dbTags = leafAllocDAO.getAllTags();
if (dbTags == null || dbTags.isEmpty()) {
@@ -155,24 +155,24 @@ private void updateCacheFromDb() {
segment.setMax(0);
segment.setStep(0);
cache.put(tag, buffer);
- log.debug("Add tag {} from db to IdCache", tag);
+ log.debug("Leaf add tag {} from db to IdCache", tag);
}
for (String tag : dbTags) {
removeTagsSet.remove(tag);
}
for (String tag : removeTagsSet) {
cache.remove(tag);
- log.debug("Remove tag {} from IdCache", tag);
+ log.debug("Leaf remove tag {} from IdCache", tag);
}
} catch (Exception e) {
- log.warn("Update cache from db exception", e);
+ log.warn("Leaf update cache from db exception", e);
}
}
private void updateCacheFromDbAtEveryMinute() {
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor(r -> {
Thread t = new Thread(r);
- t.setName("check-idCache-thread");
+ t.setName("leaf-check-id-cache-thread");
t.setDaemon(true);
return t;
});
@@ -229,9 +229,9 @@ private long getIdFromSegmentBuffer(final SegmentBuffer buffer) {
try {
updateSegmentFromDb(buffer.getKey(), next);
updateOk = true;
- log.info("Update segment {} from db {}", buffer.getKey(), next);
+ log.info("Leaf update segment {} from db {}", buffer.getKey(), next);
} catch (Exception e) {
- log.error("Update segment {} from db {} error", buffer.getKey(), e);
+ log.error("Leaf update segment {} from db {} error", buffer.getKey(), e);
} finally {
if (updateOk) {
buffer.wLock().lock();
diff --git a/eden-components/eden-spring-boot-starters/eden-arthas-spring-boot-starter/pom.xml b/eden-components/eden-spring-boot-starters/eden-arthas-spring-boot-starter/pom.xml
index 381bdb8c..27449b2d 100644
--- a/eden-components/eden-spring-boot-starters/eden-arthas-spring-boot-starter/pom.xml
+++ b/eden-components/eden-spring-boot-starters/eden-arthas-spring-boot-starter/pom.xml
@@ -55,5 +55,13 @@
com.taobao.arthas
arthas-spring-boot-starter
+
+ com.taobao.arthas
+ arthas-spy
+
+
+ com.taobao.arthas
+ arthas-agent-attach
+
diff --git a/eden-components/eden-spring-boot-starters/eden-arthas-spring-boot-starter/src/main/java/org/ylzl/eden/arthas/spring/boot/attach/CustomArthasAgent.java b/eden-components/eden-spring-boot-starters/eden-arthas-spring-boot-starter/src/main/java/org/ylzl/eden/arthas/spring/boot/attach/CustomArthasAgent.java
new file mode 100644
index 00000000..adf01aad
--- /dev/null
+++ b/eden-components/eden-spring-boot-starters/eden-arthas-spring-boot-starter/src/main/java/org/ylzl/eden/arthas/spring/boot/attach/CustomArthasAgent.java
@@ -0,0 +1,155 @@
+package org.ylzl.eden.arthas.spring.boot.attach;
+
+import com.taobao.arthas.agent.attach.ArthasAgent;
+import com.taobao.arthas.agent.attach.AttachArthasClassloader;
+import lombok.extern.slf4j.Slf4j;
+import net.bytebuddy.agent.ByteBuddyAgent;
+import org.zeroturnaround.zip.ZipUtil;
+
+import java.arthas.SpyAPI;
+import java.io.File;
+import java.lang.instrument.Instrumentation;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+/**
+ * 自定义 ArthasAgent
+ *
+ * @author gyl
+ * @since 2.4.13
+ */
+@Slf4j
+public class CustomArthasAgent extends ArthasAgent {
+
+ private static final int TEMP_DIR_ATTEMPTS = 10000;
+
+ private static final String ARTHAS_CORE_JAR = "arthas-core.jar";
+ private static final String ARTHAS_BOOTSTRAP = "com.taobao.arthas.core.server.ArthasBootstrap";
+ private static final String GET_INSTANCE = "getInstance";
+ private static final String IS_BIND = "isBind";
+
+ private static final Pattern ARTHAS_DIR_PATTERN = Pattern.compile("^arthas-(\\d{13})-.*$");
+ private static final String ARTHAS_BIN_ZIP = "arthas-bin.zip";
+ private static final String DESTROY = "destroy";
+
+ private String errorMessage;
+
+ private Map configMap = new HashMap();
+ private String arthasHome;
+ private boolean slientInit;
+ private Instrumentation instrumentation;
+
+ private Class> bootstrapClass;
+ private Object bootstrap;
+
+ public CustomArthasAgent() {
+ this(null, null, false, null);
+ }
+
+ public CustomArthasAgent(Map configMap) {
+ this(configMap, null, false, null);
+ }
+
+ public CustomArthasAgent(String arthasHome) {
+ this(null, arthasHome, false, null);
+ }
+
+ public CustomArthasAgent(Map configMap, String arthasHome, boolean slientInit,
+ Instrumentation instrumentation) {
+ if (configMap != null) {
+ this.configMap = configMap;
+ }
+
+ this.arthasHome = arthasHome;
+ this.slientInit = slientInit;
+ this.instrumentation = instrumentation;
+ }
+
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+
+ @Override
+ public void init() throws IllegalStateException {
+ // 尝试判断arthas是否已在运行,如果是的话,直接就退出
+ try {
+ Class.forName("java.arthas.SpyAPI"); // 加载不到会抛异常
+ if (SpyAPI.isInited()) {
+ return;
+ }
+ } catch (Throwable e) {
+ // ignore
+ }
+
+ try {
+ if (instrumentation == null) {
+ instrumentation = ByteBuddyAgent.install();
+ }
+
+ // 检查 arthasHome
+ if (arthasHome == null || arthasHome.trim().isEmpty()) {
+ // 解压出 arthasHome
+ URL coreJarUrl = this.getClass().getClassLoader().getResource("arthas-bin.zip");
+ if (coreJarUrl != null) {
+ File tempArthasDir = createTempDir();
+ ZipUtil.unpack(coreJarUrl.openStream(), tempArthasDir);
+ arthasHome = tempArthasDir.getAbsolutePath();
+ } else {
+ throw new IllegalArgumentException("can not getResources arthas-bin.zip from classloader: "
+ + this.getClass().getClassLoader());
+ }
+ }
+
+ // find arthas-core.jar
+ File arthasCoreJarFile = new File(arthasHome, ARTHAS_CORE_JAR);
+ if (!arthasCoreJarFile.exists()) {
+ throw new IllegalStateException("can not find arthas-core.jar under arthasHome: " + arthasHome);
+ }
+ AttachArthasClassloader arthasClassLoader = new AttachArthasClassloader(
+ new URL[] { arthasCoreJarFile.toURI().toURL() });
+
+ bootstrapClass = arthasClassLoader.loadClass(ARTHAS_BOOTSTRAP);
+ bootstrap = bootstrapClass.getMethod(GET_INSTANCE, Instrumentation.class, Map.class).invoke(null,
+ instrumentation, configMap);
+ boolean isBind = (Boolean) bootstrapClass.getMethod(IS_BIND).invoke(bootstrap);
+ if (!isBind) {
+ String errorMsg = "Arthas server port binding failed! Please check $HOME/logs/arthas/arthas.log for more details.";
+ throw new RuntimeException(errorMsg);
+ }
+ } catch (Throwable e) {
+ errorMessage = e.getMessage();
+ if (!slientInit) {
+ throw new IllegalStateException(e);
+ }
+ }
+ }
+
+ public void destroy() {
+ if (bootstrapClass == null) {
+ log.warn("Arthas is not already");
+ return;
+ }
+
+ try {
+ bootstrapClass.getMethod(DESTROY).invoke(bootstrap);
+ } catch (Throwable e) {
+ log.error(e.getMessage(), e);
+ }
+ }
+
+ private static File createTempDir() {
+ File baseDir = new File(System.getProperty("java.io.tmpdir"));
+ String baseName = "arthas-" + System.currentTimeMillis() + "-";
+
+ for (int counter = 0; counter < TEMP_DIR_ATTEMPTS; counter++) {
+ File tempDir = new File(baseDir, baseName + counter);
+ if (tempDir.mkdir()) {
+ return tempDir;
+ }
+ }
+ throw new IllegalStateException("Failed to create directory within " + TEMP_DIR_ATTEMPTS + " attempts (tried "
+ + baseName + "0 to " + baseName + (TEMP_DIR_ATTEMPTS - 1) + ')');
+ }
+}
diff --git a/eden-components/eden-spring-boot-starters/eden-arthas-spring-boot-starter/src/main/java/org/ylzl/eden/arthas/spring/boot/autoconfigure/ArthasAutoConfiguration.java b/eden-components/eden-spring-boot-starters/eden-arthas-spring-boot-starter/src/main/java/org/ylzl/eden/arthas/spring/boot/autoconfigure/ArthasAutoConfiguration.java
index 87b62340..9cf7e108 100644
--- a/eden-components/eden-spring-boot-starters/eden-arthas-spring-boot-starter/src/main/java/org/ylzl/eden/arthas/spring/boot/autoconfigure/ArthasAutoConfiguration.java
+++ b/eden-components/eden-spring-boot-starters/eden-arthas-spring-boot-starter/src/main/java/org/ylzl/eden/arthas/spring/boot/autoconfigure/ArthasAutoConfiguration.java
@@ -20,15 +20,15 @@
import com.alibaba.arthas.spring.ArthasProperties;
import com.alibaba.arthas.spring.StringUtils;
import com.taobao.arthas.agent.attach.ArthasAgent;
-import com.taobao.arthas.agent.attach.AttachArthasClassloader;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import net.bytebuddy.agent.ByteBuddyAgent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.autoconfigure.AutoConfigureBefore;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
@@ -36,19 +36,12 @@
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Role;
import org.springframework.core.env.Environment;
+import org.ylzl.eden.arthas.spring.boot.attach.CustomArthasAgent;
import org.ylzl.eden.arthas.spring.boot.env.SpringArthasProperties;
import org.ylzl.eden.spring.framework.bootstrap.constant.SpringProperties;
-import java.io.File;
-import java.lang.instrument.Instrumentation;
-import java.net.URL;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.*;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
+import java.util.HashMap;
+import java.util.Map;
/**
* Arthas 自动装配
@@ -56,12 +49,8 @@
* @author gyl
* @since 2.4.13
*/
-@ConditionalOnProperty(
- name = {"spring.arthas.enabled"},
- matchIfMissing = true
-)
-@AutoConfigureAfter(ArthasConfiguration.class)
-@EnableConfigurationProperties(SpringArthasProperties.class)
+@AutoConfigureBefore(ArthasConfiguration.class)
+@EnableConfigurationProperties({ SpringArthasProperties.class, ArthasProperties.class })
@RequiredArgsConstructor
@Slf4j
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
@@ -76,20 +65,6 @@ public class ArthasAutoConfiguration {
private static final String ARTHAS_AGENT_START_SUCCESS = "Arthas agent start success";
- private static final int TEMP_DIR_ATTEMPTS = 10000;
-
- private static final Pattern ARTHAS_DIR_PATTERN = Pattern.compile("^arthas-(\\d{13})-.*$");
-
- private static final String ARTHAS_BIN_ZIP = "arthas-bin.zip";
-
- private static final String ARTHAS_CORE_JAR = "arthas-core.jar";
-
- private static final String ARTHAS_BOOTSTRAP = "com.taobao.arthas.core.server.ArthasBootstrap";
-
- private static final String GET_INSTANCE = "getInstance";
-
- private static final String DESTROY = "destroy";
-
private final ApplicationContext applicationContext;
private final Environment environment;
@@ -103,6 +78,18 @@ public ArthasEnvironmentChangeListener arthasEnvironmentChangeListener(
environment, arthasProperties, arthasConfigMap);
}
+ @ConfigurationProperties(prefix = "arthas")
+ @ConditionalOnMissingBean(name = {"arthasConfigMap"})
+ @Primary
+ @Bean
+ public HashMap arthasConfigMap() {
+ return new HashMap();
+ }
+
+ @ConditionalOnProperty(
+ name = {"spring.arthas.enabled"},
+ matchIfMissing = true
+ )
@Primary
@Bean
public ArthasAgent arthasAgent(@Autowired @Qualifier(ARTHAS_CONFIG_MAP) Map arthasConfigMap) {
@@ -112,6 +99,7 @@ public ArthasAgent arthasAgent(@Autowired @Qualifier(ARTHAS_CONFIG_MAP) Map arthasConfigMap, Environment environment,
ArthasProperties arthasProperties) {
+ arthasConfigMap = StringUtils.removeDashKey(arthasConfigMap);
ArthasProperties.updateArthasConfigMapDefaultValue(arthasConfigMap);
String appName = environment.getProperty(SpringProperties.SPRING_APPLICATION_NAME);
@@ -124,87 +112,11 @@ public static ArthasAgent init(Map arthasConfigMap, Environment
mapWithPrefix.put(ARTHAS_PROPERTIES_PREFIX + entry.getKey(), entry.getValue());
}
- final ArthasAgent arthasAgent = new ArthasAgent(mapWithPrefix, arthasProperties.getHome(),
+ final ArthasAgent arthasAgent = new CustomArthasAgent(mapWithPrefix, arthasProperties.getHome(),
arthasProperties.isSlientInit(), null);
arthasAgent.init();
log.info(ARTHAS_AGENT_START_SUCCESS);
return arthasAgent;
}
-
- public static void destroy(Map arthasConfigMap,
- ArthasProperties arthasProperties) {
- String arthasHome = arthasProperties.getHome();
- try {
- Instrumentation instrumentation = ByteBuddyAgent.install();
-
- if (arthasHome == null || arthasHome.trim().isEmpty()) {
- ClassLoader classLoader = ArthasAgent.class.getClassLoader();
- URL coreJarUrl = classLoader.getResource(ARTHAS_BIN_ZIP);
- if (coreJarUrl != null) {
- File tempArthasDir = findTempDir();
- arthasHome = tempArthasDir.getAbsolutePath();
- } else {
- throw new IllegalArgumentException("can not getResources arthas-bin.zip from classloader: "
- + classLoader);
- }
- }
- File arthasCoreJarFile = new File(arthasHome, ARTHAS_CORE_JAR);
- if (!arthasCoreJarFile.exists()) {
- throw new IllegalArgumentException("can not find arthas-core.jar under arthasHome: {}" + arthasHome);
- }
- AttachArthasClassloader arthasClassLoader = new AttachArthasClassloader(
- new URL[] { arthasCoreJarFile.toURI().toURL() });
- Class> bootstrapClass = arthasClassLoader.loadClass(ARTHAS_BOOTSTRAP);
-
- Object bootstrap = bootstrapClass.getMethod(GET_INSTANCE, Instrumentation.class, Map.class)
- .invoke(null, instrumentation, arthasConfigMap);
- bootstrapClass.getMethod(DESTROY).invoke(bootstrap);
- } catch (Throwable e) {
- log.error(e.getMessage(), e);
- }
- }
-
- private static List listArthasDirs(File baseDir) {
- return Stream.of(baseDir.listFiles((dir, name) -> ARTHAS_DIR_PATTERN.matcher(name).matches()))
- .collect(Collectors.toList());
- }
-
- private static Date extractTimestamp(File dir) {
- Matcher matcher = ARTHAS_DIR_PATTERN.matcher(dir.getName());
- if (matcher.matches()) {
- String timestampStr = matcher.group(1);
- SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
- try {
- return sdf.parse(timestampStr);
- } catch (ParseException e) {
- throw new IllegalArgumentException("Invalid timestamp format in directory name: " + dir.getName(), e);
- }
- }
- return null;
- }
-
- private static File findLatestArthasDir(File baseDir) {
- List dirs = listArthasDirs(baseDir);
- if (!dirs.isEmpty()) {
- return dirs.stream()
- .max(Comparator.comparing(ArthasAutoConfiguration::extractTimestamp))
- .orElse(null);
- }
- return null;
- }
-
- public static File findTempDir() {
- File baseDir = new File(System.getProperty("java.io.tmpdir"));
- String baseName = "arthas-" + System.currentTimeMillis() + "-";
-
- // 尝试查找时间戳最大的以 "arthas-" 开头的目录
- File latestDir = findLatestArthasDir(baseDir);
- if (latestDir != null) {
- return latestDir;
- }
-
- throw new IllegalStateException("Failed to find directory within " + TEMP_DIR_ATTEMPTS
- + " attempts (tried " + baseName + "0 to " + baseName + (TEMP_DIR_ATTEMPTS - 1) + ')');
- }
}
diff --git a/eden-components/eden-spring-boot-starters/eden-arthas-spring-boot-starter/src/main/java/org/ylzl/eden/arthas/spring/boot/autoconfigure/ArthasEnvironmentChangeListener.java b/eden-components/eden-spring-boot-starters/eden-arthas-spring-boot-starter/src/main/java/org/ylzl/eden/arthas/spring/boot/autoconfigure/ArthasEnvironmentChangeListener.java
index 97a54c9e..def4fdca 100644
--- a/eden-components/eden-spring-boot-starters/eden-arthas-spring-boot-starter/src/main/java/org/ylzl/eden/arthas/spring/boot/autoconfigure/ArthasEnvironmentChangeListener.java
+++ b/eden-components/eden-spring-boot-starters/eden-arthas-spring-boot-starter/src/main/java/org/ylzl/eden/arthas/spring/boot/autoconfigure/ArthasEnvironmentChangeListener.java
@@ -17,7 +17,6 @@
package org.ylzl.eden.arthas.spring.boot.autoconfigure;
import com.alibaba.arthas.spring.ArthasProperties;
-import com.taobao.arthas.agent.attach.ArthasAgent;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
@@ -26,11 +25,11 @@
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.core.env.Environment;
+import org.ylzl.eden.arthas.spring.boot.attach.CustomArthasAgent;
import org.ylzl.eden.arthas.spring.boot.env.SpringArthasProperties;
import java.util.Map;
import java.util.Set;
-import java.util.concurrent.atomic.AtomicBoolean;
/**
* Arthas 开关监听器
@@ -42,18 +41,12 @@
@Slf4j
public class ArthasEnvironmentChangeListener implements ApplicationListener {
- public static final AtomicBoolean REGISTER_STATE = new AtomicBoolean(true);
-
public static final String ARTHAS_AGENT = "arthasAgent";
public static final String REGISTER_ARTHAS = "Register arthas to {}";
- public static final String ARTHAS_ALREADY_REGISTERED = "Arthas already registered";
-
public static final String DESTROY_ARTHAS = "Destroy arthas from {}";
- public static final String ARTHAS_ALREADY_DESTROY = "Arthas already destroy";
-
private final ApplicationContext applicationContext;
private final Environment environment;
@@ -78,14 +71,10 @@ public void onApplicationEvent(EnvironmentChangeEvent event) {
}
private void registerBean() {
- if (!REGISTER_STATE.compareAndSet(false, true)) {
- log.info(ARTHAS_ALREADY_REGISTERED);
- return;
- }
log.info(REGISTER_ARTHAS, arthasProperties.getTunnelServer());
DefaultListableBeanFactory defaultListableBeanFactory = getDefaultListableBeanFactory();
if (defaultListableBeanFactory.containsBean(ARTHAS_AGENT)) {
- ((ArthasAgent) defaultListableBeanFactory.getBean(ARTHAS_AGENT)).init();
+ ((CustomArthasAgent) defaultListableBeanFactory.getBean(ARTHAS_AGENT)).init();
} else {
defaultListableBeanFactory.registerSingleton(ARTHAS_AGENT,
ArthasAutoConfiguration.init(arthasConfigMap, environment, arthasProperties));
@@ -93,16 +82,12 @@ private void registerBean() {
}
private void destroyBean() {
- if (!REGISTER_STATE.compareAndSet(true, false)) {
- log.info(ARTHAS_ALREADY_DESTROY);
- return;
- }
log.info(DESTROY_ARTHAS, arthasProperties.getTunnelServer());
DefaultListableBeanFactory defaultListableBeanFactory = getDefaultListableBeanFactory();
if (defaultListableBeanFactory.containsBean(ARTHAS_AGENT)) {
+ ((CustomArthasAgent) defaultListableBeanFactory.getBean(ARTHAS_AGENT)).destroy();
defaultListableBeanFactory.destroySingleton(ARTHAS_AGENT);
}
- ArthasAutoConfiguration.destroy(arthasConfigMap, arthasProperties);
}
@NotNull
diff --git a/eden-components/eden-spring-test/pom.xml b/eden-components/eden-spring-test/pom.xml
index 0b5bc697..75c2279e 100644
--- a/eden-components/eden-spring-test/pom.xml
+++ b/eden-components/eden-spring-test/pom.xml
@@ -207,6 +207,14 @@
log4j
log4j
+
+ logback-classic
+ ch.qos.logback
+
+
+ logback-core
+ ch.qos.logback
+