如何将使用 RESTFul 的微服务迁移到 Spring Webflux 反应式

Posted

技术标签:

【中文标题】如何将使用 RESTFul 的微服务迁移到 Spring Webflux 反应式【英文标题】:How to migrate a microservice that uses RESTFul to Spring Webflux reactive 【发布时间】:2021-12-11 19:41:12 【问题描述】:

假设我有一个带有 Spring Boot 的微服务,其 PersonsRestController 输入如下:

@GetMapping(value = "/world/countryId/persons", produces = APPLICATION_JSON_UTF8_VALUE)
public ResponseEntity<PersonSaverItem> getPublishPersonsByCountry(@PathVariable("countryId") Integer countryId,
                                                                                                @RequestParam(value = "state", required = false) PublishItemState state,
                                                                                                @RequestParam(value = "limit", defaultValue = "50", required = false) int limit,
                                                                                                @RequestParam(value = "offset", defaultValue = "0", required = false) int offset) 

    PersonSaverList personSaverList = this.personSaverService.getPublishItemListBy(countryId, state, limit, offset);

    return personSaverList.getpersonSaverList();


personSaverService.getPublishItemListBy(...) 的实现如下所示:

@Override
public PersonSaverList getPublishItemListBy(Integer countryId, PublishItemState state, int limit, int offset) 

    try 

        return this.personSaverRepository.getPublishItemsBycountryId(countryId, state, limit, offset);

     catch (Exception e) 
      ...
    

最后,存储库通过 Spring Jdbc 对数据库进行查询,在本例中为 Oracle db。

如何将此逻辑迁移到 Spring WebFlux?

我已尝试仅将返回的列表更改为控制器中的 Flux:

  @GetMapping(value = "/world/countryId/persons", produces = APPLICATION_JSON_UTF8_VALUE)
  public Flux<PersonSaverItem> getPublishPersonsByCountry(@PathVariable("countryId") Integer 
      countryId,
  @RequestParam(value = "state", required = false) PublishItemState state,
  @RequestParam(value = "limit", defaultValue = "50", required = false) int limit,
  @RequestParam(value = "offset", defaultValue = "0", required = false) int offset) 

       PersonSaverList personSaverList = this.personSaverService.getPublishItemListBy(countryId, state, limit, offset);

       return Flux.fromIterable(personSaverList.getpersonSaverList());
  

但尝试 JMeter 模拟多个并发用户(线程)并没有看到任何改进。 我想还有更多工作要做。

提前致谢。

【问题讨论】:

您正在使用阻塞技术 JDBC,并将其包装在响应式中。那不会为您带来所有好处。此外,当将它与 Spring MVC 一起使用时(就像你一样),你只会得到异步部分而不是其他好处。最后可能没有任何性能优势(除非现在并行发生),而是使用更少的资源,从而允许在单个节点上进行更多的扩展。 【参考方案1】:

如果您的整个应用程序都是反应式的,那么您只会从使用反应式堆栈中获得真正的好处。在您的情况下,问题在于数据库,它不支持反应式编程,因此仍然处于阻塞状态。

您需要使用一个解决方法 (Spring Data R2DBC),以便您可以从使用 Spring WebFlux 中充分受益。

【讨论】:

以上是关于如何将使用 RESTFul 的微服务迁移到 Spring Webflux 反应式的主要内容,如果未能解决你的问题,请参考以下文章

spring boot 快速搭建 基于 Restful 风格的微服务

如何将 iOS 应用程序连接到 Symfony2 RESTful Webservice?

申通的云原生实践之路:如何实现应用基于容器的微服务改造?

使用Spring Security和OAuth2实现RESTful服务安全认证

从 RESTful 身份验证迁移到设计

使用 Asp.Net 的微服务