Spring Boot - 创建自定义事件循环

问题描述

我正在开发一个包含大约 6 万行代码的大型 Spring Boot 服务。它为每个传入请求调用大约 10 个依赖项到其单个端点。设置了断路器、超时和指标。

该服务不擅长管理困难的依赖关系。一旦他们的响应时间变长,服务就需要更多的 cpu,其延迟就会增加。这很糟糕,因为我们有一个延迟 SLO。

我们已经对 WebFlux 进行了实验,原型看起来非常有前途。现在我们要迁移。

解决这个大项目的一种方法一个一个地迁移依赖项。我们可以将它们重写为 Mono<>,然后使用 block() 调用它们。该项目可以立即再次部署。像这样迁移完所有依赖后,将引擎从MVC切换到WebFlux,然后重写RestController以及其间的所有代码。这可行,但理想情况下,我们希望在迁移第一个依赖项后立即看到性能优势。

是否可以在项目中添加一个 WebFlux 事件循环,在单独的线程中运行它并将依赖项一个一个地迁移到其中?那会是什么样子?目前,我们使用 @Async自定义线程池调用依赖项。

解决方法

事件循环不是你自己启动的,也不是你自己写的。在 webflux 中,事件循环由底层网络服务器 (netty) 创建,该服务器根据主机拥有的内核数量运行几个事件循环。

我无法在单个应用程序上同时运行 2 个不同的网络服务器实现。我不确定,Spring 团队的某个人需要在这里回答更具体的问题。

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

永远不会有任何顺利的迁移方式。