tomcat mas netty

Quiero hacer pequeรฑas pruebas con el framework wrk y JMetter a ver que vemos

Instalar wrk

Para instalar wrk(un framework open source escrito en C, para benchmarking), en linux es facil:

sudo apt install wrk

Se puede instalar tambien en WSL de Guindow$

  • Repositorio: wrk


Entorno

Pretendo probar un stack con spring mvc y spring webflux, en mi NAS y en (OCI) Oracle Cloud Infrastructure, entonces crear un simple standalone con un controller

Para eso se debe ajustar el pom.xml para que se puedo levantar el micro con Tomcat o Netty(mรกs precisamente Reactor netty, que es netty con backpressure)

Operador block()

Como sabemos seguro, con el operador block() con project reactor el stream reactivo se convertira en algo simplemente sincrono, y tambien creare un endpoint que lo use, para ver su comportamiento.

@Log4j2
@RestController
public class MyController {

    //Enndpoint bloqueante (usa Thread.sleep) (1)
    @GetMapping("/delay/blocking/{seconds}")
    public String delayBlocking(@PathVariable int seconds) {
        try {
            Thread.sleep(seconds * 1000L);
            log.info("blocking seconds:{} * 1000L {}", seconds, seconds);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        return "OK (blocking) after " + seconds + "s on " + serverType();
    }

    //Endpoint reactivo (no bloqueante) (2)
    @GetMapping("/delay/reactive/{seconds}")
    public Mono<String> delayReactive(@PathVariable int seconds) {
        return Mono.delay(Duration.ofSeconds(seconds))
                .map(i -> "OK (reactive) after " + seconds + "s on " + serverType())
                .log();
    }

    //Endpoint reactivo con el operador block()
    @GetMapping("/delay/reactive-and-block/{seconds}") (3)
    public String delayReactiveWithBlock(@PathVariable int seconds) {
        return Mono.delay(Duration.ofSeconds(seconds))
                .map(i -> "OK (reactive with block()) after " + seconds + "s on " + serverType())
                .log()
                .block();
    }

    //Endpoint reactivo con boundedElastic (4)
    @GetMapping("/delay/reactive-scheduler/{seconds}")
    public Mono<String> delayReactiveWithCustomScheduler(@PathVariable int seconds) {
        return Mono.delay(Duration.ofSeconds(seconds))
                .map(i -> "OK (reactive with block()) after " + seconds + "s on " + serverType())
                .log()
                .subscribeOn(Schedulers.boundedElastic());
    }

    private String serverType() {
        return (ClassUtils.isPresent("org.apache.catalina.startup.Tomcat", null))
                ? "Tomcat"
                : "Reactor Netty";
    }

}
1 Enndpoint bloqueante (usa Thread.sleep)
2 Endpoint reactivo (no bloqueante)
3 Endpoint reactivo pero usando el operador block()
4 Endpoint reactivo (no bloqueante) con el Scheduler boundedElastic [1]

y simplemente en el pom.xml seria

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

Para cambiar puerto de springboot en runtime

mvn spring-boot:run -Dspring-boot.run.arguments=--server.port=8000