原始性能表格 - Spring Boot 2 Webflux vs. Spring Boot 1

Posted SpringForAll社区

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了原始性能表格 - Spring Boot 2 Webflux vs. Spring Boot 1相关的知识,希望对你有一定的参考价值。

原文链接:https://dzone.com/articles/raw-performance-numbers-spring-boot-2-webflux-vs-s

译者:FraserYu

对于IO繁重的工作负载,基于Spring Webflux应用程序的Spring Boot 2要优于基于Spring Boot 1的应用程序, 以下是负载测试的总结性结果 - 对于具有不同并发用户的IO繁忙事务的响应时间:

当并发用户数量很少(比如少于1,000)时,Spring Boot 1和Spring Boot 2都能很好地处理负载,并且95%的响应时间仍然保持毫秒级,超过期望值300 ms。

在更高的并发水平上,Spring Boot 2中的异步非阻塞IO和响应式的支持开始显示它们的能力 - 即使有5000个用户的重负载,95%的响应时间仍然在312毫秒左右!而 Spring Boot 1在这些并发级别上则记录了很多失败和高响应时间。

详细

我的性能测试设置如下:

原始性能表格 - Spring Boot 2 Webflux vs. Spring Boot 1

示例应用暴露出一个端点 (/passthrough/message) ,该端点又顺序调用了下游服务,到端点的请求消息类似这样:

 
   
   
 
  1. {

  2.  "id": "1",

  3.  "payload": "sample payload",

  4.  "delay": 3000

  5. }

下游服务将根据消息中 "delay" 属性进行延迟(以毫秒为单位)。

Spring Boot 1 应用

我使用Spring Boot 1.5.8.RELEASE作为应用程序的Boot 1版本。 该端点是一个简单的Spring MVC控制器,该控制器使用Spring的 RestTemplate 进行下游服务的调用。 一切都是同步和阻塞的,并且在运行时我使用默认嵌入式的Tomcat容器。 这是下游调用的原始代码:

 
   
   
 
  1. public MessageAck handlePassthrough(Message message) {

  2.    ResponseEntity<MessageAck> responseEntity = this.restTemplate.postForEntity(targetHost

  3.                                                            + "/messages", message, MessageAck.class);

  4.    return responseEntity.getBody();

  5. }

Spring Boot 2 应用

该应用程序的 Spring Boot 2 版本暴露出一个基于 Spring Webflux 的端点并且使用 WebClient , 这是对 RestTemplate 的新型非阻塞,响应式的替代方案,用于进行下游服务的调用,我还使用了 Kotlin 进行实现,它不影响性能。 运行时服务是 Netty:

 
   
   
 
  1. import org.springframework.http.HttpHeaders

  2. import org.springframework.http.MediaType

  3. import org.springframework.web.reactive.function.BodyInserters.fromObject

  4. import org.springframework.web.reactive.function.client.ClientResponse

  5. import org.springframework.web.reactive.function.client.WebClient

  6. import org.springframework.web.reactive.function.client.bodyToMono

  7. import org.springframework.web.reactive.function.server.ServerRequest

  8. import org.springframework.web.reactive.function.server.ServerResponse

  9. import org.springframework.web.reactive.function.server.bodyToMono

  10. import reactor.core.publisher.Mono

  11. class PassThroughHandler(private val webClient: WebClient) {

  12.    fun handle(serverRequest: ServerRequest): Mono<ServerResponse> {

  13.        val messageMono = serverRequest.bodyToMono<Message>()

  14.        return messageMono.flatMap { message ->

  15.            passThrough(message)

  16.                    .flatMap { messageAck ->

  17.                        ServerResponse.ok().body(fromObject(messageAck))

  18.                    }

  19.        }

  20.    }

  21.    fun passThrough(message: Message): Mono<MessageAck> {

  22.        return webClient.post()

  23.                .uri("/messages")

  24.                .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)

  25.                .header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)

  26.                .body(fromObject<Message>(message))

  27.                .exchange()

  28.                .flatMap { response: ClientResponse ->

  29.                    response.bodyToMono<MessageAck>()

  30.                }

  31.    }

  32. }

性能测试详细

测试很简单;对于不同组的并发用户量(300,1000,1500,3000,5000),我发送一个延迟属性设置为 300 毫秒的消息, 并且每个用户在请求之间以 1 到 2 秒的延迟重复该场景 30 次,我正在使用出色的 Gatling 工具来生成这个负载。

结果

这些是通过 Gatling 捕获的结果:

原始性能表格 - Spring Boot 2 Webflux vs. Spring Boot 1

原始性能表格 - Spring Boot 2 Webflux vs. Spring Boot 1

原始性能表格 - Spring Boot 2 Webflux vs. Spring Boot 1

原始性能表格 - Spring Boot 2 Webflux vs. Spring Boot 1

参考

示例应用和负载脚本在我的GitHub仓库 my GitHub repo 可用。

本文由spring4all.com翻译小分队创作,采用 知识共享-署名-非商业性使用-相同方式共享 4.0 国际 许可 协议进行许可。

最后

关注社区公号,加入社区纯技术微信群

以上是关于原始性能表格 - Spring Boot 2 Webflux vs. Spring Boot 1的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot快速入门

SpringBoot常用starter解读

Spring Boot教程第24篇:整合docker

Spring Boot Sample 024之spring-boot-data-influxdb

Spring Boot 2.2.0,性能提升+支持Java13

Spring Boot 2.x 的性能问题?