mirror of
https://github.com/alibaba/arthas.git
synced 2024-04-21 10:21:39 +00:00
add heartbeat interval option
This commit is contained in:
@@ -134,12 +134,15 @@ COMMAND=
|
||||
# batch file to execute
|
||||
BATCH_FILE=
|
||||
|
||||
# tunnel server url
|
||||
TUNNEL_SERVER=
|
||||
|
||||
# channel server address
|
||||
CHANNEL_SERVER=
|
||||
|
||||
# channel client heartbeat interval seconds
|
||||
HEARTBEAT_INTERVAL=
|
||||
|
||||
# tunnel server url
|
||||
TUNNEL_SERVER=
|
||||
|
||||
# agent id
|
||||
AGENT_ID=
|
||||
|
||||
@@ -406,7 +409,7 @@ usage()
|
||||
Usage:
|
||||
$0 [-h] [--target-ip <value>] [--telnet-port <value>]
|
||||
[--http-port <value>] [--session-timeout <value>] [--arthas-home <value>]
|
||||
[--channel-server <value>]
|
||||
[--channel-server <value>] [--heartbeat-interval <value>]
|
||||
[--tunnel-server <value>] [--agent-id <value>] [--stat-url <value>]
|
||||
[--app-name <value>]
|
||||
[--username <value>] [--password <value>]
|
||||
@@ -427,8 +430,9 @@ Options and Arguments:
|
||||
--use-http Enforce use http to download, default use https
|
||||
--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
|
||||
--heartbeat-interval The arthas agent (channel client) heartbeat interval seconds, default 5
|
||||
--tunnel-server Remote tunnel server url
|
||||
--agent-id Special agent id
|
||||
--app-name Special app name
|
||||
--username Special username
|
||||
@@ -450,6 +454,7 @@ EXAMPLES:
|
||||
./as.sh --tunnel-server 'ws://192.168.10.11:7777/ws' --app-name demoapp
|
||||
./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' --heartbeat-interval 10
|
||||
./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' <pid>
|
||||
@@ -603,13 +608,18 @@ parse_arguments()
|
||||
shift # past argument
|
||||
shift # past value
|
||||
;;
|
||||
--tunnel-server)
|
||||
TUNNEL_SERVER="$2"
|
||||
--channel-server)
|
||||
CHANNEL_SERVER="$2"
|
||||
shift # past argument
|
||||
shift # past value
|
||||
;;
|
||||
--channel-server)
|
||||
CHANNEL_SERVER="$2"
|
||||
--heartbeat-interval)
|
||||
HEARTBEAT_INTERVAL="$2"
|
||||
shift # past argument
|
||||
shift # past value
|
||||
;;
|
||||
--tunnel-server)
|
||||
TUNNEL_SERVER="$2"
|
||||
shift # past argument
|
||||
shift # past value
|
||||
;;
|
||||
@@ -819,14 +829,18 @@ attach_jvm()
|
||||
fi
|
||||
|
||||
local tempArgs=()
|
||||
if [ "${TUNNEL_SERVER}" ]; then
|
||||
tempArgs+=("-tunnel-server")
|
||||
tempArgs+=("${TUNNEL_SERVER}")
|
||||
fi
|
||||
if [ "${CHANNEL_SERVER}" ]; then
|
||||
tempArgs+=("-channel-server")
|
||||
tempArgs+=("${CHANNEL_SERVER}")
|
||||
fi
|
||||
if [ "${HEARTBEAT_INTERVAL}" ]; then
|
||||
tempArgs+=("-heartbeat-interval")
|
||||
tempArgs+=("${CHANNEL_SERVER}")
|
||||
fi
|
||||
if [ "${TUNNEL_SERVER}" ]; then
|
||||
tempArgs+=("-tunnel-server")
|
||||
tempArgs+=("${TUNNEL_SERVER}")
|
||||
fi
|
||||
if [ "${AGENT_ID}" ]; then
|
||||
tempArgs+=("-agent-id")
|
||||
tempArgs+=("${AGENT_ID}")
|
||||
|
||||
@@ -31,6 +31,7 @@ import com.taobao.middleware.cli.CommandLine;
|
||||
import com.taobao.middleware.cli.UsageMessageFormatter;
|
||||
import com.taobao.middleware.cli.annotations.Argument;
|
||||
import com.taobao.middleware.cli.annotations.CLIConfigurator;
|
||||
import com.taobao.middleware.cli.annotations.DefaultValue;
|
||||
import com.taobao.middleware.cli.annotations.Description;
|
||||
import com.taobao.middleware.cli.annotations.Name;
|
||||
import com.taobao.middleware.cli.annotations.Option;
|
||||
@@ -51,6 +52,7 @@ import static com.taobao.arthas.boot.ProcessUtils.STATUS_EXEC_TIMEOUT;
|
||||
+ " java -jar arthas-boot.jar --tunnel-server 'ws://192.168.10.11:7777/ws' --app-name demoapp\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' --heartbeat-interval 10\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' <pid>\n"
|
||||
@@ -118,8 +120,10 @@ public class Bootstrap {
|
||||
private String command;
|
||||
private String batchFile;
|
||||
|
||||
private String tunnelServer;
|
||||
private String channelServer;
|
||||
private int heartbeatInterval;
|
||||
|
||||
private String tunnelServer;
|
||||
private String agentId;
|
||||
|
||||
private String appName;
|
||||
@@ -255,18 +259,25 @@ public class Bootstrap {
|
||||
this.verbose = verbose;
|
||||
}
|
||||
|
||||
@Option(longName = "tunnel-server")
|
||||
@Description("The tunnel server url")
|
||||
public void setTunnelServer(String tunnelServer) {
|
||||
this.tunnelServer = tunnelServer;
|
||||
}
|
||||
|
||||
@Option(longName = "channel-server")
|
||||
@Description("The channel server address")
|
||||
public void setChannelServer(String channelServer) {
|
||||
this.channelServer = channelServer;
|
||||
}
|
||||
|
||||
@Option(longName = "heartbeat-interval")
|
||||
@DefaultValue("5")
|
||||
@Description("The arthas agent (channel client) heartbeat interval seconds")
|
||||
public void setHeartbeatInterval(int heartbeatInterval) {
|
||||
this.heartbeatInterval = heartbeatInterval;
|
||||
}
|
||||
|
||||
@Option(longName = "tunnel-server")
|
||||
@Description("The tunnel server url")
|
||||
public void setTunnelServer(String tunnelServer) {
|
||||
this.tunnelServer = tunnelServer;
|
||||
}
|
||||
|
||||
@Option(longName = "agent-id")
|
||||
@Description("The agent id register to tunnel server")
|
||||
public void setAgentId(String agentId) {
|
||||
@@ -837,14 +848,18 @@ public class Bootstrap {
|
||||
return width;
|
||||
}
|
||||
|
||||
public String getTunnelServer() {
|
||||
return tunnelServer;
|
||||
}
|
||||
|
||||
public String getChannelServer() {
|
||||
return channelServer;
|
||||
}
|
||||
|
||||
public int getHeartbeatInterval() {
|
||||
return heartbeatInterval;
|
||||
}
|
||||
|
||||
public String getTunnelServer() {
|
||||
return tunnelServer;
|
||||
}
|
||||
|
||||
public String getAgentId() {
|
||||
return agentId;
|
||||
}
|
||||
|
||||
+26
-8
@@ -46,12 +46,14 @@ public class ChannelClient {
|
||||
private ManagedChannel channel;
|
||||
private ScheduledFuture<?> reconnectFuture;
|
||||
private String channelServerAddress;
|
||||
private int reconnectDelay = 5000;
|
||||
private int reconnectDelay = 5;
|
||||
private int heartbeatInterval = 5;
|
||||
private EventLoopGroup group;
|
||||
|
||||
//channel info
|
||||
private String channelVersion = "1.0.0";
|
||||
private List<String> channelFeatures = Arrays.asList("WebConsole", "ExecuteCommand");
|
||||
private long lastHeartbeatTime;
|
||||
|
||||
public ChannelClient(String host, int port) {
|
||||
this.host = host;
|
||||
@@ -263,7 +265,7 @@ public class ChannelClient {
|
||||
public void onCompleted() {
|
||||
}
|
||||
});
|
||||
|
||||
lastHeartbeatTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
//多线程发送数据貌似会出现错误,加上synchronized后没有出现错误
|
||||
@@ -280,6 +282,7 @@ public class ChannelClient {
|
||||
}
|
||||
|
||||
private void scheduleReconnectTask() {
|
||||
logger.info("Agent reconnect delay seconds: "+reconnectDelay+", heartbeat interval seconds: "+heartbeatInterval);
|
||||
reconnectFuture = executorService.scheduleWithFixedDelay(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -307,14 +310,17 @@ public class ChannelClient {
|
||||
}
|
||||
} else {
|
||||
// send heartbeat
|
||||
try {
|
||||
sendHeartbeat(arthasServiceStub);
|
||||
} catch (Throwable e) {
|
||||
logger.error("send heartbeat failure", e);
|
||||
long delta = System.currentTimeMillis() - lastHeartbeatTime;
|
||||
if (delta >= heartbeatInterval * 1000) {
|
||||
try {
|
||||
sendHeartbeat(arthasServiceStub);
|
||||
} catch (Throwable e) {
|
||||
logger.error("send heartbeat failure", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, reconnectDelay, reconnectDelay, TimeUnit.MILLISECONDS);
|
||||
}, reconnectDelay, reconnectDelay, TimeUnit.SECONDS);
|
||||
|
||||
}
|
||||
|
||||
@@ -374,13 +380,25 @@ public class ChannelClient {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set reconnect delay time (ms)
|
||||
* Set reconnect delay seconds
|
||||
* @param reconnectDelay
|
||||
*/
|
||||
public void setReconnectDelay(int reconnectDelay) {
|
||||
this.reconnectDelay = reconnectDelay;
|
||||
}
|
||||
|
||||
public int getHeartbeatInterval() {
|
||||
return heartbeatInterval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set heartbeat interval seconds
|
||||
* @param heartbeatInterval
|
||||
*/
|
||||
public void setHeartbeatInterval(int heartbeatInterval) {
|
||||
this.heartbeatInterval = heartbeatInterval;
|
||||
}
|
||||
|
||||
public ScheduledExecutorService getExecutorService() {
|
||||
return executorService;
|
||||
}
|
||||
|
||||
@@ -27,32 +27,31 @@ public class Arthas {
|
||||
}
|
||||
|
||||
private Configure parse(String[] args) {
|
||||
Option pid = new TypedOption<Long>().setType(Long.class).setShortName("pid").setRequired(true);
|
||||
Option core = new TypedOption<String>().setType(String.class).setShortName("core").setRequired(true);
|
||||
Option agent = new TypedOption<String>().setType(String.class).setShortName("agent").setRequired(true);
|
||||
Option target = new TypedOption<String>().setType(String.class).setShortName("target-ip");
|
||||
Option telnetPort = new TypedOption<Integer>().setType(Integer.class)
|
||||
.setShortName("telnet-port");
|
||||
Option httpPort = new TypedOption<Integer>().setType(Integer.class)
|
||||
.setShortName("http-port");
|
||||
Option sessionTimeout = new TypedOption<Integer>().setType(Integer.class)
|
||||
.setShortName("session-timeout");
|
||||
Option pid = createOption(Long.class, "pid", true);
|
||||
Option core = createOption(String.class, "core", true);
|
||||
Option agent = createOption(String.class, "agent", true);
|
||||
Option target = createOption(String.class, "target-ip");
|
||||
Option telnetPort = createOption(Integer.class, "telnet-port");
|
||||
Option httpPort = createOption(Integer.class, "http-port");
|
||||
Option sessionTimeout = createOption(Integer.class, "session-timeout");
|
||||
|
||||
Option username = new TypedOption<String>().setType(String.class).setShortName("username");
|
||||
Option password = new TypedOption<String>().setType(String.class).setShortName("password");
|
||||
Option username = createOption(String.class, "username");
|
||||
Option password = createOption(String.class, "password");
|
||||
|
||||
Option tunnelServer = new TypedOption<String>().setType(String.class).setShortName("tunnel-server");
|
||||
Option channelServer = new TypedOption<String>().setType(String.class).setShortName("channel-server");
|
||||
Option agentId = new TypedOption<String>().setType(String.class).setShortName("agent-id");
|
||||
Option appName = new TypedOption<String>().setType(String.class).setShortName(ArthasConstants.APP_NAME);
|
||||
Option channelServer = createOption(String.class, "channel-server");
|
||||
Option heartbeatInterval = createOption(Integer.class, "heartbeat-interval");
|
||||
|
||||
Option statUrl = new TypedOption<String>().setType(String.class).setShortName("stat-url");
|
||||
Option tunnelServer = createOption(String.class, "tunnel-server");
|
||||
Option agentId = createOption(String.class, "agent-id");
|
||||
Option appName = createOption(String.class, ArthasConstants.APP_NAME);
|
||||
|
||||
Option statUrl = createOption(String.class, "stat-url");
|
||||
|
||||
CLI cli = CLIs.create("arthas").addOption(pid).addOption(core).addOption(agent).addOption(target)
|
||||
.addOption(telnetPort).addOption(httpPort).addOption(sessionTimeout)
|
||||
.addOption(username).addOption(password)
|
||||
.addOption(tunnelServer).addOption(channelServer)
|
||||
.addOption(agentId).addOption(appName).addOption(statUrl);
|
||||
.addOption(channelServer).addOption(heartbeatInterval)
|
||||
.addOption(tunnelServer).addOption(agentId).addOption(appName).addOption(statUrl);
|
||||
CommandLine commandLine = cli.parse(Arrays.asList(args));
|
||||
|
||||
Configure configure = new Configure();
|
||||
@@ -77,14 +76,24 @@ public class Arthas {
|
||||
configure.setUsername((String) commandLine.getOptionValue("username"));
|
||||
configure.setPassword((String) commandLine.getOptionValue("password"));
|
||||
|
||||
configure.setTunnelServer((String) commandLine.getOptionValue("tunnel-server"));
|
||||
configure.setChannelServer((String) commandLine.getOptionValue("channel-server"));
|
||||
configure.setHeartbeatInterval((Integer) commandLine.getOptionValue("heartbeat-interval"));
|
||||
|
||||
configure.setTunnelServer((String) commandLine.getOptionValue("tunnel-server"));
|
||||
configure.setAgentId((String) commandLine.getOptionValue("agent-id"));
|
||||
configure.setStatUrl((String) commandLine.getOptionValue("stat-url"));
|
||||
configure.setAppName((String) commandLine.getOptionValue(ArthasConstants.APP_NAME));
|
||||
return configure;
|
||||
}
|
||||
|
||||
private <T> TypedOption<T> createOption(Class<T> type, String shortName, boolean required) {
|
||||
return new TypedOption<T>().setType(type).setShortName(shortName).setRequired(required);
|
||||
}
|
||||
|
||||
private <T> TypedOption<T> createOption(Class<T> type, String shortName) {
|
||||
return createOption(type, shortName, false);
|
||||
}
|
||||
|
||||
private void attachAgent(Configure configure) throws Exception {
|
||||
VirtualMachineDescriptor virtualMachineDescriptor = null;
|
||||
for (VirtualMachineDescriptor descriptor : VirtualMachine.list()) {
|
||||
|
||||
@@ -28,7 +28,14 @@ public class Configure {
|
||||
private String tunnelServer;
|
||||
private String agentId;
|
||||
|
||||
/**
|
||||
* Channel server address
|
||||
*/
|
||||
private String channelServer;
|
||||
/**
|
||||
* Agent (Channel client) heartbeat interval seconds
|
||||
*/
|
||||
private int heartbeatInterval = 5;
|
||||
|
||||
private String username;
|
||||
private String password;
|
||||
@@ -134,6 +141,14 @@ public class Configure {
|
||||
this.channelServer = channelServer;
|
||||
}
|
||||
|
||||
public int getHeartbeatInterval() {
|
||||
return heartbeatInterval;
|
||||
}
|
||||
|
||||
public void setHeartbeatInterval(int heartbeatInterval) {
|
||||
this.heartbeatInterval = heartbeatInterval;
|
||||
}
|
||||
|
||||
public String getAgentId() {
|
||||
return agentId;
|
||||
}
|
||||
|
||||
@@ -457,6 +457,7 @@ public class ArthasBootstrap {
|
||||
if (configure.getChannelServer() != null) {
|
||||
try {
|
||||
channelClient = new ChannelClient(configure.getChannelServer());
|
||||
channelClient.setHeartbeatInterval(configure.getHeartbeatInterval());
|
||||
channelClient.setAgentInfoService(new AgentInfoServiceImpl(channelClient, configure));
|
||||
channelClient.setRequestListener(new ChannelRequestHandler(channelClient, sessionManager, historyManager));
|
||||
channelClient.start();
|
||||
|
||||
Reference in New Issue
Block a user