2016-06-06 8 views
0

Ich habe versucht, mit den möglichen Auswirkungen einer Integration von DeferredResult und RxJava auf Spring MVC zu experimentieren. Beachten Sie die Leistungsabnahme vom norx-Endpunkt im Vergleich zu den rx-Endpunkten. Ich habe erwartet, dass die RxJava + DeferredResult-Implementierung die Vanilla-Version übertrifft (Anzahl der Anfragen, Req/Sek.). Kann mir jemand erklären, warum das passiert ist?Leistungsreduzierung bei Verwendung von DeferredResult und RxJava mit Spring MVC

Verwendung des folgenden Codes: https://gist.github.com/richardkabiling/b53eae46c4414d4341ef310bf3a070c1

@Controller 
public class SumController { 

    SecureRandom random = new SecureRandom(); 

    @RequestMapping(value = "/init") 
    public ResponseEntity<Void> init() { 
     return ResponseEntity.ok(null); 
    } 

    @RequestMapping(value = "/norx1") 
    public ResponseEntity<BigDecimal> simpleSync() { 
     return ResponseEntity.ok(getA()); 
    } 

    @RequestMapping(value = "/rx1") 
    public DeferredResult<ResponseEntity<BigDecimal>> simpleAsync() { 
     DeferredResult<ResponseEntity<BigDecimal>> result = new DeferredResult<>(); 
     Observable.create(emit(this::getA)) 
      .map(n -> ResponseEntity.ok(n)) 
      .subscribe(re -> result.setResult(re)); 
     return result; 
    } 

    @RequestMapping(value = "/norx2") 
    public ResponseEntity<BigDecimal> sync() { 
     return ResponseEntity.ok(getA().add(getB())); 
    } 

    @RequestMapping(value = "/rx2") 
    public DeferredResult<ResponseEntity<BigDecimal>> async() { 
     DeferredResult<ResponseEntity<BigDecimal>> result = new DeferredResult<>(); 
     Observable.create(emit(this::getA)) 
       .zipWith(Observable.create(emit(this::getB)), (x, y) -> x.add(y)) 
       .map(n -> ResponseEntity.ok(n)) 
       .subscribe(re -> result.setResult(re)); 
     return result; 
    } 


    private Observable.OnSubscribe<BigDecimal> emit(Supplier<? extends BigDecimal> p) { 
     return s -> { 
      s.onNext(p.get()); 
      s.onCompleted(); 
     }; 
    } 

    private BigDecimal getA() { 
     sleep(); 
     return BigDecimal.valueOf(500); 
    } 

    private BigDecimal getB() { 
     sleep(); 
     return BigDecimal.valueOf(300); 
    } 

    private void sleep() { 
     try { Thread.sleep(10 + random.nextInt(10)); } catch (InterruptedException e) { } 
    } 
} 

Ich habe die folgenden Performance-Ergebnisse (mit wrk):

Running 10s test @ http://localhost:8080/norx1 
    10 threads and 1000 connections 
    Thread Stats Avg  Stdev  Max +/- Stdev 
    Latency 78.11ms 31.32ms 250.18ms 67.27% 
    Req/Sec 307.06  68.75 474.00  65.60% 
    30663 requests in 10.05s, 4.98MB read 
    Socket errors: connect 759, read 129, write 0, timeout 0 
Requests/sec: 3052.35 
Transfer/sec: 507.18KB 

Running 10s test @ http://localhost:8080/rx1 
    10 threads and 1000 connections 
    Thread Stats Avg  Stdev  Max +/- Stdev 
    Latency 86.67ms 38.32ms 313.65ms 67.19% 
    Req/Sec 277.84 101.59 565.00  73.37% 
    27732 requests in 10.08s, 4.50MB read 
    Socket errors: connect 759, read 0, write 0, timeout 0 
Requests/sec: 2749.94 
Transfer/sec: 456.98KB 

Running 10s test @ http://localhost:8080/norx2 
    10 threads and 1000 connections 
    Thread Stats Avg  Stdev  Max +/- Stdev 
    Latency 77.19ms 21.17ms 224.72ms 67.65% 
    Req/Sec 311.54 174.18 770.00  68.80% 
    31115 requests in 10.09s, 5.05MB read 
    Socket errors: connect 759, read 116, write 0, timeout 0 
Requests/sec: 3084.71 
Transfer/sec: 512.57KB 

Running 10s test @ http://localhost:8080/rx2 
    10 threads and 1000 connections 
    Thread Stats Avg  Stdev  Max +/- Stdev 
    Latency 86.05ms 27.78ms 226.40ms 64.60% 
    Req/Sec 554.96 387.63  1.28k 55.13% 
    27761 requests in 10.07s, 4.51MB read 
    Socket errors: connect 759, read 102, write 0, timeout 0 
Requests/sec: 2756.15 
Transfer/sec: 458.01KB 
+1

Vor einiger Zeit habe ich genau das Gleiche überprüft und eine Frage [hier] (http://stackoverflow.com/questions/34286017/unexplainable-lack-of-performance-improvement-using-rxjava-observables-in- Web-ap). Am Ende war ein Programmierfehler. Sie können sehen, [mein Projekt] (https://github.com/codependent/spring-nio-rest) – codependent

+0

Hallo @codependent, basierend auf der verknüpften Frage, ist die Empfehlung, den Schlaf zu entfernen. Aber ich möchte eine lang andauernde Operation simulieren (die auch wie Schlaf blockiert). Kann ich den Schlaf nicht besiegen, was ich erreichen will? – Chad

+1

Sie können die Ausführung so verzögern: 'Observable.just (generateData()). Delay (400, TimeUnit.MILLISECONDS);' – codependent

Antwort

0

Nach Herumspielen weiter, so scheint es, das Hauptproblem war ich wurde Begegnung dass die von mir gewählte Verzögerung (~ 20ms) zu klein war, um asynchrone Operationen in Spring MVC + RxJava zu nutzen. Das Erhöhen auf ~ 500 ms hat den Trick vollbracht und große Leistungsverbesserungen gezeigt.

+0

Können Sie erklären, wie Sie sich verbessern? – ilumin

Verwandte Themen