grinder agent 进程的主入口
class Grinder.java
public static void main(String[] args) {
try {
final Grinder grinder = new Grinder(args, logger);
//调用grinder的run方法。
grinder.run();
}
private void run() throws GrinderException {
//调用agent的run
m_agent.run();
//Agent interface.
interface Agent
//agent接口的run方法,有2个实现。agentdaemon和agentImpl
void run() throws GrinderException;
//start agent
public final class AgentDaemon implements Agent
public void run() throws GrinderException {
// 啥意思?google一下
Runtime.getRuntime().addShutdownHook(m_shutdownHook);
try {
while (true) {
//agent.run
m_delegateAgent.run();
m_logger.info("agent finished");
m_sleeper.sleepNormal(m_sleepTime);
}
}
class agentImpl
//Run the Grinder agent process.
public void run() throws GrinderException {
// 最重要的2个参数,script和properties
ScriptLocation script = null;
GrinderProperties properties;
do {
properties =
createAndMergeProperties(startMessage != null ?
startMessage.getProperties() : null);
if (startMessage != null) {
final GrinderProperties messageProperties =
startMessage.getProperties();
if (script == null) {
final File scriptFile =
properties.resolveRelativeFile(
properties.getFile(GrinderProperties.SCRIPT,
GrinderProperties.DEFAULT_SCRIPT));
script = new ScriptLocation(scriptFile);
}
//
final WorkerProcessCommandLine workerCommandLine =
new WorkerProcessCommandLine(properties,
System.getProperties(),
jvmArguments,
script.getDirectory());
// 传入script 和properties参数
workerFactory =
new ProcessWorkerFactory(
workerCommandLine, m_agentIdentity, m_fanOutStreamSender,
consoleCommunication != null, script, properties);
//
final WorkerLauncher workerLauncher =
new WorkerLauncher(properties.getInt("grinder.processes", 1),
workerFactory,
m_eventSynchronisation,
m_logger);
//启动worker进程
workerLauncher.startAllWorkers();
//Manages launching a set of workers.
class WorkerLauncher
//启动所有的workers
public void startAllWorkers() throws EngineException {
//调用startSomeWorkers方法
startSomeWorkers(m_workers.length - m_nextWorkerIndex);
}
public boolean startSomeWorkers(int numberOfWorkers)
throws EngineException {
final int numberToStart =
Math.min(numberOfWorkers, m_workers.length - m_nextWorkerIndex);
for (int i = 0; i < numberToStart; ++i) {
final int workerIndex = m_nextWorkerIndex;
//通过workerFactory的create方法,创建worker进程。
final Worker worker = m_workerFactory.create(System.out, System.err);
class AbstractWorkerFactory implements WorkerFactory
public Worker create(
OutputStream outputStream, OutputStream errorStream)
throws EngineException {
//创建一个workerId
final WorkerIdentityImplementation workerIdentity =
m_agentIdentity.createWorkerIdentity();
//传入workerID,out,error参数。创建worker进程
final Worker worker = createWorker(workerIdentity,
outputStream,
errorStream);
protected abstract Worker createWorker(
WorkerIdentityImplementation workerIdentity,
OutputStream outputStream,
OutputStream errorStream) throws EngineException;
}
//Class that starts workers as separate processes.
class ProcessWorkerFactory
@Override
protected Worker createWorker(WorkerIdentityImplementation workerIdentity,
OutputStream outputStream,
OutputStream errorStream)
throws EngineException {
return new ProcessWorker(workerIdentity,
m_commandLine,
outputStream,
errorStream);
}
// This class knows how to start a child process. It redirects the
//child process standard output and error streams to our streams.
class ProcessWorker implements Worker
private final Process m_process;
final ProcessBuilder processBuilder =
new ProcessBuilder(commandLine.getCommandList());
try {
//通过processBuilder.start。真正启动worker进程。
m_process = processBuilder.start();
}
//final class WorkerProcessCommandLine implements CommandLine
private final List<String> m_command;
@Override public List<String> getCommandList() {
return m_command;
}
m_command.add(properties.getProperty("grinder.jvm", "java"));
if (agent != null) {
try {
m_command.add("-javaagent:" +
workingDirectory.rebaseFile(agent));
}
m_command.add(token);
m_command.add("-classpath");
m_command.add(workingDirectory.rebasePath(classpath.toString()));
//worker进程的内部入口。
m_command.add(WorkerProcessEntryPoint.class.getName());
//Entry point for processes launched by the agent.
//public class WorkerProcessEntryPoint {
grinderProcess.run();
//class GrinderProcess
final GrinderProperties properties =
m_initialisationMessage.getProperties();
final short numberOfThreads =
properties.getShort("grinder.threads", (short)1);
final int duration = properties.getInt("grinder.duration", 0);
final Instrumenter instrumenter =
scriptEngineContainer.createInstrumenter();
final ThreadSynchronisation threadSynchronisation =
new ThreadSynchronisation(m_eventSynchronisation);
m_terminalLogger.info("starting threads");
//同步线程
synchronized (m_eventSynchronisation) {
m_threadStarter =
new ThreadStarterImplementation(threadSynchronisation, scriptEngine);
for (int i = 0; i < numberOfThreads; i++) {
//启动线程,执行脚本
m_threadStarter.startThread(null);
}
}
threadSynchronisation.startThreads();