【发布时间】:2016-10-05 15:17:22
【问题描述】:
我一直在尝试将 DeferredResult 和 RxJava 与 Spring MVC 集成可能带来的性能影响。请注意,与 rx 端点相比,norx 端点的性能下降。我期待 RxJava + DeferredResult 实现优于普通版本(请求数,req/sec)。谁能解释为什么会这样?
使用以下代码: 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) { }
}
}
我得到了以下性能结果(使用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
【问题讨论】:
-
前段时间我检查了同样的事情并开始了一个问题here。最后是编程错误。你可以看看my project
-
嗨@codependent,根据链接的问题,建议删除睡眠。但我想模拟一个长时间运行的操作(它也会像睡眠一样阻塞)。消除睡眠不会破坏我想要实现的目标吗?
-
你可以像这样延迟它的执行:
Observable.just(generateData()).delay(400, TimeUnit.MILLISECONDS);
标签: java spring spring-mvc rx-java