美文网首页
Spring Webflux线程使用情况调研

Spring Webflux线程使用情况调研

作者: 光谷电锯狂魔 | 来源:发表于2019-10-18 17:18 被阅读0次

    Stack overflow: Threading model of Spring WebFlux and Reactor
    Netty reactor thread modeling
    Spring framework reference: webflux-concurrency-model

    Spring MVC vs Spring WebFlux

    • Architecture diagram


      image.png
    image.png

    Threading Model

    • For WebFlux Http request handling

      • On a "vanilla" Spring WebFlux server (e.g. no data access, nor other optional dependencies), you can expect one thread for the server, and several others for request processing (typically as many as the number of CPU cores). Servlet containers, however, may start with more threads (e.g. 10 on Tomcat), in support of both servlet, blocking I/O and servlet 3.1, non-blocking I/O usage.
      • The reactive WebClient operates in event loop style. So you’ll see a small, fixed number of processing threads related to that, e.g. "reactor-http-nio-" with the Reactor Netty connector. However if Reactor Netty is used for both client and server, the two will share event loop resources by default.
      • Reactor and RxJava provide thread pool abstractions, called Schedulers, to use with the publishOn operator that is used to switch processing to a different thread pool. The schedulers have names that suggest a specific concurrency strategy, e.g. "parallel" for CPU-bound work with a limited number of threads, or "elastic" for I/O-bound work with a large number of threads. If you see such threads it means some code is using a specific thread pool Scheduler strategy.
      • Data access libraries and other 3rd party dependencies may also create and use threads of their own.
    • For MongoDB

      • DB access and subsequent data operation via thread created from NioEventLoopGroup.
      • NioEventLoopGroup is created by MongoReactiveAutoConfiguration and can be configured via MongoClientSettings
      • Thread number is defined in MultithreadEventLoopGroup: DEFAULT_EVENT_LOOP_THREADS = Math.max(1, SystemPropertyUtil.getInt("io.netty.eventLoopThreads", NettyRuntime.availableProcessors() * 2))

    Thread usage records in our server

    Local Macbook pro 2015 15 inch', with 4 cores and 8 threads

    Thread used in single call
    • Main - Application startup
    • reactor-http-nio-x - Request handler & Response Handler for both Http and Websocket
    • nioEventLoopGroup-2-y - Reactive mongo repository
    Thread used in concurrent calls from 100 users

    Using Gatling to make 100 concurrent calls on the Http apis:

    • /lexicons
    • /lexicons/random
    • /users

    Using Gatling to make 20 concurrent calls on the Websocket apis:

    • /join then send Command(REFRESH)

    Thread used (Http and websocket have the same result):

    • reactor-http-nio-x: 8 threads
    • nioEventLoopGroup-x-y: 16 threads

    Issue records

    • LexiconRepositoryCustom should be implemented in a non-blocking way. Which means the syncronized data CURD with mongoTemplate should be deffered and dispatched to another thread. (Which thread pool?)
      Solution: Replace MongoTemplate with ReactiveMongoTempate
    • All service executions are running on nioEventLoopGroup-x-y because they start with repository calls. Should we dispatch it back to ctor-http-nio-x?
      Answer: No need. As long as it dose no block the nio threads.

    相关文章

      网友评论

          本文标题:Spring Webflux线程使用情况调研

          本文链接:https://www.haomeiwen.com/subject/hmhwmctx.html