diff --git a/labs/cluster-management/README.md b/labs/cluster-management/README.md index 99b99f4d8aa..32a20673b9e 100644 --- a/labs/cluster-management/README.md +++ b/labs/cluster-management/README.md @@ -1,18 +1,63 @@ ## Arthas Native Agent - 集群管理 - -![](images/cluster_management.png) -# 快速开始 + + +# 快速开始 - 单体模式(适用快速体验) + +![](asserts/cluster_management_single.png) +## 单体模式启动native-agent-management-web +native-agent的管理页面,启动需要指定prxoy地址,启动参数 + +| 参数 | 必填 | 解释 | +|---------------|-----|-----------------------| +| port | N | http端口 ,默认3939 | +| proxy-address | Y | native-agent-proxy的地址 | +example: +```shell +java -jar native-agent-management-web.jar --proxy-address 161.169.97.114:2233 +``` + +## 单体模式启动native-agent-proxy +proxy启动参数 + +| 参数 | 必填 | 解释 | +|--------------------|-----|--------------------------------------| +| port | N | http/ws端口 ,默认2233 | + +```shell +java -jar native-agent-proxy.jar +``` + +## 单体模式启动native-agent +native-agent,启动在需要动态attach的服务器上。同时需要依赖arthas-agent。请把arthas-agent、arthas-core、arthas-spy放在和native-agent同一个目录下。 + +| 参数 | 必填 | 解释 | +|---------------|-----|----------------------------| +| http-port | N | http端口 ,默认2671 | +| ws-port | N | ws端口,默认2672 | +| ip | Y | native-agent的ip | +| proxy-address | Y | native-agent-proxy的地址,用于注册 | +```shell +java -jar native-agent.jar --ip 127.0.0.1 --proxy-address 127.0.0.1 :2233 +``` + + + + +# 集群模式 +![](asserts/cluster_management.png) ## 启动native-agent -native-agent,启动在需要动态attach的服务器上 +native-agent,启动在需要动态attach的服务器上。同时需要依赖arthas-agent。请把arthas-agent、arthas-core、arthas-spy放在和native-agent同一个目录下。 + 启动参数 | 参数 | 必填 | 解释 | |----------------------|-----|-------------------------------------| | http-port | N | http端口 ,默认2671 | | ws-port | N | ws端口,默认2672 | +| ip | Y | native-agent的ip地址 | | registration-typ | Y | 注册中心类型(目前实现的有etcd和zookeeper,推荐etcd) | | registration-address | Y | 注册中心的地址 | @@ -57,11 +102,11 @@ java -jar native-agent-management-web.jar --registration-type etcd --registrati ## 监控指定JVM 进入native-agent-server管理页面,点击VIEW JAVA PROCESS INFO 按钮,可以查看到当前服务器上的Java进程 -![](images/native_agent_list.png) +![](asserts/native_agent_list.png) 进入到Java进程页后,我们可以点击Monitor按钮,Monitor目标Java进程 -![](images/native_agent_java_process_page.png) +![](asserts/native_agent_java_process_page.png) 之后点击MONITOR按钮就可以进入到监控界面了 -![](images/native_agent_moniotr_page.png) +![](asserts/native_agent_moniotr_page.png) # 扩展注册中心 目前实现的有zookeeper和etcd,如果想要扩展注册中心,可以看看下面的实现。下面演示的是native-agent-management-web的扩展,其他也是同样的道理。 diff --git a/labs/cluster-management/images/cluster_management.png b/labs/cluster-management/asserts/cluster_management.png similarity index 100% rename from labs/cluster-management/images/cluster_management.png rename to labs/cluster-management/asserts/cluster_management.png diff --git a/labs/cluster-management/asserts/cluster_management_single.png b/labs/cluster-management/asserts/cluster_management_single.png new file mode 100644 index 00000000000..1c25b636e02 Binary files /dev/null and b/labs/cluster-management/asserts/cluster_management_single.png differ diff --git a/labs/cluster-management/images/native_agent_architecture.png b/labs/cluster-management/asserts/native_agent_architecture.png similarity index 100% rename from labs/cluster-management/images/native_agent_architecture.png rename to labs/cluster-management/asserts/native_agent_architecture.png diff --git a/labs/cluster-management/images/native_agent_java_process_page.png b/labs/cluster-management/asserts/native_agent_java_process_page.png similarity index 100% rename from labs/cluster-management/images/native_agent_java_process_page.png rename to labs/cluster-management/asserts/native_agent_java_process_page.png diff --git a/labs/cluster-management/images/native_agent_list.png b/labs/cluster-management/asserts/native_agent_list.png similarity index 100% rename from labs/cluster-management/images/native_agent_list.png rename to labs/cluster-management/asserts/native_agent_list.png diff --git a/labs/cluster-management/images/native_agent_moniotr_page.png b/labs/cluster-management/asserts/native_agent_moniotr_page.png similarity index 100% rename from labs/cluster-management/images/native_agent_moniotr_page.png rename to labs/cluster-management/asserts/native_agent_moniotr_page.png diff --git a/labs/cluster-management/native-agent-common/src/main/java/com/alibaba/arthas/nat/agent/common/utils/OkHttpUtil.java b/labs/cluster-management/native-agent-common/src/main/java/com/alibaba/arthas/nat/agent/common/utils/OkHttpUtil.java index fae2acb47fa..8294f2308c9 100644 --- a/labs/cluster-management/native-agent-common/src/main/java/com/alibaba/arthas/nat/agent/common/utils/OkHttpUtil.java +++ b/labs/cluster-management/native-agent-common/src/main/java/com/alibaba/arthas/nat/agent/common/utils/OkHttpUtil.java @@ -43,4 +43,18 @@ public static String post(String url, String json) throws IOException { } } + + public static Response postAndResponse(String url, String json) throws IOException { + RequestBody body = RequestBody.create(json, JSON); + Request request = new Request.Builder() + .url(url) + .post(body) + .header("Content-Type", "application/json") + .build(); + + try (Response response = client.newCall(request).execute()) { + return response; + } + } + } diff --git a/labs/cluster-management/native-agent-management-web/src/main/java/com/alibaba/arthas/nat/agent/management/web/discovery/impl/NativeAgentManagementNativeAgentProxyDiscovery.java b/labs/cluster-management/native-agent-management-web/src/main/java/com/alibaba/arthas/nat/agent/management/web/discovery/impl/NativeAgentManagementNativeAgentProxyDiscovery.java new file mode 100644 index 00000000000..56cdbc20cdc --- /dev/null +++ b/labs/cluster-management/native-agent-management-web/src/main/java/com/alibaba/arthas/nat/agent/management/web/discovery/impl/NativeAgentManagementNativeAgentProxyDiscovery.java @@ -0,0 +1,22 @@ +package com.alibaba.arthas.nat.agent.management.web.discovery.impl; + +import com.alibaba.arthas.nat.agent.management.web.discovery.NativeAgentProxyDiscovery; + +import java.util.Arrays; +import java.util.List; + +/** + * @description: NativeAgentManagementNativeAgentProxyDiscovery(Σ(っ °Д °;)っ 好长的类名) + * @author:flzjkl + * @date: 2024-10-29 20:59 + */ +public class NativeAgentManagementNativeAgentProxyDiscovery implements NativeAgentProxyDiscovery { + + public static String proxyAddress; + + @Override + public List listNativeAgentProxy(String address) { + return Arrays.asList(proxyAddress); + } + +} diff --git a/labs/cluster-management/native-agent-management-web/src/main/java/com/alibaba/arthas/nat/agent/management/web/server/NativeAgentManagementWebBootstrap.java b/labs/cluster-management/native-agent-management-web/src/main/java/com/alibaba/arthas/nat/agent/management/web/server/NativeAgentManagementWebBootstrap.java index 2251169e317..22e4de156ed 100644 --- a/labs/cluster-management/native-agent-management-web/src/main/java/com/alibaba/arthas/nat/agent/management/web/server/NativeAgentManagementWebBootstrap.java +++ b/labs/cluster-management/native-agent-management-web/src/main/java/com/alibaba/arthas/nat/agent/management/web/server/NativeAgentManagementWebBootstrap.java @@ -2,6 +2,7 @@ import com.alibaba.arthas.nat.agent.common.constants.NativeAgentConstants; import com.alibaba.arthas.nat.agent.common.utils.WelcomeUtil; +import com.alibaba.arthas.nat.agent.management.web.discovery.impl.NativeAgentManagementNativeAgentProxyDiscovery; import com.alibaba.arthas.nat.agent.management.web.server.http.HttpRequestHandler; import com.taobao.middleware.cli.CLI; @@ -23,20 +24,21 @@ import java.util.Arrays; /** - * @description: native agent server + * @description: native agent management web * @author:flzjkl * @date: 2024-07-20 9:23 */ - @Name("arthas-native-agent-management-web") @Summary("Bootstrap Arthas Native Management Web") -@Description("EXAMPLES:\n" + " java -jar native-agent-management-web.jar --registration-type etcd --registration-address 161.169.97.114:2379\n" +@Description("EXAMPLES:\n" + "java -jar native-agent-management-web.jar --proxy-address 161.169.97.114:2233\n" + + "java -jar native-agent-management-web.jar --registration-type etcd --registration-address 161.169.97.114:2379\n" + "java -jar native-agent-management-web.jar --port 3939 --registration-type etcd --registration-address 161.169.97.114:2379\n" + "https://arthas.aliyun.com/doc\n") public class NativeAgentManagementWebBootstrap { private static final Logger logger = LoggerFactory.getLogger(NativeAgentManagementWebBootstrap.class); private static final int DEFAULT_NATIVE_AGENT_MANAGEMENT_WEB_PORT = 3939; private Integer port; + private String proxyAddress; public static String registrationType; public static String registrationAddress; @@ -46,13 +48,19 @@ public void setPort(Integer port) { this.port = port; } - @Option(longName = "registration-type", required = true) + @Option(longName = "proxy-address") + @Description("native agent proxy address") + public void setProxyAddress(String proxyAddress) { + this.proxyAddress = proxyAddress; + } + + @Option(longName = "registration-type") @Description("registration type") public void setRegistrationType(String registrationType) { this.registrationType = registrationType; } - @Option(longName = "registration-address", required = true) + @Option(longName = "registration-address") @Description("registration address") public void setRegistrationAddress(String registrationAddress) { this.registrationAddress = registrationAddress; @@ -75,6 +83,19 @@ public static void main(String[] args) { } logger.info("read input success!"); + logger.info("check bootstrap params ..."); + boolean checkBootstrapParamsRes = checkBootstrapParams(nativeAgentManagementWebBootstrap); + if (!checkBootstrapParamsRes) { + throw new RuntimeException("Failed to verify the bootstrap parameters. " + + "Please read the documentation and check the parameters you entered"); + } + if (nativeAgentManagementWebBootstrap.getRegistrationType() == null + && nativeAgentManagementWebBootstrap.getRegistrationAddress() == null + && nativeAgentManagementWebBootstrap.getProxyAddress() != null) { + nativeAgentManagementWebBootstrap.setRegistrationType("native-agent-management"); + nativeAgentManagementWebBootstrap.setRegistrationAddress("127.0.0,1:" + nativeAgentManagementWebBootstrap.getPortOrDefault()); + NativeAgentManagementNativeAgentProxyDiscovery.proxyAddress = nativeAgentManagementWebBootstrap.getProxyAddress(); + } // Start the http server logger.info("start the http server... httPort:{}", nativeAgentManagementWebBootstrap.getPortOrDefault()); NioEventLoopGroup bossGroup = new NioEventLoopGroup(); @@ -106,6 +127,21 @@ protected void initChannel(SocketChannel ch) { } } + private static boolean checkBootstrapParams(NativeAgentManagementWebBootstrap managementBootstrap) { + String address = managementBootstrap.getRegistrationAddress(); + String type = managementBootstrap.getRegistrationType(); + String proxyAddress = managementBootstrap.getProxyAddress(); + // single + if (address == null && type == null && proxyAddress != null) { + return true; + } + // cluster + if (address != null && type != null && proxyAddress == null) { + return true; + } + return false; + } + public int getPortOrDefault() { if (this.port == null) { return DEFAULT_NATIVE_AGENT_MANAGEMENT_WEB_PORT; @@ -122,6 +158,10 @@ public String getRegistrationAddress() { return registrationAddress; } + public String getProxyAddress() { + return proxyAddress; + } + public Integer getPort() { return port; } diff --git a/labs/cluster-management/native-agent-management-web/src/main/java/com/alibaba/arthas/nat/agent/management/web/server/http/HttpNativeAgentProxyHandler.java b/labs/cluster-management/native-agent-management-web/src/main/java/com/alibaba/arthas/nat/agent/management/web/server/http/HttpNativeAgentProxyHandler.java index 0e1ad426694..22187931b9f 100644 --- a/labs/cluster-management/native-agent-management-web/src/main/java/com/alibaba/arthas/nat/agent/management/web/server/http/HttpNativeAgentProxyHandler.java +++ b/labs/cluster-management/native-agent-management-web/src/main/java/com/alibaba/arthas/nat/agent/management/web/server/http/HttpNativeAgentProxyHandler.java @@ -1,18 +1,18 @@ package com.alibaba.arthas.nat.agent.management.web.server.http; import com.alibaba.arthas.nat.agent.management.web.discovery.NativeAgentProxyDiscovery; +import com.alibaba.arthas.nat.agent.management.web.discovery.impl.NativeAgentManagementNativeAgentProxyDiscovery; import com.alibaba.arthas.nat.agent.management.web.factory.NativeAgentProxyDiscoveryFactory; import com.alibaba.arthas.nat.agent.management.web.server.NativeAgentManagementWebBootstrap; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.TypeReference; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.http.DefaultFullHttpResponse; -import io.netty.handler.codec.http.FullHttpRequest; -import io.netty.handler.codec.http.FullHttpResponse; -import io.netty.handler.codec.http.HttpResponseStatus; +import io.netty.handler.codec.http.*; import java.nio.charset.StandardCharsets; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import java.util.List; import java.util.Map; import java.util.Random; @@ -34,6 +34,7 @@ public FullHttpResponse handle(ChannelHandlerContext ctx, FullHttpRequest reques return responseFindAvailableProxyAddress(ctx, request); } + return null; } @@ -48,6 +49,7 @@ public FullHttpResponse responseFindAvailableProxyAddress(ChannelHandlerContext HttpResponseStatus.OK, Unpooled.copiedBuffer(availableProxyAddress, StandardCharsets.UTF_8) ); + fillCorsHead(response); return response; } @@ -67,4 +69,15 @@ public String findAvailableProxyAddress() { } + private void fillCorsHead(FullHttpResponse fullHttpResponse) { + // 设置跨域响应头 + fullHttpResponse.headers().set(HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN, "*"); + fullHttpResponse.headers().set(HttpHeaderNames.ACCESS_CONTROL_ALLOW_METHODS, "GET, POST, PUT, DELETE, OPTIONS"); + fullHttpResponse.headers().set(HttpHeaderNames.ACCESS_CONTROL_ALLOW_HEADERS, "X-Requested-With, Content-Type, Authorization"); + + // 设置其他必要的头部 + fullHttpResponse.headers().set(HttpHeaderNames.CONTENT_TYPE, "application/json"); + fullHttpResponse.headers().set(HttpHeaderNames.CONTENT_LENGTH, fullHttpResponse.content().readableBytes()); + } + } diff --git a/labs/cluster-management/native-agent-management-web/src/main/resources/META-INF/arthas/com.alibaba.arthas.native.agent.management.web.NativeAgentProxyDiscoveryFactory b/labs/cluster-management/native-agent-management-web/src/main/resources/META-INF/arthas/com.alibaba.arthas.native.agent.management.web.NativeAgentProxyDiscoveryFactory index c47db4f485f..c89daad856b 100644 --- a/labs/cluster-management/native-agent-management-web/src/main/resources/META-INF/arthas/com.alibaba.arthas.native.agent.management.web.NativeAgentProxyDiscoveryFactory +++ b/labs/cluster-management/native-agent-management-web/src/main/resources/META-INF/arthas/com.alibaba.arthas.native.agent.management.web.NativeAgentProxyDiscoveryFactory @@ -1,2 +1,3 @@ +native-agent-management=com.alibaba.arthas.nat.agent.management.web.discovery.impl.NativeAgentManagementNativeAgentProxyDiscovery zookeeper=com.alibaba.arthas.nat.agent.management.web.discovery.impl.ZookeeperNativeAgentProxyDiscovery etcd=com.alibaba.arthas.nat.agent.management.web.discovery.impl.EtcdNativeAgentProxyDiscovery \ No newline at end of file diff --git a/labs/cluster-management/native-agent-proxy/src/main/java/com/alibaba/arthas/nat/agent/proxy/discovery/impl/NativeAgentProxyNativeAgentDiscovery.java b/labs/cluster-management/native-agent-proxy/src/main/java/com/alibaba/arthas/nat/agent/proxy/discovery/impl/NativeAgentProxyNativeAgentDiscovery.java new file mode 100644 index 00000000000..ad387cd5ee0 --- /dev/null +++ b/labs/cluster-management/native-agent-proxy/src/main/java/com/alibaba/arthas/nat/agent/proxy/discovery/impl/NativeAgentProxyNativeAgentDiscovery.java @@ -0,0 +1,54 @@ +package com.alibaba.arthas.nat.agent.proxy.discovery.impl; + +import com.alibaba.arthas.nat.agent.proxy.discovery.NativeAgentDiscovery; + +import java.time.LocalDateTime; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +/** + * @description: NativeAgentProxyNativeAgentDiscovery + * @author:flzjkl + * @date: 2024-10-28 21:07 + */ +public class NativeAgentProxyNativeAgentDiscovery implements NativeAgentDiscovery { + + /** + * key: native agent ip : http port : ws port , value: expiration time + */ + private static Map nativeAgentMap = new ConcurrentHashMap<>(); + private final static int INITIAL_DELAY_SECONDS = 5; + private final static int PERIOD_SECONDS = 5; + + public static void storageNativeAgent(String address, LocalDateTime expirationTime) { + nativeAgentMap.put(address, expirationTime); + } + + public static void nativeAgentCheckScheduled () { + ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); + Runnable task = () -> { + LocalDateTime now = LocalDateTime.now(); + nativeAgentMap.forEach((key, expirationTime) ->{ + if (now.isAfter(expirationTime)) { + nativeAgentMap.remove(key); + } + }); + }; + scheduler.scheduleAtFixedRate(task, INITIAL_DELAY_SECONDS, PERIOD_SECONDS, TimeUnit.SECONDS); + } + + + @Override + public Map findNativeAgent(String address) { + Map res = new HashMap<>(); + for (String key : nativeAgentMap.keySet()) { + String[] split = key.split("@"); + res.put(split[0], split[1]); + } + return res; + } +} diff --git a/labs/cluster-management/native-agent-proxy/src/main/java/com/alibaba/arthas/nat/agent/proxy/registry/impl/NativeAgentManagementNativeAgentProxyRegistry.java b/labs/cluster-management/native-agent-proxy/src/main/java/com/alibaba/arthas/nat/agent/proxy/registry/impl/NativeAgentManagementNativeAgentProxyRegistry.java new file mode 100644 index 00000000000..d16d450a8be --- /dev/null +++ b/labs/cluster-management/native-agent-proxy/src/main/java/com/alibaba/arthas/nat/agent/proxy/registry/impl/NativeAgentManagementNativeAgentProxyRegistry.java @@ -0,0 +1,17 @@ +package com.alibaba.arthas.nat.agent.proxy.registry.impl; + +import com.alibaba.arthas.nat.agent.proxy.registry.NativeAgentProxyRegistry; + +/** + * @description: NativeAgentManagementNativeAgentProxyRegistry(...好长的类名) + * @author:flzjkl + * @date: 2024-10-29 20:26 + */ +public class NativeAgentManagementNativeAgentProxyRegistry implements NativeAgentProxyRegistry { + + @Override + public void register(String address, String k, String v) { + // do nothing + } + +} diff --git a/labs/cluster-management/native-agent-proxy/src/main/java/com/alibaba/arthas/nat/agent/proxy/server/NativeAgentProxyBootstrap.java b/labs/cluster-management/native-agent-proxy/src/main/java/com/alibaba/arthas/nat/agent/proxy/server/NativeAgentProxyBootstrap.java index d667ad5d47b..784e4a1a22d 100644 --- a/labs/cluster-management/native-agent-proxy/src/main/java/com/alibaba/arthas/nat/agent/proxy/server/NativeAgentProxyBootstrap.java +++ b/labs/cluster-management/native-agent-proxy/src/main/java/com/alibaba/arthas/nat/agent/proxy/server/NativeAgentProxyBootstrap.java @@ -2,6 +2,7 @@ import com.alibaba.arthas.nat.agent.common.constants.NativeAgentConstants; import com.alibaba.arthas.nat.agent.common.utils.WelcomeUtil; +import com.alibaba.arthas.nat.agent.proxy.discovery.impl.NativeAgentProxyNativeAgentDiscovery; import com.alibaba.arthas.nat.agent.proxy.factory.NativeAgentProxyRegistryFactory; import com.alibaba.arthas.nat.agent.proxy.registry.NativeAgentProxyRegistry; import com.alibaba.arthas.nat.agent.proxy.server.handler.RequestHandler; @@ -31,7 +32,8 @@ */ @Name("arthas-native-agent-proxy") @Summary("Bootstrap Arthas Native Agent Proxy") -@Description("EXAMPLES:\n" + "java -jar native-agent-proxy.jar --ip 151.159.27.114 --management-registration-type etcd --management-registration-address 161.169.97.114:2379 --agent-registration-type etcd --agent-registration-address 161.169.97.114:2379\n" +@Description("EXAMPLES:\n" + "java -jar native-agent-proxy.jar\n" + + "java -jar native-agent-proxy.jar --ip 151.159.27.114 --management-registration-type etcd --management-registration-address 161.169.97.114:2379 --agent-registration-type etcd --agent-registration-address 161.169.97.114:2379\n" + "java -jar native-agent-proxy.jar --ip 151.159.27.114 --port 2233 --management-registration-type etcd --management-registration-address 161.169.97.114:2379 --agent-registration-type etcd --agent-registration-address 161.169.97.114:2379\n" + "https://arthas.aliyun.com/doc\n") public class NativeAgentProxyBootstrap { @@ -47,37 +49,38 @@ public class NativeAgentProxyBootstrap { public static String managementRegistrationAddress; public static String agentRegistrationAddress; + @Option(longName = "port") @Description("native agent proxy http/ws port, default 2233") public void setPort(Integer port) { this.port = port; } - @Option(longName = "ip", required = true) + @Option(longName = "ip") @Description("ip") public void setIp(String ip) { this.ip = ip; } - @Option(longName = "management-registration-type", required = true) + @Option(longName = "management-registration-type") @Description("management registration type") public void setManagementRegistrationType(String managementRegistrationType) { this.managementRegistrationType = managementRegistrationType; } - @Option(longName = "agent-registration-type", required = true) + @Option(longName = "agent-registration-type") @Description("agent registration type") public void setAgentRegistrationType(String agentRegistrationType) { this.agentRegistrationType = agentRegistrationType; } - @Option(longName = "management-registration-address", required = true) + @Option(longName = "management-registration-address") @Description("management registration address") public void setManagementRegistrationAddress(String managementRegistrationAddress) { this.managementRegistrationAddress = managementRegistrationAddress; } - @Option(longName = "agent-registration-address", required = true) + @Option(longName = "agent-registration-address") @Description("agent registration address") public void setAgentRegistrationAddress(String agentRegistrationAddress) { this.agentRegistrationAddress = agentRegistrationAddress; @@ -102,6 +105,21 @@ public static void main(String[] args) { // Register native agent proxy + logger.info("check register params ..."); + boolean checkRegisterParamsRes = checkRegisterParams(nativeAgentProxyBootstrap); + if (!checkRegisterParamsRes) { + throw new RuntimeException("Failed to verify the registration parameters. " + + "Please read the documentation and check the parameters you entered"); + } + if (managementRegistrationType == null + && managementRegistrationAddress == null + && agentRegistrationType == null + && agentRegistrationAddress ==null) { + nativeAgentProxyBootstrap.setAgentRegistrationType("native-agent-proxy"); + nativeAgentProxyBootstrap.setManagementRegistrationType("native-agent-management"); + nativeAgentProxyBootstrap.setAgentRegistrationAddress("127.0.0.1:" + nativeAgentProxyBootstrap.getPortOrDefault()); + NativeAgentProxyNativeAgentDiscovery.nativeAgentCheckScheduled(); + } try { logger.info("register native agent proxy..."); NativeAgentProxyRegistryFactory registerFactory = NativeAgentProxyRegistryFactory.getNativeAgentProxyRegistryFactory(); @@ -150,6 +168,31 @@ protected void initChannel(SocketChannel ch) { } + private static boolean checkRegisterParams(NativeAgentProxyBootstrap nativeAgentProxyBootstrap) { + String ip = nativeAgentProxyBootstrap.getIp(); + String managementRegistrationType = nativeAgentProxyBootstrap.getManagementRegistrationType(); + String managementRegistrationAddress = nativeAgentProxyBootstrap.getManagementRegistrationAddress(); + String agentRegistrationType = nativeAgentProxyBootstrap.getAgentRegistrationType(); + String agentRegistrationAddress = nativeAgentProxyBootstrap.getAgentRegistrationAddress(); + // single + if (managementRegistrationType == null + && managementRegistrationAddress == null + && agentRegistrationType == null + && agentRegistrationAddress ==null) { + return true; + } + // cluster + if (ip != null + && managementRegistrationType != null + && managementRegistrationAddress != null + && agentRegistrationType != null + && agentRegistrationAddress != null) { + return true; + } + + return false; + } + public int getPortOrDefault() { if (this.port == null) { return DEFAULT_NATIVE_AGENT_PROXY_PORT; @@ -174,6 +217,7 @@ public String getAgentRegistrationAddress() { return agentRegistrationAddress; } + public String getIp() { return ip; } diff --git a/labs/cluster-management/native-agent-proxy/src/main/java/com/alibaba/arthas/nat/agent/proxy/server/handler/http/HttpNativeAgentHandler.java b/labs/cluster-management/native-agent-proxy/src/main/java/com/alibaba/arthas/nat/agent/proxy/server/handler/http/HttpNativeAgentHandler.java index a15ade1090d..c4311f6614f 100644 --- a/labs/cluster-management/native-agent-proxy/src/main/java/com/alibaba/arthas/nat/agent/proxy/server/handler/http/HttpNativeAgentHandler.java +++ b/labs/cluster-management/native-agent-proxy/src/main/java/com/alibaba/arthas/nat/agent/proxy/server/handler/http/HttpNativeAgentHandler.java @@ -3,6 +3,7 @@ import com.alibaba.arthas.nat.agent.common.dto.NativeAgentInfoDTO; import com.alibaba.arthas.nat.agent.proxy.discovery.NativeAgentDiscovery; +import com.alibaba.arthas.nat.agent.proxy.discovery.impl.NativeAgentProxyNativeAgentDiscovery; import com.alibaba.arthas.nat.agent.proxy.factory.NativeAgentDiscoveryFactory; import com.alibaba.arthas.nat.agent.proxy.server.NativeAgentProxyBootstrap; import com.alibaba.fastjson2.JSON; @@ -15,10 +16,11 @@ import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; /** @@ -28,8 +30,6 @@ */ public class HttpNativeAgentHandler { - private Map localCache = new ConcurrentHashMap<>(); - public FullHttpResponse handle(ChannelHandlerContext ctx, FullHttpRequest request) { String content = request.content().toString(StandardCharsets.UTF_8); Map bodyMap = JSON.parseObject(content, new TypeReference>() { @@ -50,9 +50,26 @@ public FullHttpResponse handle(ChannelHandlerContext ctx, FullHttpRequest reques return forwardRequest(request, address); } + if ("register".equals(operation)) { + String addressInfo = (String) bodyMap.get("nativeAgentAddress"); + String expirationTimeStr = (String) bodyMap.get("expirationTime"); + return doRegisterNativeAgent(request, addressInfo, expirationTimeStr); + } + return null; } + private FullHttpResponse doRegisterNativeAgent(FullHttpRequest request, String addressInfo, String expirationTimeStr) { + LocalDateTime expirationTime = LocalDateTime.parse(expirationTimeStr, DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS")); + NativeAgentProxyNativeAgentDiscovery.storageNativeAgent(addressInfo, expirationTime); + DefaultFullHttpResponse response = new DefaultFullHttpResponse( + request.getProtocolVersion(), + HttpResponseStatus.OK, + Unpooled.copiedBuffer("success", StandardCharsets.UTF_8) + ); + fillCorsHead(response); + return response; + } private FullHttpResponse forwardRequest(FullHttpRequest request, String address) { @@ -84,14 +101,7 @@ private FullHttpResponse forwardRequest(FullHttpRequest request, String address) HttpResponseStatus.OK, Unpooled.copiedBuffer(responseBody, StandardCharsets.UTF_8) ); - // 设置跨域响应头 - fullHttpResponse.headers().set(HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN, "*"); - fullHttpResponse.headers().set(HttpHeaderNames.ACCESS_CONTROL_ALLOW_METHODS, "GET, POST, PUT, DELETE, OPTIONS"); - fullHttpResponse.headers().set(HttpHeaderNames.ACCESS_CONTROL_ALLOW_HEADERS, "X-Requested-With, Content-Type, Authorization"); - - // 设置其他必要的头部 - fullHttpResponse.headers().set(HttpHeaderNames.CONTENT_TYPE, "application/json"); - fullHttpResponse.headers().set(HttpHeaderNames.CONTENT_LENGTH, fullHttpResponse.content().readableBytes()); + fillCorsHead(fullHttpResponse); return fullHttpResponse; } else { return new DefaultFullHttpResponse( @@ -110,6 +120,17 @@ private FullHttpResponse forwardRequest(FullHttpRequest request, String address) } } + private void fillCorsHead(FullHttpResponse fullHttpResponse) { + // 设置跨域响应头 + fullHttpResponse.headers().set(HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN, "*"); + fullHttpResponse.headers().set(HttpHeaderNames.ACCESS_CONTROL_ALLOW_METHODS, "GET, POST, PUT, DELETE, OPTIONS"); + fullHttpResponse.headers().set(HttpHeaderNames.ACCESS_CONTROL_ALLOW_HEADERS, "X-Requested-With, Content-Type, Authorization"); + + // 设置其他必要的头部 + fullHttpResponse.headers().set(HttpHeaderNames.CONTENT_TYPE, "application/json"); + fullHttpResponse.headers().set(HttpHeaderNames.CONTENT_LENGTH, fullHttpResponse.content().readableBytes()); + } + private FullHttpResponse doListNativeAgent(ChannelHandlerContext ctx, FullHttpRequest request) { NativeAgentDiscoveryFactory nativeAgentDiscoveryFactory = NativeAgentDiscoveryFactory.getNativeAgentDiscoveryFactory(); NativeAgentDiscovery nativeAgentDiscovery = nativeAgentDiscoveryFactory.getNativeAgentDiscovery(NativeAgentProxyBootstrap.agentRegistrationType); @@ -132,14 +153,7 @@ private FullHttpResponse doListNativeAgent(ChannelHandlerContext ctx, FullHttpRe Unpooled.copiedBuffer(nativeAgentInfoStr, StandardCharsets.UTF_8) ); - // 设置跨域响应头 - response.headers().set(HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN, "*"); - response.headers().set(HttpHeaderNames.ACCESS_CONTROL_ALLOW_METHODS, "GET, POST, PUT, DELETE, OPTIONS"); - response.headers().set(HttpHeaderNames.ACCESS_CONTROL_ALLOW_HEADERS, "X-Requested-With, Content-Type, Authorization"); - - // 设置其他必要的头部 - response.headers().set(HttpHeaderNames.CONTENT_TYPE, "application/json"); - response.headers().set(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes()); + fillCorsHead(response); return response; } diff --git a/labs/cluster-management/native-agent-proxy/src/main/resources/META-INF/arthas/com.alibaba.arthas.native.agent.proxy.NativeAgentDiscoveryFactory b/labs/cluster-management/native-agent-proxy/src/main/resources/META-INF/arthas/com.alibaba.arthas.native.agent.proxy.NativeAgentDiscoveryFactory index df49c3f96e2..8a50c91cd63 100644 --- a/labs/cluster-management/native-agent-proxy/src/main/resources/META-INF/arthas/com.alibaba.arthas.native.agent.proxy.NativeAgentDiscoveryFactory +++ b/labs/cluster-management/native-agent-proxy/src/main/resources/META-INF/arthas/com.alibaba.arthas.native.agent.proxy.NativeAgentDiscoveryFactory @@ -1,2 +1,3 @@ +native-agent-proxy=com.alibaba.arthas.nat.agent.proxy.discovery.impl.NativeAgentProxyNativeAgentDiscovery zookeeper=com.alibaba.arthas.nat.agent.proxy.discovery.impl.ZookeeperNativeAgentDiscovery etcd=com.alibaba.arthas.nat.agent.proxy.discovery.impl.EtcdNativeAgentDiscovery \ No newline at end of file diff --git a/labs/cluster-management/native-agent-proxy/src/main/resources/META-INF/arthas/com.alibaba.arthas.native.agent.proxy.NativeAgentProxyRegistryFactory b/labs/cluster-management/native-agent-proxy/src/main/resources/META-INF/arthas/com.alibaba.arthas.native.agent.proxy.NativeAgentProxyRegistryFactory index e76c783b9ac..a17418253bc 100644 --- a/labs/cluster-management/native-agent-proxy/src/main/resources/META-INF/arthas/com.alibaba.arthas.native.agent.proxy.NativeAgentProxyRegistryFactory +++ b/labs/cluster-management/native-agent-proxy/src/main/resources/META-INF/arthas/com.alibaba.arthas.native.agent.proxy.NativeAgentProxyRegistryFactory @@ -1,2 +1,3 @@ +native-agent-management=com.alibaba.arthas.nat.agent.proxy.registry.impl.NativeAgentManagementNativeAgentProxyRegistry zookeeper=com.alibaba.arthas.nat.agent.proxy.registry.impl.ZookeeperNativeAgentProxyRegistry etcd=com.alibaba.arthas.nat.agent.proxy.registry.impl.EtcdNativeAgentProxyRegistry diff --git a/labs/cluster-management/native-agent/pom.xml b/labs/cluster-management/native-agent/pom.xml index e9ac3b042ba..c0e617ef0ab 100644 --- a/labs/cluster-management/native-agent/pom.xml +++ b/labs/cluster-management/native-agent/pom.xml @@ -26,15 +26,15 @@ - io.earcam.wrapped - com.sun.tools.attach - 1.8.0_jdk8u172-b11 + com.taobao.arthas + arthas-common + ${project.version} - com.taobao.arthas - arthas-core - ${project.version} + io.earcam.wrapped + com.sun.tools.attach + 1.8.0_jdk8u172-b11 @@ -49,12 +49,6 @@ test - - com.taobao.arthas - native-agent-common - ${project.version} - compile - diff --git a/labs/cluster-management/native-agent/src/main/java/com/alibaba/arthas/nat/agent/core/ListJvmProcessHandler.java b/labs/cluster-management/native-agent/src/main/java/com/alibaba/arthas/nat/agent/core/ListJvmProcessHandler.java index 9663a4b08d1..7ae09502231 100644 --- a/labs/cluster-management/native-agent/src/main/java/com/alibaba/arthas/nat/agent/core/ListJvmProcessHandler.java +++ b/labs/cluster-management/native-agent/src/main/java/com/alibaba/arthas/nat/agent/core/ListJvmProcessHandler.java @@ -1,16 +1,14 @@ package com.alibaba.arthas.nat.agent.core; +import com.taobao.arthas.common.ExecutingCommand; +import com.taobao.arthas.common.PidUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.File; -import java.lang.reflect.Method; -import java.net.URL; -import java.net.URLClassLoader; +import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; -import static com.alibaba.arthas.nat.agent.core.ArthasHomeHandler.ARTHAS_HOME_DIR; - /** * @description: list java process via invoke com.taobao.arthas.boot.ProcessUtils#listProcessByJps * @author:flzjkl @@ -19,39 +17,43 @@ public class ListJvmProcessHandler { private static final Logger logger = LoggerFactory.getLogger(ListJvmProcessHandler.class); - private static final String PROCESS_UTILS_PATH = "com.taobao.arthas.boot.ProcessUtils"; - private static final String LIST_PROCESS_BY_JPS_METHOD = "listProcessByJps"; - public static Map listJvmProcessByInvoke() { - if (ARTHAS_HOME_DIR == null) { - ArthasHomeHandler.findArthasHome(); - } + public static Map listProcessByJps() { + Map result = new LinkedHashMap(); - if (ARTHAS_HOME_DIR == null) { - return null; - } + String jps = "jps"; - String arthasBootPath = ARTHAS_HOME_DIR + File.separator + "arthas-boot.jar"; - Method method = null; - Object instance = null; - Map result = null; + String[] command = new String[] { jps, "-l" }; - try { - URLClassLoader classLoader = new URLClassLoader(new URL[]{new File(arthasBootPath).toURI().toURL()}); + List lines = ExecutingCommand.runNative(command); - Class clazz = classLoader.loadClass(PROCESS_UTILS_PATH); - method = clazz.getDeclaredMethod(LIST_PROCESS_BY_JPS_METHOD, boolean.class); - method.setAccessible(true); + long currentPid = Long.parseLong(PidUtils.currentPid()); + for (String line : lines) { + String[] strings = line.trim().split("\\s+"); + if (strings.length < 1) { + continue; + } + try { + long pid = Long.parseLong(strings[0]); + if (pid == currentPid) { + continue; + } + if (strings.length >= 2 && isJpsProcess(strings[1])) { // skip jps + continue; + } - instance = clazz.getDeclaredConstructor().newInstance(); + result.put(pid, line); + } catch (Throwable e) { - result = (Map) method.invoke(instance, false); - } catch (Exception e) { - logger.error("invoke list java process failed:" + e.getMessage()); - throw new RuntimeException(e); + } } return result; } + + private static boolean isJpsProcess(String mainClassName) { + return "sun.tools.jps.Jps".equals(mainClassName) || "jdk.jcmd/sun.tools.jps.Jps".equals(mainClassName); + } + } diff --git a/labs/cluster-management/native-agent/src/main/java/com/alibaba/arthas/nat/agent/registry/impl/NativeAgentProxyNativeAgentRegistry.java b/labs/cluster-management/native-agent/src/main/java/com/alibaba/arthas/nat/agent/registry/impl/NativeAgentProxyNativeAgentRegistry.java new file mode 100644 index 00000000000..78527ac6c02 --- /dev/null +++ b/labs/cluster-management/native-agent/src/main/java/com/alibaba/arthas/nat/agent/registry/impl/NativeAgentProxyNativeAgentRegistry.java @@ -0,0 +1,59 @@ +package com.alibaba.arthas.nat.agent.registry.impl; + +import com.alibaba.arthas.nat.agent.common.utils.OkHttpUtil; +import com.alibaba.arthas.nat.agent.registry.NativeAgentRegistry; +import okhttp3.Response; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.time.LocalDateTime; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +/** + * @description: NativeAgentProxyNativeAgentRegistry + * @author:flzjkl + * @date: 2024-10-27 9:48 + */ +public class NativeAgentProxyNativeAgentRegistry implements NativeAgentRegistry { + + private static final Logger logger = LoggerFactory.getLogger(NativeAgentProxyNativeAgentRegistry.class); + private final int INITIAL_DELAY_SECONDS = 5; + private final int PERIOD_SECONDS = 5; + private final int TIME_OUT_SECONDS = 15; + + @Override + public void registerNativeAgent(String address, String k, String v) { + register(address, k, v); + logger.info("register to native agent proxy success, native agent address:{}", k); + sendHeadBeat(address, k, v); + } + + private void sendHeadBeat(String address, String k, String v) { + ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); + Runnable task = () -> { + register(address, k, v); + }; + scheduler.scheduleAtFixedRate(task, INITIAL_DELAY_SECONDS, PERIOD_SECONDS, TimeUnit.SECONDS); + } + + private void register (String address, String k, String v) { + try { + String url = "http://" + address + "/api/native-agent-proxy"; + LocalDateTime expirationTime = LocalDateTime.now().plusSeconds(TIME_OUT_SECONDS); + String jsonBody = "{" + + "\"operation\": \"register\"," + + "\"nativeAgentAddress\":\""+ k +"@"+ v +"\", " + + "\"expirationTime\": \"" + expirationTime+ "\"}"; + Response response = OkHttpUtil.postAndResponse(url, jsonBody); + if (response.code() != 200) { + throw new RuntimeException("Register failed! response code: " + response.code()); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/labs/cluster-management/native-agent/src/main/java/com/alibaba/arthas/nat/agent/server/NativeAgentBootstrap.java b/labs/cluster-management/native-agent/src/main/java/com/alibaba/arthas/nat/agent/server/NativeAgentBootstrap.java index b873dce05ef..2d5f8988eb0 100644 --- a/labs/cluster-management/native-agent/src/main/java/com/alibaba/arthas/nat/agent/server/NativeAgentBootstrap.java +++ b/labs/cluster-management/native-agent/src/main/java/com/alibaba/arthas/nat/agent/server/NativeAgentBootstrap.java @@ -1,5 +1,6 @@ package com.alibaba.arthas.nat.agent.server; +import com.alibaba.arthas.nat.agent.common.constants.NativeAgentConstants; import com.alibaba.arthas.nat.agent.factory.NativeAgentRegistryFactory; import com.alibaba.arthas.nat.agent.registry.NativeAgentRegistry; import com.alibaba.arthas.nat.agent.core.ArthasHomeHandler; @@ -34,14 +35,16 @@ import static com.taobao.arthas.common.ArthasConstants.MAX_HTTP_CONTENT_LENGTH; /** - * @description: hello world + * @description: NativeAgentBootstrap * @author:flzjkl * @date: 2024-07-20 9:23 */ @Name("arthas-native-agent") @Summary("Bootstrap Arthas Native Agent") -@Description("EXAMPLES:\n" + "java -jar native-agent.jar --ip 116.196.97.114 --http-port 2671 --ws-port 2672 --registration-type etcd --registration-address 126.166.97.114:2379\n" +@Description("EXAMPLES:\n" + "java -jar native-agent.jar --ip 127.0.0.1 --proxy-address 127.0.0.1 :2233\n" + + "java -jar native-agent.jar --ip 116.196.97.114 --http-port 2671 --ws-port 2672 --proxy-address 116.196.97.114:2233\n" + + "java -jar native-agent.jar --ip 116.196.97.114 --http-port 2671 --ws-port 2672 --registration-type etcd --registration-address 126.166.97.114:2379\n" + " https://arthas.aliyun.com/doc\n") public class NativeAgentBootstrap { @@ -53,6 +56,7 @@ public class NativeAgentBootstrap { public Integer wsPort; public String registrationType; public String registrationAddress; + public String proxyAddress; @Option(longName = "ip", required = true) @Description("native agent ip") @@ -72,18 +76,24 @@ public void wsPort(Integer wsPort) { this.wsPort = wsPort; } - @Option(longName = "registration-type", required = true) + @Option(longName = "registration-type") @Description("registration type") public void setRegistrationType(String registrationType) { this.registrationType = registrationType; } - @Option(longName = "registration-address", required = true) + @Option(longName = "registration-address") @Description("registration address") public void setRegistrationAddress(String registrationAddress) { this.registrationAddress = registrationAddress; } + @Option(longName = "proxy-address") + @Description("registration proxy address") + public void setProxyAddress(String proxyAddress) { + this.proxyAddress = proxyAddress; + } + public static void main(String[] args) { // Print welcome info WelcomeUtil.printNativeAgentWelcomeMsg(); @@ -109,6 +119,17 @@ public static void main(String[] args) { logger.info("read input config success"); // Register native agent + logger.info("check register params ..."); + boolean checkRegisterParamsRes = checkRegisterParams(nativeAgentBootstrap); + if (!checkRegisterParamsRes) { + throw new RuntimeException("Failed to verify the registration parameters. " + + "Please read the documentation and check the parameters you entered"); + } + if (nativeAgentBootstrap.getProxyAddress() != null) { + nativeAgentBootstrap.setRegistrationType("native-agent-proxy"); + nativeAgentBootstrap.setRegistrationAddress(nativeAgentBootstrap.getProxyAddress()); + } + logger.info("check register params success"); try { logger.info("register native agent ..."); NativeAgentRegistryFactory nativeAgentRegistryFactory = NativeAgentRegistryFactory.getNativeAgentClientRegisterFactory(); @@ -177,7 +198,7 @@ protected void initChannel(SocketChannel ch) { @Override protected void initChannel(SocketChannel ch) { ch.pipeline().addLast(new HttpServerCodec()); - ch.pipeline().addLast(new HttpObjectAggregator(MAX_HTTP_CONTENT_LENGTH)); + ch.pipeline().addLast(new HttpObjectAggregator(NativeAgentConstants.MAX_HTTP_CONTENT_LENGTH)); ch.pipeline().addLast(new HttpRequestHandler()); } }); @@ -195,6 +216,23 @@ protected void initChannel(SocketChannel ch) { } + private static boolean checkRegisterParams(NativeAgentBootstrap nativeAgentBootstrap) { + String proxyAddress = nativeAgentBootstrap.getProxyAddress(); + String thirdPartyAddress = nativeAgentBootstrap.getRegistrationAddress(); + String thirdPartyType = nativeAgentBootstrap.getRegistrationType(); + + // Register with proxy + if (proxyAddress != null && thirdPartyAddress == null && thirdPartyType == null) { + return true; + } + // Register with a third-party registry + if (proxyAddress == null && thirdPartyType != null && thirdPartyAddress != null) { + return true; + } + + return false; + } + private static String usage(CLI cli) { StringBuilder usageStringBuilder = new StringBuilder(); UsageMessageFormatter usageMessageFormatter = new UsageMessageFormatter(); @@ -239,4 +277,8 @@ public String getRegistrationAddress() { public String getRegistrationType() { return registrationType; } + + public String getProxyAddress() { + return proxyAddress; + } } diff --git a/labs/cluster-management/native-agent/src/main/java/com/alibaba/arthas/nat/agent/server/forward/ForwardClientSocketClientHandler.java b/labs/cluster-management/native-agent/src/main/java/com/alibaba/arthas/nat/agent/server/forward/ForwardClientSocketClientHandler.java index 54d31db05ed..74623313f33 100644 --- a/labs/cluster-management/native-agent/src/main/java/com/alibaba/arthas/nat/agent/server/forward/ForwardClientSocketClientHandler.java +++ b/labs/cluster-management/native-agent/src/main/java/com/alibaba/arthas/nat/agent/server/forward/ForwardClientSocketClientHandler.java @@ -2,7 +2,6 @@ import com.alibaba.arthas.nat.agent.common.constants.NativeAgentConstants; -import com.taobao.arthas.common.ArthasConstants; import io.netty.bootstrap.Bootstrap; import io.netty.channel.*; import io.netty.channel.nio.NioEventLoopGroup; @@ -67,7 +66,7 @@ protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(new LoggingHandler(LogLevel.INFO)); pipeline.addLast(new HttpClientCodec()); - pipeline.addLast(new HttpObjectAggregator(ArthasConstants.MAX_HTTP_CONTENT_LENGTH)); + pipeline.addLast(new HttpObjectAggregator(NativeAgentConstants.MAX_HTTP_CONTENT_LENGTH)); pipeline.addLast(new WebSocketClientProtocolHandler( WebSocketClientHandshakerFactory.newHandshaker( new URI("ws://127.0.0.1:" + NativeAgentConstants.ARTHAS_SERVER_HTTP_PORT + "/ws"), diff --git a/labs/cluster-management/native-agent/src/main/java/com/alibaba/arthas/nat/agent/server/forward/RelayHandler.java b/labs/cluster-management/native-agent/src/main/java/com/alibaba/arthas/nat/agent/server/forward/RelayHandler.java index ffe56b5ae4c..1bf0656b5c1 100644 --- a/labs/cluster-management/native-agent/src/main/java/com/alibaba/arthas/nat/agent/server/forward/RelayHandler.java +++ b/labs/cluster-management/native-agent/src/main/java/com/alibaba/arthas/nat/agent/server/forward/RelayHandler.java @@ -1,8 +1,8 @@ package com.alibaba.arthas.nat.agent.server.forward; -import com.alibaba.arthas.tunnel.client.ChannelUtils; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; +import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.util.ReferenceCountUtil; @@ -40,7 +40,7 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) { @Override public void channelInactive(ChannelHandlerContext ctx) { if (relayChannel.isActive()) { - ChannelUtils.closeOnFlush(relayChannel); + ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE); } } diff --git a/labs/cluster-management/native-agent/src/main/java/com/alibaba/arthas/nat/agent/server/http/HttpNativeAgentHandler.java b/labs/cluster-management/native-agent/src/main/java/com/alibaba/arthas/nat/agent/server/http/HttpNativeAgentHandler.java index 278ca16f6dc..67235bed6bb 100644 --- a/labs/cluster-management/native-agent/src/main/java/com/alibaba/arthas/nat/agent/server/http/HttpNativeAgentHandler.java +++ b/labs/cluster-management/native-agent/src/main/java/com/alibaba/arthas/nat/agent/server/http/HttpNativeAgentHandler.java @@ -75,7 +75,7 @@ private FullHttpResponse doAttachJvm(ChannelHandlerContext ctx, FullHttpRequest private FullHttpResponse doListProcess(ChannelHandlerContext ctx, FullHttpRequest request) { Map processMap = null; try { - processMap = ListJvmProcessHandler.listJvmProcessByInvoke(); + processMap = ListJvmProcessHandler.listProcessByJps(); } catch (Exception e) { throw new RuntimeException(e); } diff --git a/labs/cluster-management/native-agent/src/main/resources/META-INF/arthas/com.alibaba.arthas.native.agent.NativeAgentRegistryFactory b/labs/cluster-management/native-agent/src/main/resources/META-INF/arthas/com.alibaba.arthas.native.agent.NativeAgentRegistryFactory index b87b4a3a776..1b27469c9d9 100644 --- a/labs/cluster-management/native-agent/src/main/resources/META-INF/arthas/com.alibaba.arthas.native.agent.NativeAgentRegistryFactory +++ b/labs/cluster-management/native-agent/src/main/resources/META-INF/arthas/com.alibaba.arthas.native.agent.NativeAgentRegistryFactory @@ -1,2 +1,3 @@ +native-agent-proxy=com.alibaba.arthas.nat.agent.registry.impl.NativeAgentProxyNativeAgentRegistry zookeeper=com.alibaba.arthas.nat.agent.registry.impl.ZookeeperNativeAgentRegistry etcd=com.alibaba.arthas.nat.agent.registry.impl.EtcdNativeAgentRegistry