我正在开发一个大型Spring Boot服务,大约有60k行代码。它为每个到其单个端点的传入请求调用大约10个依赖项。有适当的断路器,超时和指标。
该服务不擅长管理挣扎的依赖关系。一旦它们的响应时间变长,服务就需要更多的CPU,其延迟就会增加。这很糟糕,因为我们有延迟SLO。
我们已经用WebFlux做了实验,原型看起来很有希望。现在我们要迁移。
处理这个大项目的一个方法是一个接一个地迁移依赖项。我们可以把它们写成Mono<>
然后用block()
来表示。该项目可以立即再次部署。在所有依赖都像这样迁移之后,将引擎从MVC切换到WebFlux,然后重写RestController
和两者之间的所有代码。这是可行的,但理想情况下,我们希望在迁移第一个依赖项后立即看到性能优势。
是否有可能在项目中添加WebFlux事件循环,在单独的线程中运行,并将依赖项一个接一个地迁移到其中?那会是什么样子?目前我们使用@Async
和自定义线程池调用依赖项。
事件循环不是由您自己启动或编写的。在webflux中,事件循环是由底层web服务器(netty)创建的,它根据主机有多少内核运行几个事件循环。
我看不出在同一时间在一个应用程序上运行两个不同的web服务器实现的任何方式。我不确定,春季团队需要有人在这里回答更多的细节。
如果这是一个大而重要的项目,我会保留原来的服务器,然后通过前端使用负载平衡器,通过复制请求并将它们发送到两个服务并实现一个端点开始,并行运行一段时间,看看它是否工作良好,然后关闭并行运行。同时对每个/几个端点执行此操作。
也有特定的阴影工具用于此目的,如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
永远没有平稳的迁移方式。