{"id":15138543,"url":"https://github.com/zicat/spring-webflux-research","last_synced_at":"2026-03-07T13:32:29.203Z","repository":{"id":166238890,"uuid":"129828022","full_name":"zicat/spring-webflux-research","owner":"zicat","description":"spring webflux research","archived":false,"fork":false,"pushed_at":"2018-07-24T03:11:43.000Z","size":100,"stargazers_count":42,"open_issues_count":0,"forks_count":25,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-06T17:51:41.979Z","etag":null,"topics":["performance","reactor","spring","vertx","webflux"],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zicat.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-04-17T01:31:16.000Z","updated_at":"2024-02-23T20:05:18.000Z","dependencies_parsed_at":null,"dependency_job_id":"b442fd5f-a816-485a-9cce-895bfb14d193","html_url":"https://github.com/zicat/spring-webflux-research","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/zicat/spring-webflux-research","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zicat%2Fspring-webflux-research","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zicat%2Fspring-webflux-research/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zicat%2Fspring-webflux-research/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zicat%2Fspring-webflux-research/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zicat","download_url":"https://codeload.github.com/zicat/spring-webflux-research/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zicat%2Fspring-webflux-research/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30215671,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-07T13:25:55.541Z","status":"ssl_error","status_checked_at":"2026-03-07T13:25:38.596Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["performance","reactor","spring","vertx","webflux"],"created_at":"2024-09-26T07:40:57.835Z","updated_at":"2026-03-07T13:32:29.159Z","avatar_url":"https://github.com/zicat.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"## What is WebFlux framework\nWebFlux framework是Spring5第一代响应式编程框架。\n[官方文档](https://docs.spring.io/spring/docs/5.0.0.BUILD-SNAPSHOT/spring-framework-reference/html/web-reactive.html)\n\n\u003cimg src=\"/docs/image2018-4-14 14_50_43.png\" /\u003e\n\n架构上spring-webflux与spring-webmvc同级，是spring-webmvc的替代方案，底层网络模型脱离Servlet Api，采用了基于NIO的网络编程框架，支持包括Tomcat，Jetty，Netty等。\n\nspring-webflux依然沿用了与spring-webmvc相同的Controller注解和路由方式，对于旧项目迁移至新项目中带来了便利。\n\n中间层的业务代码由Reactive Stream方式管理，Reactive Streams默认采用Reactor框架，同时还支持另一款相对庞大的Reactive Stream框架RxJava。\n\n可以说WebFlux框架是非常灵活的，选择WebFlux作为响应式异步网络编程是明智的选择。\n\n## WebFlux framework搭建\n\n1. $ check out this project\n2. $ cd ${project root dir}\n3. $ mvn clean install\n4. $ mvn spring-boot:run\n5. [open browser](http://localhost:8080/product?productId=10)\n\n## Spring MVC差异对比\n\nSpring MVC依然还是沿用Servlet编程模式，Servlet编程模式屏蔽了底层IO模型，所以很多Servlet容器都支持NIO和BIO等多种模式可选，但是Servlet对于线程模型的控制力度很粗。\n\nServlet网络编程采用的是线程或者线程池模型。在BIO模型下，通过accept模式阻塞，等待客户端请求，当接收到客户端请求后分配一个线程给一个request并采用回调的方式让用户实现servlet.service()方法，即用户在实现service()方法时是在一个分配好的线程中，而不是在accept线程中，accept线程就是所谓的Loop线程。同样在NIO Selector模型下，等待客户端的读写事件，然后为每个事件绑定线程并采用回调的方式让用户实现servlet.service()方法。这种模型的好处是request线程和loop线程进行了有效的隔离，即便是业务代码阻塞也完全不影响loop线程的运行，坏处是线程利用率低下，并发request数越大需要的线程越多，极大的影响了服务的极限性能。举个例子，假设有个业务非常简单，只返回系统当前时间，而系统当前时间通过一个变量维护，通过后台线程不断更新数据，request只简单的返回该变量，这种情况下完全不需要开启request级别线程，在loop线程中就可以直接处理request，只需要1个或几个线程就能应对极大并发的请求。这种业务场景下旧模型没有优势。\n\nWebFlux模式的优势不是在于底层是否采用了NIO还是BIO，而是在上层替换了旧的Servlet线程模型。既然旧模型的问题在于用户无法使用Loop线程，所以WebFlux直接将Controller移交到Loop线程中，所以在Controller层返回的对象必须用Mono\u003cT\u003e或者Flux\u003cT\u003e包裹。这样做的好处在于允许用户在Loop线程中进行一些快速的非阻塞的操作，比如定义响应式编程模型对象等，不阻塞Loop线程，并绑定Scheduler，保证响应式编程模型能在新的线程中执行，提高并发性能。\n\n将项目以Debug方式启动后，可以将断点设置在Controller入口的第一行代码，并用多个浏览器同时请求可以发现和Spring MVC的差异，当WebFlux设置Loop线程=1时，只有第一个request能进入Controller层，其他线程会在第一个request运行完所有Controller代码后才能依次被调用。而Spring MVC可以允许多个request并发调用Controller层代码。\n\n## 性能测试\n将WebFlux，VertX和Servlet(JAXRS2.1 Tomcat)三者进行性能测试。\n\n### 测试场景\n    1. 1000/user, 总request数量500000\n    2. request：/product?productID=10 response：{\"productId\":\"10\"}\n    3. service server 参数：\n        cpu = 32  Intel(R) Xeon(R) CPU E5-2690 0 @ 2.90GHz,\n        memory = 252GB\n        linux = version 2.6.32-358.el6.x86_64\n        java = Java(TM) SE Runtime Environment (build 1.8.0_73-b02)\n        JVM = Java HotSpot(TM) 64-Bit Server VM (build 25.73-b02, mixed mode)\n    4. client server 参数：same with service server\n    5. 客户端测试工具 Apache Jmeter 4.0\n    注：为了尽量和实际service保持一致，每个request耗时控制在20MS。\n\n### 测试结果\n\nVertX   summary = 2574404 in 00:00:57 = 45311.3/s Avg:  21 Min:  5 Max:  1133 Err:  75 (0.00%)\n\nWebFlux summary = 2499748 in 00:00:57 = 44004.2/s Avg:  22 Min:  4 Max:  4020 Err: 65 (0.00%)\n\nTomcat  summary = 1831730 in 00:01:01 = 30234.1/s Avg:  27 Min:  3 Max: 31020 Err:  72 (0.00%)\n\n\n### 结论\n\nVertX  吞吐量45311.3/s排名第一，在1000并发平均响应性能损失5%，最坏情况性能损失5665%。\n\nWebFlux吞吐量44004.2/s排名第二，在1000并发平均响应性能损失10%，最坏情况性能损失20100%。\n\nTomcat 吞吐量30234.1/s排名第三，在1000并发平均响应性能损失35%，最坏情况性能损失155100%。\n\n\n\n\n### 总结\nVertX的性能非常优秀，性能损失极低，最坏情况令人满意。\n\nSpring WebFlux性能紧随其后，性能损失和最坏情况都稍逊于VertX。\n\nTomcat性能损失偏大，最坏情况性能损失不能令人满意。\n\n### 试用场景\nVertX的MVC还停留在API级别，在功能上比Spring MVC要弱，VertX适合一些历史包袱轻的新项目特别是作为Rest Api Service比较适合。\n\nSpring Webflux由于支持Controller，对于一些已有的Spring MVC Service来说，迁移的工作量和风险相对较小。\n\n对于一些service由于并发高导致部署过多instance的可以考虑切换至响应式Java Web，可以大大减少instance的部署，降低机器成本。对于并发不高的service虽然不会有明显的性能提升，但依然可以考虑切换，将这些service可以集中部署在几台server上，提高server资源的利用率和维护成本。\n\n特别注意：不要简单的将WebFlux、VertX和性能挂上等号，每个服务的性能有诸多因素决定，对于性能优化还是要具体问题具体分析，不要盲目崇拜。\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzicat%2Fspring-webflux-research","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzicat%2Fspring-webflux-research","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzicat%2Fspring-webflux-research/lists"}