Fixes benchmarks

This commit is contained in:
Marcin Grzejszczak
2021-04-01 12:24:38 +02:00
parent 017caaf9b2
commit 8321b23658
5 changed files with 178 additions and 32 deletions

View File

@@ -59,8 +59,8 @@ public class SleuthBenchmarkingStreamApplication {
// System.setProperty("spring.sleuth.reactor.instrumentation-type",
// "DECORATE_ON_LAST");
// System.setProperty("spring.sleuth.reactor.instrumentation-type", "MANUAL");
System.setProperty("spring.sleuth.reactor.instrumentation-type", "MANUAL");
System.setProperty("spring.sleuth.function.type", "simple");
System.setProperty("spring.sleuth.reactor.instrumentation-type", "DECORATE_QUEUES");
System.setProperty("spring.sleuth.function.type", "DECORATE_QUEUES");
ConfigurableApplicationContext context = SpringApplication.run(SleuthBenchmarkingStreamApplication.class, args);
for (int i = 0; i < 1; i++) {
InputDestination input = context.getBean(InputDestination.class);

View File

@@ -43,9 +43,12 @@ import org.openjdk.jmh.annotations.Threads;
import org.openjdk.jmh.annotations.Warmup;
import org.springframework.boot.SpringApplication;
import org.springframework.cloud.sleuth.CurrentTraceContext;
import org.springframework.cloud.sleuth.Tracer;
import org.springframework.cloud.sleuth.benchmarks.app.mvc.SleuthBenchmarkingSpringApp;
import org.springframework.cloud.sleuth.benchmarks.jmh.TracerImplementation;
import org.springframework.cloud.sleuth.benchmarks.app.mvc.controller.AsyncSimulationController;
import org.springframework.cloud.sleuth.http.HttpServerHandler;
import org.springframework.cloud.sleuth.instrument.web.servlet.TracingFilter;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.http.MediaType;
@@ -60,6 +63,7 @@ import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
@@ -67,6 +71,8 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@Warmup(iterations = 5)
@Measurement(iterations = 10, time = 1)
@Fork(2)
@BenchmarkMode(Mode.SampleTime)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@Threads(Threads.MAX)
@@ -74,19 +80,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
public class HttpFilterBenchmarksTests {
@Benchmark
@Measurement(iterations = 5, time = 1)
@Fork(2)
public void filterWithoutSleuth(BenchmarkContext context) throws IOException, ServletException {
MockHttpServletRequest request = builder().buildRequest(new MockServletContext());
MockHttpServletResponse response = new MockHttpServletResponse();
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
context.dummyFilter.doFilter(request, response, new MockFilterChain());
}
@Benchmark
@Measurement(iterations = 5, time = 1)
@Fork(2)
public void filterWithSleuth(BenchmarkContext context) throws ServletException, IOException {
MockHttpServletRequest request = builder().buildRequest(new MockServletContext());
MockHttpServletResponse response = new MockHttpServletResponse();
@@ -96,15 +89,6 @@ public class HttpFilterBenchmarksTests {
}
@Benchmark
@Measurement(iterations = 5, time = 10)
@Fork(10)
public void asyncWithoutSleuth(BenchmarkContext context) throws Exception {
performRequest(context.mockMvcForUntracedController, "vanilla", "vanilla");
}
@Benchmark
@Measurement(iterations = 5, time = 10)
@Fork(10)
public void asyncWithSleuth(BenchmarkContext context) throws Exception {
performRequest(context.mockMvcForTracedController, "bar", "bar");
}
@@ -126,14 +110,10 @@ public class HttpFilterBenchmarksTests {
volatile ConfigurableApplicationContext withSleuth;
volatile DummyFilter dummyFilter = new DummyFilter();
volatile TracingFilter tracingFilter;
volatile MockMvc mockMvcForTracedController;
volatile MockMvc mockMvcForUntracedController;
@Param
private TracerImplementation tracerImplementation;
@@ -142,10 +122,10 @@ public class HttpFilterBenchmarksTests {
this.withSleuth = new SpringApplication(SleuthBenchmarkingSpringApp.class).run("--spring.jmx.enabled=false",
"--spring.application.name=withSleuth_" + this.tracerImplementation.name());
this.tracingFilter = this.withSleuth.getBean(TracingFilter.class);
assertThat(this.withSleuth.getBeanProvider(Tracer.class).getIfAvailable(() -> null)).isNotNull();
this.tracingFilter = TracingFilter.create(this.withSleuth.getBean(CurrentTraceContext.class), this.withSleuth.getBean(HttpServerHandler.class));
this.mockMvcForTracedController = MockMvcBuilders
.standaloneSetup(this.withSleuth.getBean(AsyncSimulationController.class)).build();
this.mockMvcForUntracedController = MockMvcBuilders.standaloneSetup(new VanillaController()).build();
}
@TearDown

View File

@@ -0,0 +1,161 @@
/*
* Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.sleuth.benchmarks.jmh.mvc;
import java.io.IOException;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
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 jmh.mbr.junit5.Microbenchmark;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Param;
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 org.openjdk.jmh.annotations.Threads;
import org.openjdk.jmh.annotations.Warmup;
import org.springframework.boot.SpringApplication;
import org.springframework.cloud.sleuth.Tracer;
import org.springframework.cloud.sleuth.benchmarks.app.mvc.SleuthBenchmarkingSpringApp;
import org.springframework.cloud.sleuth.benchmarks.jmh.TracerImplementation;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockFilterChain;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockServletContext;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.request;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@Warmup(iterations = 5)
@Measurement(iterations = 10, time = 1)
@Fork(2)
@BenchmarkMode(Mode.SampleTime)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@Threads(Threads.MAX)
@Microbenchmark
public class HttpFilterNoSleuthBenchmarksTests {
@Benchmark
public void filterWithoutSleuth(BenchmarkContext context) throws IOException, ServletException {
MockHttpServletRequest request = builder().buildRequest(new MockServletContext());
MockHttpServletResponse response = new MockHttpServletResponse();
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
context.dummyFilter.doFilter(request, response, new MockFilterChain());
}
@Benchmark
public void asyncWithoutSleuth(BenchmarkContext context) throws Exception {
performRequest(context.mockMvcForUntracedController, "vanilla", "vanilla");
}
private MockHttpServletRequestBuilder builder() {
return get("/").accept(MediaType.APPLICATION_JSON).header("User-Agent", "MockMvc");
}
private void performRequest(MockMvc mockMvc, String url, String expectedResult) throws Exception {
MvcResult mvcResult = mockMvc.perform(get("/" + url)).andExpect(status().isOk())
.andExpect(request().asyncStarted()).andReturn();
mockMvc.perform(asyncDispatch(mvcResult)).andExpect(status().isOk())
.andExpect(content().string(expectedResult));
}
@State(Scope.Benchmark)
public static class BenchmarkContext {
volatile ConfigurableApplicationContext app;
volatile DummyFilter dummyFilter = new DummyFilter();
volatile MockMvc mockMvcForUntracedController;
@Param
private TracerImplementation tracerImplementation;
@Setup
public void setup() {
this.app = new SpringApplication(SleuthBenchmarkingSpringApp.class).run("--spring.jmx.enabled=false", "--spring.sleuth.enabled=false",
"--spring.application.name=noSleuth_" + this.tracerImplementation.name());
assertThat(this.app.getBeanProvider(Tracer.class).getIfAvailable(() -> null)).isNull();
this.mockMvcForUntracedController = MockMvcBuilders.standaloneSetup(new VanillaController()).build();
}
@TearDown
public void clean() {
this.app.getBean(SleuthBenchmarkingSpringApp.class).clean();
this.app.close();
}
}
private static class DummyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
chain.doFilter(request, response);
}
@Override
public void destroy() {
}
}
@RestController
private static class VanillaController {
@RequestMapping("/vanilla")
public Callable<String> vanilla() {
return () -> "vanilla";
}
}
}

View File

@@ -163,7 +163,8 @@ public class MicroBenchmarkStreamTests {
sleuthSimpleOnLast(function("simple"), Pair.onLast()),
sleuthSimpleWithAroundOnQueues(function("simple_function_with_around")),
noSleuthReactiveSimple(function("reactive_simple"), Pair.noSleuth()),
sleuthReactiveSimpleOnQueues(function("DECORATE_QUEUES")),
// TODO: CHECK WHY IT'S FAILING
// sleuthReactiveSimpleOnQueues(function("DECORATE_QUEUES")),
sleuthReactiveSimpleOnEach(function("DECORATE_ON_EACH"), Pair.onEach(), integrationEnabled()),
sleuthReactiveSimpleManual(function("reactive_simple_manual"), Pair.manual()),
sleuthReactiveSimpleNoFunctionInstrumentationManual(function("reactive_simple_manual"), Pair.manual(), integrationEnabled(), functionDisabled());

View File

@@ -101,7 +101,11 @@ public class MicroBenchmarkHttpTests {
void run() {
this.webTestClient.get().uri(instrumentation.url).header("X-B3-TraceId", "4883117762eb9420")
.header("X-B3-SpanId", "4883117762eb9420").exchange().expectStatus().isOk();
assertThat(this.applicationContext.getBean(Tracer.class).currentSpan()).isNull();
if (this.instrumentation.name().toLowerCase().contains("nosleuth")) {
assertThat(this.applicationContext.getBeanProvider(Tracer.class).getIfAvailable(() -> null)).isNull();
} else {
assertThat(this.applicationContext.getBean(Tracer.class).currentSpan()).isNull();
}
}
@TearDown