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
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
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
Sie können die Ausführung so verzögern: 'Observable.just (generateData()). Delay (400, TimeUnit.MILLISECONDS);' – codependent