spring-boot - Spring Boot - 创建自定义事件循环
问题描述
我正在开发一个包含大约 60k 行代码的大型 Spring Boot 服务。它为每个传入请求到其单个端点调用大约 10 个依赖项。有断路器、超时和指标。
该服务在管理苦苦挣扎的依赖方面并不出色。一旦他们的响应时间变长,服务就需要更多的 CPU 并且它的延迟会增加。这很糟糕,因为我们有延迟 SLO。
我们已经用 WebFlux 进行了实验,原型看起来很有希望。现在我们要迁移。
解决这个大项目的一种方法是一个接一个地迁移依赖项。我们可以将它们重写为Mono<>
,然后使用block()
. 该项目可以立即再次部署。像这样迁移所有依赖项后,将引擎从 MVC 切换到 WebFlux,然后重写中间的RestController
所有代码。这会起作用,但理想情况下,我们希望在迁移第一个依赖项后立即看到性能优势。
是否可以改为将 WebFlux 事件循环添加到项目中,在单独的线程中运行它并将依赖项一一迁移到其中?那会是什么样子?@Async
目前,我们使用自定义线程池调用依赖项。
解决方案
事件循环不是你自己启动的,也不是你自己写的。在 webflux 中,事件循环由底层网络服务器(netty)创建,该服务器根据主机拥有的内核数量运行几个事件循环。
我看不到在单个应用程序上同时运行 2 个不同的网络服务器实现的任何方式。我不确定,春季团队的某个人需要在这里回答更多细节。
Tbh,如果这是一个大而重要的项目,我会保留原始服务器,然后通过在前面使用负载平衡器,首先复制请求并将它们发送到两个服务并实现一个端点,并行运行它一段时间以确保它运行良好,然后关闭并行运行。并同时为每个/几个端点执行此操作。
也有用于此目的的特定阴影工具,例如goreplay
.
req ---------> LB ------> original
\
\------> webflux
req ---------> LB
\
\------> webflux
// Or for instance goreplay that runs on a host and also
// shadows requests forward to another service
req ---------> original
\
\------> webflux
从来没有任何平滑的迁移方式。
推荐阅读
- ios - 使用 SWReveal 视图控制器隐藏标签栏项目
- javascript - 如何从 datepicker 获取选定的日期到后端的方法
- flutter - 为什么我无法访问以 .dev 结尾的网站?
- asp.net - 使用查询创建表,但它向我显示括号所在的语法错误
- reactjs - 绑定和保存反应按钮值
- ios - 如何根据 JSON 数组中的字段对表格视图单元格进行分组
- php - 如何循环遍历数组而不重复?
- jestjs - 如何重置状态 beforeEach/afterEach 笑话测试?
- postman - 如何修复 Postman 中的“无法得到任何响应”?
- cordova - 随机获取/不获取可用网络列表 - Ionic Android Hotspot Plugin