ArthasArthas Command处理流程
Posted 九师兄
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ArthasArthas Command处理流程相关的知识,希望对你有一定的参考价值。
1.概述
2.开篇
这篇文章主要是为了分析Arthas的命令的执行过程,整体过程包括任务的创建和任务的执行。
arthas的命令都是实现统一的接口,对外通过process方法进行调用。
public abstract class AnnotatedCommand
// 不同的命令又不同的process实现
public abstract void process(CommandProcess process);
├── AbstractTraceAdviceListener.java
├── DashboardCommand.java
├── DashboardInterruptHandler.java
├── EnhancerCommand.java
├── GroovyAdviceListener.java
├── GroovyScriptCommand.java
├── HeapDumpCommand.java
├── JvmCommand.java
├── MBeanCommand.java
├── MonitorAdviceListener.java
├── MonitorCommand.java
├── MonitorData.java
├── PathTraceAdviceListener.java
├── PerfCounterCommand.java
├── ProfilerCommand.java
├── StackAdviceListener.java
├── StackCommand.java
├── ThreadCommand.java
├── ThreadSampler.java
├── TimeFragment.java
├── TimeTunnelAdviceListener.java
├── TimeTunnelCommand.java
├── TimeTunnelTable.java
├── TraceAdviceListener.java
├── TraceCommand.java
├── TraceEntity.java
├── WatchAdviceListener.java
└── WatchCommand.java
3.任务创建和执行
public class ShellLineHandler implements Handler<String>
private ShellImpl shell;
private Term term;
@Override
public void handle(String line)
List<CliToken> tokens = CliTokens.tokenize(line);
// 解析参数生成tokens,根据tokens来创建Job
Job job = createJob(tokens);
if (job != null)
// 执行任务
job.run();
// 根据请求参数创建任务
private Job createJob(List<CliToken> tokens)
Job job;
try
job = shell.createJob(tokens);
catch (Exception e)
// 省略无关代码
return job;
createJob根据传入参数创建Job对象
通过job.run()
来执行Job任务
如sc *
命令,那么根据sc关键字创建SearchClassCommand
的任务并执行
4.任务创建流程
public class ShellImpl implements Shell
private JobControllerImpl jobController;
public synchronized Job createJob(List<CliToken> args)
Job job = jobController.createJob(commandManager, args, session, new ShellJobHandler(this), term, null);
return job;
public class GlobalJobControllerImpl extends JobControllerImpl
public Job createJob(InternalCommandManager commandManager, List<CliToken> tokens, Session session, JobListener jobHandler, Term term, ResultDistributor resultDistributor)
final Job job = super.createJob(commandManager, tokens, session, jobHandler, term, resultDistributor);
JobTimeoutTask jobTimeoutTask = new JobTimeoutTask(job);
long jobTimeoutInSecond = getJobTimeoutInSecond();
Date timeoutDate = new Date(System.currentTimeMillis() + (jobTimeoutInSecond * 1000));
ArthasBootstrap.getInstance().getScheduledExecutorService().schedule(jobTimeoutTask, jobTimeoutInSecond, TimeUnit.SECONDS);
jobTimeoutTaskMap.put(job.id(), jobTimeoutTask);
job.setTimeoutDate(timeoutDate);
return job;
public class JobControllerImpl implements JobController
public Job createJob(InternalCommandManager commandManager, List<CliToken> tokens, Session session, JobListener jobHandler, Term term, ResultDistributor resultDistributor)
checkPermission(session, tokens.get(0));
int jobId = idGenerator.incrementAndGet();
StringBuilder line = new StringBuilder();
for (CliToken arg : tokens)
line.append(arg.raw());
boolean runInBackground = runInBackground(tokens);
// 根据tokens创建Process对象
Process process = createProcess(session, tokens, commandManager, jobId, term, resultDistributor);
process.setJobId(jobId);
// 创建JobImpl包含Process对象
JobImpl job = new JobImpl(jobId, this, process, line.toString(), runInBackground, session, jobHandler);
jobs.put(jobId, job);
return job;
createProcess创建tokens对应的Process对象
JobImpl将创建的Process对象进行封装,Job的执行会调用Process的方法
public class JobControllerImpl implements JobController
private Process createProcess(Session session, List<CliToken> line, InternalCommandManager commandManager, int jobId, Term term, ResultDistributor resultDistributor)
try
ListIterator<CliToken> tokens = line.listIterator();
while (tokens.hasNext())
CliToken token = tokens.next();
if (token.isText())
// check before create process
checkPermission(session, token);
// 1、获取命令对应的处理函数对象Command
Command command = commandManager.getCommand(token.value());
if (command != null)
// 2、创建Process对象
return createCommandProcess(command, tokens, jobId, term, resultDistributor);
else
throw new IllegalArgumentException(token.value() + ": command not found");
throw new IllegalArgumentException();
catch (Exception e)
private Process createCommandProcess(Command command, ListIterator<CliToken> tokens, int jobId, Term term, ResultDistributor resultDistributor) throws IOException
// 省略相关代码
ProcessImpl process = new ProcessImpl(command, remaining, command.processHandler(), ProcessOutput, resultDistributor);
process.setTty(term);
return process;
public class InternalCommandManager
private final List<CommandResolver> resolvers;
public InternalCommandManager(List<CommandResolver> resolvers)
this.resolvers = resolvers;
public Command getCommand(String commandName)
Command command = null;
for (CommandResolver resolver : resolvers)
// 内建命令在ShellLineHandler里提前处理了,所以这里不需要再查找内建命令
if (resolver instanceof BuiltinCommandPack)
command = getCommand(resolver, commandName);
if (command != null)
break;
return command;
private static Command getCommand(CommandResolver commandResolver, String name)
List<Command> commands = commandResolver.commands();
for (Command command : commands)
if (name.equals(command.name()))
return command;
根据命令的tokens去查询commands获取对应的command创建Process对象。
查询返回的command是AnnotatedCommandImpl对象。
public class BuiltinCommandPack implements CommandResolver
private static List<Command> commands = new ArrayList<Command>();
static
initCommands();
@Override
public List<Command> commands()
return commands;
private static void initCommands()
commands.add(Command.create(HelpCommand.class));
commands.add(Command.create(AuthCommand.class));
commands.add(Command.create(KeymapCommand.class));
commands.add(Command.create(SearchClassCommand.class));
commands.add(Command.create(SearchMethodCommand.class));
commands.add(Command.create(ClassLoaderCommand.class));
commands.add(Command.create(JadCommand.class));
commands.add(Command.create(GetStaticCommand.class));
commands.add(Command.create(MonitorCommand.class));
commands.add(Command.create(StackCommand.class));
commands.add(Command.create(ThreadCommand.class));
commands.add(Command.create(TraceCommand.class));
commands.add(Command.create(WatchCommand.class));
commands.add(Command.create(TimeTunnelCommand.class));
commands.add(Command.create(JvmCommand.class));
commands.add(Command.create(PerfCounterCommand.class));
// commands.add(Command.create(GroovyScriptCommand.class));
commands.add(Command.create(OgnlCommand.class));
commands.add(Command.create(MemoryCompilerCommand.class));
commands.add(Command.create(RedefineCommand.class));
commands.add(Command.create(RetransformCommand.class));
commands.add(Command.create(DashboardCommand.class));
commands.add(Command.create(DumpClassCommand.class));
commands.add(Command.create(HeapDumpCommand.class));
commands.add(Command.create(JulyCommand.class));
commands.add(Command.create(ThanksCommand.class));
commands.add(Command.create(OptionsCommand.class));
commands.add(Command.create(ClsCommand.class));
commands.add(Command.create(ResetCommand.class));
commands.add(Command.create(VersionCommand.class));
commands.add(Command.create(SessionCommand.class));
commands.add(Command.create(SystemPropertyCommand.class));
commands.add(Command.create(SystemEnvCommand.class));
commands.add(Command.create(VMOptionCommand.class));
commands.add(Command.create(LoggerCommand.class));
commands.add(Command.create(HistoryCommand.class));
commands.add(Command.create(CatCommand.class));
commands.add(Command.create(Base64Command.class));
commands.add(Command.create(EchoCommand.class));
commands.add(Command.create(PwdCommand.class));
commands.add(Command.create(MBeanCommand.class));
commands.add(Command.create(GrepCommand.class));
commands.add(Command.create(TeeCommand.class));
commands.add(Command.create(ProfilerCommand.class));
commands.add(Command.create(ShutdownCommand.class));
commands.add(Command.create(StopCommand.class));
public abstract class Command
public static Command create(final Class<? extends AnnotatedCommand> clazz)
return new AnnotatedCommandImpl(clazz);
public class AnnotatedCommandImpl extends Command
private CLI cli;
private Class<? extends AnnotatedCommand> clazz;
private Handler<CommandProcess> processHandler <以上是关于ArthasArthas Command处理流程的主要内容,如果未能解决你的问题,请参考以下文章
ArthasArthas使用watch命令(生产上查看方法出入参)