aws-xray-agent-benchmark/src/jmh/java/com/amazonaws/xray/agent/benchmark/HttpDownstreamBenchmark.java (59 lines of code) (raw):
package com.amazonaws.xray.agent.benchmark;
import com.amazonaws.xray.AWSXRay;
import com.amazonaws.xray.AWSXRayRecorder;
import com.amazonaws.xray.agent.utils.BenchmarkUtils;
import com.amazonaws.xray.agent.utils.ClientProvider;
import com.amazonaws.xray.agent.utils.SimpleJettyServer;
import com.amazonaws.xray.entities.TraceHeader;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.eclipse.jetty.server.Server;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Level;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.TearDown;
import java.io.IOException;
public class HttpDownstreamBenchmark {
private static final int PORT = 20808;
private static final String PATH = "/path/to/page";
@State(Scope.Benchmark)
public static class BenchmarkState {
CloseableHttpClient httpClient;
HttpGet httpGet;
AWSXRayRecorder recorder;
Server jettyServer;
@Setup(Level.Trial)
public void setup() {
recorder = BenchmarkUtils.configureXRayRecorder();
if (System.getProperty("com.amazonaws.xray.sdk") != null) {
httpClient = ClientProvider.instrumentedApacheHttpClient();
} else {
httpClient = ClientProvider.normalApacheHttpClient();
}
httpGet = new HttpGet("http://localhost:" + PORT + PATH);
jettyServer = SimpleJettyServer.create(PORT, PATH);
}
@TearDown(Level.Trial)
public void cleanup() {
try {
jettyServer.stop();
} catch (Exception e) {
e.printStackTrace();
} finally {
jettyServer.destroy();
}
}
}
/**
* This benchmark tests the time it takes to make a HTTP request with an Apache client wrapped in an X-Ray Segment.
* It can be tested with or without the agent running on the JVM. The segment is necessary because we only want to
* test the performance change introduced by the instrumentation of the Apache client, and without the segment we
* get CMEs, which do not accurately represent the instrumentation latency.
*
* As something of a hack, we add an additional JVM arg pointing to an agent config file in the resources directory
* that disables the agent's instrumentation of servlet requests. This prevents us from attempting to start a new
* segment when the Jetty server handles these HTTP requests, which would add latency.
*/
@Benchmark
@Fork(jvmArgsAppend = "-Dcom.amazonaws.xray.configFile=/com/amazonaws/xray/agent/agent-config.json")
public void makeHttpRequest(BenchmarkState state) throws IOException {
AWSXRay.beginSegment("Benchmark");
state.httpClient.execute(state.httpGet);
state.httpGet.releaseConnection(); // Prevents overwhelming max connections
state.httpGet.removeHeaders(TraceHeader.HEADER_KEY); // Prevents Trace ID headers stacking up
AWSXRay.endSegment();
}
}