add heartbeat interval option

This commit is contained in:
gongdewei
2021-05-21 17:23:59 +08:00
parent 85d1c1c108
commit d6fdd0a4e9
6 changed files with 124 additions and 52 deletions
+27 -13
View File
@@ -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;
}
@@ -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();