2016-06-06 2 views
0

Я пытался поэкспериментировать с возможными последствиями производительности интеграции DeferredResult и RxJava с Spring MVC. Обратите внимание на снижение производительности с конечной точки norx по сравнению с конечными точками rx. Я ожидал, что реализация RxJava + DeferredResult превзойдет (количество запросов, req/sec) ванильного. Может ли кто-нибудь объяснить, почему это произошло?Снижение производительности при использовании DeferredResult и RxJava с Spring MVC

Используя следующий код: 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 
+1

Некоторое время назад я проверил ту же самую вещь и задал вопрос [здесь] (http://stackoverflow.com/questions/34286017/unexplainable-lack-of-performance-improvement-using-rxjava-observables-in- веб-ар). В итоге была ошибка программирования. Вы можете взглянуть на [мой проект] (https://github.com/codependent/spring-nio-rest) – codependent

+0

Привет @codependent, исходя из связанного вопроса, рекомендуется удалить сон. Но я хотел бы симулировать длительную операцию (которая также будет блокировать как сон). Не снимает ли сон то, чего я хочу достичь? – Chad

+1

Вы можете отложить его выполнение следующим образом: 'Observable.just (generateData()). Delay (400, TimeUnit.MILLISECONDS);' – codependent

ответ

0

Позабавившись дальше, кажется, главная проблема, которую я сталкивался был что задержка, которую я выбрал (~ 20 мс), была слишком мала, чтобы использовать асинхронные операции в Spring MVC + RxJava. Увеличение до ~ 500 мс сделало трюк и продемонстрировало большие улучшения производительности.

+0

Не могли бы вы объяснить, как вы улучшаетесь? – ilumin

Смежные вопросы