diff --git a/bin/as.sh b/bin/as.sh index 4b29b596c..54a1d5a4d 100755 --- a/bin/as.sh +++ b/bin/as.sh @@ -133,6 +133,10 @@ BATCH_FILE= # tunnel server url TUNNEL_SERVER= + +# channel server address +CHANNEL_SERVER= + # agent id AGENT_ID= @@ -392,7 +396,7 @@ usage() Usage: $0 [-h] [--target-ip ] [--telnet-port ] [--http-port ] [--session-timeout ] [--arthas-home ] - [--tunnel-server ] [--agent-id ] [--stat-url ] + [--tunnel-server ] [--channel-server ] [--agent-id ] [--stat-url ] [--use-version ] [--repo-mirror ] [--versions] [--use-http] [--attach-only] [-c ] [-f ] [-v] [pid] @@ -411,6 +415,7 @@ Options and Arguments: --attach-only Attach target process only, do not connect --debug-attach Debug attach agent --tunnel-server Remote tunnel server url + --channel-server Remote channel server address --agent-id Special agent id --select select target process by classname or JARfilename -c,--command Command to execute, multiple commands separated @@ -427,6 +432,8 @@ EXAMPLES: ./as.sh --telnet-port 9999 --http-port -1 ./as.sh --tunnel-server 'ws://192.168.10.11:7777/ws' ./as.sh --tunnel-server 'ws://192.168.10.11:7777/ws' --agent-id bvDOe8XbTM2pQWjF4cfw + ./as.sh --channel-server '192.168.10.11:7700' + ./as.sh --channel-server '192.168.10.11:7700' --agent-id bvDOe8XbTM2pQWjF4cfw ./as.sh --stat-url 'http://192.168.10.11:8080/api/stat' ./as.sh -c 'sysprop; thread' ./as.sh -f batch.as @@ -557,6 +564,11 @@ parse_arguments() shift # past argument shift # past value ;; + --channel-server) + CHANNEL_SERVER="$2" + shift # past argument + shift # past value + ;; --agent-id) AGENT_ID="$2" shift # past argument @@ -750,6 +762,10 @@ attach_jvm() tempArgs+=("-tunnel-server") tempArgs+=("${TUNNEL_SERVER}") fi + if [ "${CHANNEL_SERVER}" ]; then + tempArgs+=("-channel-server") + tempArgs+=("${CHANNEL_SERVER}") + fi if [ "${AGENT_ID}" ]; then tempArgs+=("-agent-id") tempArgs+=("${AGENT_ID}") diff --git a/boot/src/main/java/com/taobao/arthas/boot/Bootstrap.java b/boot/src/main/java/com/taobao/arthas/boot/Bootstrap.java index c99370132..387bbc3be 100644 --- a/boot/src/main/java/com/taobao/arthas/boot/Bootstrap.java +++ b/boot/src/main/java/com/taobao/arthas/boot/Bootstrap.java @@ -49,6 +49,8 @@ import static com.taobao.arthas.boot.ProcessUtils.STATUS_EXEC_TIMEOUT; + " java -jar arthas-boot.jar --telnet-port 9999 --http-port -1\n" + " java -jar arthas-boot.jar --tunnel-server 'ws://192.168.10.11:7777/ws'\n" + " java -jar arthas-boot.jar --tunnel-server 'ws://192.168.10.11:7777/ws' --agent-id bvDOe8XbTM2pQWjF4cfw\n" + + " java -jar arthas-boot.jar --channel-server '192.168.10.11:7700'\n" + + " java -jar arthas-boot.jar --channel-server '192.168.10.11:7700' --agent-id bvDOe8XbTM2pQWjF4cfw\n" + " java -jar arthas-boot.jar --stat-url 'http://192.168.10.11:8080/api/stat'\n" + " java -jar arthas-boot.jar -c 'sysprop; thread' \n" + " java -jar arthas-boot.jar -f batch.as \n" @@ -116,6 +118,7 @@ public class Bootstrap { private String batchFile; private String tunnelServer; + private String channelServer; private String agentId; private String statUrl; @@ -252,6 +255,12 @@ public class Bootstrap { this.tunnelServer = tunnelServer; } + @Option(longName = "channel-server") + @Description("The channel server address") + public void setChannelServer(String channelServer) { + this.channelServer = channelServer; + } + @Option(longName = "agent-id") @Description("The agent id register to tunnel server") public void setAgentId(String agentId) { @@ -492,6 +501,10 @@ public class Bootstrap { attachArgs.add("-tunnel-server"); attachArgs.add(bootstrap.getTunnelServer()); } + if (bootstrap.getChannelServer() != null) { + attachArgs.add("-channel-server"); + attachArgs.add(bootstrap.getChannelServer()); + } if (bootstrap.getAgentId() != null) { attachArgs.add("-agent-id"); attachArgs.add(bootstrap.getAgentId()); @@ -756,6 +769,10 @@ public class Bootstrap { return tunnelServer; } + public String getChannelServer() { + return channelServer; + } + public String getAgentId() { return agentId; } diff --git a/core/src/main/java/arthas.properties b/core/src/main/java/arthas.properties index 8a906de63..96e582968 100644 --- a/core/src/main/java/arthas.properties +++ b/core/src/main/java/arthas.properties @@ -3,5 +3,13 @@ arthas.telnetPort=3658 arthas.httpPort=8563 arthas.ip=localhost -#arthas.tunnelServer=ws://127.0.0.1:7777/ws +# If you customize the agent id, ensure that each agent id is unique. +# Otherwise, a random agent id will be automatically generated. #arthas.agentId=mmmmmmyiddddd + +# tunnel server url +#arthas.tunnelServer=ws://127.0.0.1:7777/ws + +# channel server address +#arthas.channelServer=127.0.0.1:7700 + diff --git a/core/src/main/java/com/taobao/arthas/core/Arthas.java b/core/src/main/java/com/taobao/arthas/core/Arthas.java index 901e3f364..ab9f645b3 100644 --- a/core/src/main/java/com/taobao/arthas/core/Arthas.java +++ b/core/src/main/java/com/taobao/arthas/core/Arthas.java @@ -41,12 +41,15 @@ public class Arthas { .setShortName("session-timeout").setDefaultValue("" + Configure.DEFAULT_SESSION_TIMEOUT_SECONDS); Option tunnelServer = new TypedOption().setType(String.class).setShortName("tunnel-server"); + Option channelServer = new TypedOption().setType(String.class).setShortName("channel-server"); Option agentId = new TypedOption().setType(String.class).setShortName("agent-id"); Option statUrl = new TypedOption().setType(String.class).setShortName("stat-url"); CLI cli = CLIs.create("arthas").addOption(pid).addOption(core).addOption(agent).addOption(target) - .addOption(telnetPort).addOption(httpPort).addOption(sessionTimeout).addOption(tunnelServer).addOption(agentId).addOption(statUrl); + .addOption(telnetPort).addOption(httpPort).addOption(sessionTimeout) + .addOption(tunnelServer).addOption(channelServer).addOption(agentId) + .addOption(statUrl); CommandLine commandLine = cli.parse(Arrays.asList(args)); Configure configure = new Configure(); @@ -64,6 +67,7 @@ public class Arthas { configure.setHttpPort((Integer) commandLine.getOptionValue("http-port")); configure.setTunnelServer((String) commandLine.getOptionValue("tunnel-server")); + configure.setChannelServer((String) commandLine.getOptionValue("channel-server")); configure.setAgentId((String) commandLine.getOptionValue("agent-id")); configure.setStatUrl((String) commandLine.getOptionValue("stat-url")); return configure; diff --git a/core/src/main/java/com/taobao/arthas/core/config/Configure.java b/core/src/main/java/com/taobao/arthas/core/config/Configure.java index 17a62d868..3075acb8c 100644 --- a/core/src/main/java/com/taobao/arthas/core/config/Configure.java +++ b/core/src/main/java/com/taobao/arthas/core/config/Configure.java @@ -28,6 +28,8 @@ public class Configure { private String tunnelServer; private String agentId; + private String channelServer; + /** * report executed command */ @@ -102,6 +104,14 @@ public class Configure { this.tunnelServer = tunnelServer; } + public String getChannelServer() { + return channelServer; + } + + public void setChannelServer(String channelServer) { + this.channelServer = channelServer; + } + public String getAgentId() { return agentId; } diff --git a/core/src/main/java/com/taobao/arthas/core/server/ArthasBootstrap.java b/core/src/main/java/com/taobao/arthas/core/server/ArthasBootstrap.java index 10b33c904..8e3067f67 100644 --- a/core/src/main/java/com/taobao/arthas/core/server/ArthasBootstrap.java +++ b/core/src/main/java/com/taobao/arthas/core/server/ArthasBootstrap.java @@ -56,6 +56,7 @@ import com.taobao.arthas.core.shell.term.impl.httptelnet.HttpTelnetTermServer; import com.taobao.arthas.core.util.ArthasBanner; import com.taobao.arthas.core.util.FileUtils; import com.taobao.arthas.core.util.LogUtil; +import com.taobao.arthas.core.util.StringUtils; import com.taobao.arthas.core.util.UserStatUtil; import io.netty.channel.ChannelFuture; import io.netty.channel.nio.NioEventLoopGroup; @@ -279,7 +280,13 @@ public class ArthasBootstrap { throw new IllegalStateException("already bind"); } - String agentId = null; + //check and gen agent id + if (configure.getChannelServer() != null || configure.getTunnelServer() != null) { + if (StringUtils.isBlank(configure.getAgentId())) { + configure.setAgentId(generateRandomAgentId()); + } + } + try { if (configure.getTunnelServer() != null && configure.getHttpPort() > 0) { tunnelClient = new TunnelClient(); @@ -295,7 +302,7 @@ public class ArthasBootstrap { ChannelFuture channelFuture = tunnelClient.start(); channelFuture.await(10, TimeUnit.SECONDS); if(channelFuture.isSuccess()) { - agentId = tunnelClient.getId(); + configure.setAgentId(tunnelClient.getId()); } } } catch (Throwable t) { @@ -308,13 +315,10 @@ public class ArthasBootstrap { .setPid(PidUtils.currentLongPid()) .setSessionTimeout(configure.getSessionTimeout() * 1000); - if (agentId == null) { - agentId = generateRandomAgentId(); - } - if (agentId != null) { - configure.setAgentId(agentId); + + if (configure.getAgentId() != null) { Map welcomeInfos = new HashMap(); - welcomeInfos.put("id", agentId); + welcomeInfos.put("id", configure.getAgentId()); options.setWelcomeMessage(ArthasBanner.welcome(welcomeInfos)); } @@ -355,13 +359,17 @@ public class ArthasBootstrap { configure.getTelnetPort(), configure.getHttpPort(), options.getConnectionTimeout()); // start channel client - //TODO configure channel server - channelClient = new ChannelClient("localhost", 7700); - channelClient.setAgentInfoService(new AgentInfoServiceImpl(configure)); - channelClient.setExecutorService(executorService); - channelClient.setRequestListener(new ChannelRequestHandler(channelClient, sessionManager, historyManager)); - channelClient.start(); - + if (configure.getChannelServer() != null) { + try { + channelClient = new ChannelClient(configure.getChannelServer()); + channelClient.setAgentInfoService(new AgentInfoServiceImpl(configure)); + channelClient.setExecutorService(executorService); + channelClient.setRequestListener(new ChannelRequestHandler(channelClient, sessionManager, historyManager)); + channelClient.start(); + } catch (Throwable e) { + logger().error("start channel client failure", e); + } + } // 异步回报启动次数 if (configure.getStatUrl() != null) { @@ -520,6 +528,10 @@ public class ArthasBootstrap { return tunnelClient; } + public ChannelClient getChannelClient() { + return channelClient; + } + public ShellServer getShellServer() { return shellServer; } @@ -559,4 +571,8 @@ public class ArthasBootstrap { public HttpApiHandler getHttpApiHandler() { return httpApiHandler; } + + public Configure getConfigure() { + return configure; + } }