2017-01-03 2 views
2

Ich habe eine Anwendung, die ich unter Verwendung JMH Benchmark verwenden möchte. Jede Referenz für diese Integration wird nützlich sein.Benchmarking Spring Boot-Anwendung mit JMH

+0

IMHO 'jmh' ist nicht für Benchmarking-Anwendungen geeignet, sondern nur für bestimmte Methoden. –

+1

Ich habe getan, um für Frühjahr MVC-Anwendung bechmarking.Sie sollte Weg sein, es für Spring-Boot-Anwendungen tun –

Antwort

5

Die Lösung war ziemlich einfach als ich dachte. Der wichtige Teil ist, die Spring-Boot-Anwendung zu starten, wenn der Benchmark initialisiert wird. Definieren Sie eine Klassenvariable für den Konfigurationskontext und geben Sie während der Einrichtung des Benchmarks einen Verweis darauf an. Rufen Sie die Bean-Methode im Benchmark auf.

import java.io.File; 
import java.net.URL; 
import java.net.URLClassLoader; 
import java.util.concurrent.TimeUnit; 
import org.openjdk.jmh.annotations.Benchmark; 
import org.openjdk.jmh.annotations.BenchmarkMode; 
import org.openjdk.jmh.annotations.Level; 
import org.openjdk.jmh.annotations.Mode; 
import org.openjdk.jmh.annotations.OutputTimeUnit; 
import org.openjdk.jmh.annotations.Scope; 
import org.openjdk.jmh.annotations.Setup; 
import org.openjdk.jmh.annotations.State; 
import org.openjdk.jmh.infra.Blackhole; 
import org.openjdk.jmh.runner.Runner; 
import org.openjdk.jmh.runner.options.Options; 
import org.openjdk.jmh.runner.options.OptionsBuilder; 
import org.springframework.boot.SpringApplication; 
import org.springframework.context.ConfigurableApplicationContext; 

@BenchmarkMode(Mode.Throughput) @OutputTimeUnit(TimeUnit.MINUTES) 
@State(Scope.Thread) 
public class ProcessFeedBenchMark { 

    public static void main(String args[]) throws Exception { 
     URLClassLoader classLoader = (URLClassLoader) ProcessFeedBenchMark.class.getClassLoader(); 
     StringBuilder classpath = new StringBuilder(); 
     for(URL url : classLoader.getURLs()) 
      classpath.append(url.getPath()).append(File.pathSeparator); 
     classpath.append("/D:/work/zymespace/benchmark/src/main/resources/").append(File.pathSeparator); 
     System.out.print(classpath.toString()); 
     System.setProperty("java.class.path", classpath.toString()); 

     Options opt = new OptionsBuilder() 
     .include(ProcessFeedBenchMark.class.getName() + ".*") 
     .timeUnit(TimeUnit.MILLISECONDS) 
     .threads(1) 

     .shouldFailOnError(true) 
     .shouldDoGC(true) 
     .build(); 

     new Runner(opt).run(); 
    } 
    static ConfigurableApplicationContext context; 

    private BenchmarkTestService service; 

    @Setup (Level.Trial) 
    public synchronized void initialize() { 
     try { 
      String args = ""; 
      if(context == null) { 
       context = SpringApplication.run(BenchmarkSpringBootStater.class, args); 
      } 
      service = context.getBean(BenchmarkTestService.class); 
      System.out.println(service); 
     } catch(Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    @Benchmark 
    public void benchmark1 (ProcessFeedBenchMark state, Blackhole bh) { 
     try { 
      service.li(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 
+3

Ich würde nicht auf eine Zahl verlassen, die Sie aus dieser Benchmark bekommen. Sie verlassen sich wahrscheinlich auf die Dienstkonfiguration und jeden Proxy-Mechanismus. Außerdem wird die meiste Zeit für das Drucken des Ergebnisses ausgegeben. Stattdessen sollten Sie den Dienstwert aus der Methode zurückgeben und JMH den Escape-Befehl behandeln lassen. So sollten Sie JMH nicht verwenden. –

+0

Die Anweisung System.out.println wird entfernt, um den richtigen Benchmark für die Methode li() zu erhalten. –

+0

Fantastisch, danke für das Beispiel. –