从一个微服务到另一个微服务的 WebClient 构建器调用在 Webflux 中首次出现错误的请求错误

Posted

技术标签:

【中文标题】从一个微服务到另一个微服务的 WebClient 构建器调用在 Webflux 中首次出现错误的请求错误【英文标题】:WebClient builder call from one microservice to another microservice giving bad request error for first time in Webflux 【发布时间】:2020-06-01 15:29:28 【问题描述】:

我们正在使用 WebClient Builder 调用在我们的项目中的微服务之间进行通信。它是基于 springboot-thymleaf-webflux 的应用程序。到目前为止一切都运行良好,但我们得到了客户端的要求,将 GET 调用更改为 POST 调用thymleaf 控制器。在 UI 和后端进行这些更改后,Thymleaf 调用工作正常,但其中一个 XHR 即来自 UI 的后调用 - 给 Webclient 调用第二个微服务以进行第一次单击并为第二次单击工作的错误请求错误。我比较两次单击的标题和请求没有发现任何区别。我无法理解为什么 webclient 第一次表现异常而第二次工作正常。下面是用于 webclient 调用的代码 sn-p,它通过说 BAD Request for http://second-microservice -eureka-address/endpoint-url 路由到 WebclientResponseException 而不会到达第二个微服务

     * Submitting xyz 
     * @param submitFlowRequest
     */
    @Override
    public Mono<ApiResponse<SubmitResponse>> submitFlow(SubmitFlowRequest submitFlowRequest,
            Map<String, String> headers) 
        long startTime = System.currentTimeMillis();
        String uri = propertyConfig.getAggregationService()
                + propertyConfig.getAggregationSubmitCCInfoURL();
        DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(uri);
        factory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.URI_COMPONENT);
        MultiValueMap<String, String> clientHeaders = buildHeaders(headers);
        return webClientBuilder.uriBuilderFactory(factory).build().post()
                .headers(httpHeaders -> httpHeaders.addAll(clientHeaders)).accept(MediaType.APPLICATION_JSON)
                .syncBody(submitFlowRequest).retrieve().bodyToMono(ApiResponse.class)
                .onErrorMap(ConnectException.class,
                        error -> new VzwRuntimeException(ErrorCodeEnum.V404.toString(), Constants.OPP_TC_SYSTEM_ERROR,
                                (Constants.CONNECTION_FAILURE_TEXT + Constants.AGGREGATION)))
                .onErrorMap(WebClientResponseException.class,
                        error -> new VzwRuntimeException(ErrorCodeEnum.V404.toString(), Constants.OPP_TC_SYSTEM_ERROR,
                                (Constants.CONNECTION_FAILURE_TEXT + Constants.AGGREGATION)))
                .flatMap(res -> 
                    Audit apiAudit = Audit.builder().apiUrl(uri).request(LoggerUtil.asJson(submitFlowRequest))
                            .response(LoggerUtil.asJson(res))
                            .executionTime(String.valueOf(System.currentTimeMillis() - startTime))
                            .headers(LoggerUtil.asJson(clientHeaders)).transactionType(res.getData()!=null?mapper.map(res.getData(), SubmitResponse.class).getTransactionType():"").build();
                    LoggerUtil.logExternalApiCalls(apiAudit);
                    return Mono.just((ApiResponse<SubmitResponse>) res);
                );
    ```

Please provide me some lead.I am tired of finding solution for this.

【问题讨论】:

【参考方案1】:

这是 Netty 的一个持续问题。 Netty 持有一些状态无效的连接 HttpObjectEncoder。当客户端从池中获取此类连接并使用它向目标服务器发出请求时,它会立即失败,因为 DefaultHttpRequest 无法由 HttpObjectEncoder 编码。 禁用连接池可以解决问题。

【讨论】:

以上是关于从一个微服务到另一个微服务的 WebClient 构建器调用在 Webflux 中首次出现错误的请求错误的主要内容,如果未能解决你的问题,请参考以下文章

spring boot - 假装客户端发送基本授权标头|将 jwt 令牌从一个微服务传递到另一个微服务

如何将数据库中的数据从一个服务器微服务更新到另一个?

微服务是不是应该具有仅将操作转发到另一个微服务的操作?

Spring WebClient与RestTemplate性能对比——响应式Spring的道法

LoadBalancerSpringCloud微服务组件LoadBalancer

LoadBalancerSpringCloud微服务组件LoadBalancer