-
Notifications
You must be signed in to change notification settings - Fork 713
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This adds a benchmark of our canonical zipkin example. The goal is to show relative overhead, conceding some of this will be skewed a bit. EndToEndBenchmarks takes the same approach as example projects like https://github.com/openzipkin/sleuth-webmvc-example, using the fastest components we have: currently servlet and okhttp instrumentation. http://localhost:PORT/BASEPATH calls http://localhost:PORT/BASEPATH/api This simulates a simple ingress -> egress scenario EndToEndBenchmarks include the following: * server_get - uninstrumented baseline * tracedServer_get - server starts and propagates a new trace * tracedServer_get_resumeTrace - server resumes an existing trace * unsampledServer_get - server doesn't sample, but propagates Here's a sample run: ``` Benchmark Mode Cnt Score Error Units EndToEndBenchmarks.server_get avgt 15 141.483 ± 9.793 us/op EndToEndBenchmarks.tracedServer_get avgt 15 160.231 ± 3.479 us/op EndToEndBenchmarks.tracedServer_get_resumeTrace avgt 15 165.453 ± 7.216 us/op EndToEndBenchmarks.unsampledServer_get avgt 15 153.022 ± 4.111 us/op ``` In this case, it appears resuming a trace takes longer than starting a new one. While this can be explained, having benchmarks allow us to drive numbers down relatively objectively.
- Loading branch information
1 parent
2014931
commit 7c6e56c
Showing
6 changed files
with
169 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
120 changes: 120 additions & 0 deletions
120
instrumentation/benchmarks/src/main/java/brave/EndToEndBenchmarks.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
package brave; | ||
|
||
import brave.http.HttpServerBenchmarks; | ||
import brave.okhttp3.TracingCallFactory; | ||
import brave.sampler.Sampler; | ||
import brave.servlet.TracingFilter; | ||
import io.undertow.servlet.Servlets; | ||
import io.undertow.servlet.api.DeploymentInfo; | ||
import io.undertow.servlet.api.FilterInfo; | ||
import java.io.IOException; | ||
import java.util.Date; | ||
import javax.servlet.Filter; | ||
import javax.servlet.FilterChain; | ||
import javax.servlet.FilterConfig; | ||
import javax.servlet.ServletException; | ||
import javax.servlet.ServletRequest; | ||
import javax.servlet.ServletResponse; | ||
import javax.servlet.http.HttpServlet; | ||
import javax.servlet.http.HttpServletRequest; | ||
import javax.servlet.http.HttpServletResponse; | ||
import okhttp3.Call; | ||
import okhttp3.HttpUrl; | ||
import okhttp3.OkHttpClient; | ||
import okhttp3.Request; | ||
import org.openjdk.jmh.runner.Runner; | ||
import org.openjdk.jmh.runner.RunnerException; | ||
import org.openjdk.jmh.runner.options.Options; | ||
import org.openjdk.jmh.runner.options.OptionsBuilder; | ||
|
||
import static javax.servlet.DispatcherType.REQUEST; | ||
|
||
/** Uses the canonical zipkin frontend-backend app, with the fastest components */ | ||
public class EndToEndBenchmarks extends HttpServerBenchmarks { | ||
static volatile int PORT; | ||
|
||
static class HelloServlet extends HttpServlet { | ||
final Call.Factory callFactory = new OkHttpClient(); | ||
|
||
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) | ||
throws IOException { | ||
resp.addHeader("Content-Type", "text/plain; charset=UTF-8"); | ||
// regardless of how we got here, if we are "api" we just return a string | ||
if (req.getRequestURI().endsWith("/api")) { | ||
resp.getWriter().println(new Date().toString()); | ||
} else { | ||
Request request = new Request.Builder().url(new HttpUrl.Builder() | ||
.scheme("http") | ||
.host("127.0.0.1") | ||
.port(PORT) | ||
.encodedPath(req.getRequestURI() + "/api").build()).build(); | ||
|
||
// If we are tracing, we'll have a scoped call factory available | ||
Call.Factory localCallFactory = | ||
(Call.Factory) req.getAttribute(Call.Factory.class.getName()); | ||
if (localCallFactory == null) localCallFactory = callFactory; | ||
|
||
resp.getWriter().println(localCallFactory.newCall(request).execute().body().string()); | ||
} | ||
} | ||
} | ||
|
||
public static class Unsampled extends ForwardingTracingFilter { | ||
public Unsampled() { | ||
super(Tracing.newBuilder().sampler(Sampler.NEVER_SAMPLE).spanReporter(s -> { | ||
}).build()); | ||
} | ||
} | ||
|
||
public static class Traced extends ForwardingTracingFilter { | ||
public Traced() { | ||
super(Tracing.newBuilder().spanReporter(s -> { | ||
}).build()); | ||
} | ||
} | ||
|
||
@Override protected void init(DeploymentInfo servletBuilder) { | ||
servletBuilder.addFilter(new FilterInfo("Unsampled", Unsampled.class)) | ||
.addFilterUrlMapping("Unsampled", "/unsampled", REQUEST) | ||
.addFilterUrlMapping("Unsampled", "/unsampled/api", REQUEST) | ||
.addFilter(new FilterInfo("Traced", Traced.class)) | ||
.addFilterUrlMapping("Traced", "/traced", REQUEST) | ||
.addFilterUrlMapping("Traced", "/traced/api", REQUEST) | ||
.addServlets(Servlets.servlet("HelloServlet", HelloServlet.class).addMapping("/*")); | ||
} | ||
|
||
@Override protected int initServer() throws ServletException { | ||
return PORT = super.initServer(); | ||
} | ||
|
||
// Convenience main entry-point | ||
public static void main(String[] args) throws RunnerException { | ||
Options opt = new OptionsBuilder() | ||
.include(".*" + EndToEndBenchmarks.class.getSimpleName() + ".*") | ||
.build(); | ||
|
||
new Runner(opt).run(); | ||
} | ||
|
||
static class ForwardingTracingFilter implements Filter { | ||
final Filter delegate; | ||
final Call.Factory callFactory; | ||
|
||
public ForwardingTracingFilter(Tracing tracing) { | ||
this.delegate = TracingFilter.create(tracing); | ||
this.callFactory = TracingCallFactory.create(tracing, new OkHttpClient()); | ||
} | ||
|
||
@Override public void init(FilterConfig filterConfig) throws ServletException { | ||
} | ||
|
||
@Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, | ||
FilterChain filterChain) throws IOException, ServletException { | ||
servletRequest.setAttribute(Call.Factory.class.getName(), callFactory); | ||
delegate.doFilter(servletRequest, servletResponse, filterChain); | ||
} | ||
|
||
@Override public void destroy() { | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters