端点发送响应花费的时间太长

Endpoint takes too much time to send the response

我在使用 Spring WebFlux 时遇到问题。其实我的项目是由

  1. Api 包装器(基本上是使用 WebClient 调用远程服务的代码)

    private final BinanceServerTimeApi binanceServerTimeApi;
    
    private final WebClient webClient;
    
    @Value("${binance.api.secret}")
    private String secret;
    
    @Autowired
    public BinanceAccountApi(@Value("${binance.api.baseurl}") String baseUrl,
                             @Value("${binance.api.key}") String key,
                             BinanceServerTimeApi binanceServerTimeApi) {
        this.binanceServerTimeApi = binanceServerTimeApi;
        this.webClient = WebClient.builder()
                .baseUrl(baseUrl)
                .defaultHeader("X-MBX-APIKEY",key)
                .build();
    }
    
    public Mono<AccountInformation> getAccountInformation() {
        Mono<ResponseServerTime> responseServerTime = binanceServerTimeApi.getServerTime();
        String apiEndpoint = "api/v3/account?";
        String queryParams = "recvWindow=50000&timestamp=" + responseServerTime.block().getServerTime();
        String signature = HmacSHA256Signer.sign(queryParams, secret);
        String payload = apiEndpoint+queryParams+"&signature="+signature;
    
        log.info("final url for getAccountInformation is {}", payload);
    
        return this.webClient.get().uri(payload).accept(MediaType.APPLICATION_JSON)
                .retrieve().bodyToMono(AccountInformation.class).log();
    }
    
  2. 我的 javascript 客户端使用的端点

    @Autowired

    private BinanceAccountApi binanceAccountApi;
    public Mono<ServerResponse> getAccountPortfolio(ServerRequest request)     {
        return binanceAccountApi.getAccountInformation()
                .flatMap(accountInformation -> ServerResponse.ok()
                .contentType(MediaType.APPLICATION_JSON)
                .body(fromObject(accountInformation))).log();
    }
    
  3. 这里是我的主要class

    @Bean
    
    public RouterFunction<ServerResponse> route(AccountHandler handler)     {
        return RouterFunctions                .route(GET("/route/accountInformation").and(accept(MediaType.APPLICATION_JSON)),handler::getAccountPortfolio);
    }
    

当我点击到达此路由 /route/accountInformation 时,第一个调用工作正常,但其他调用处于待处理状态(服务器从不发送响应)。

请注意,对端点的第一次调用持续 2000 毫秒。 这是我对 WebFlux 项目的第一种方法,我正试图弄清楚它是如何工作的。

在没有更多信息的情况下,很难判断发生了什么(log 运算符的输出应该在此处有所帮助)。但是在处理程序中间使用 block 运算符是可疑的;通过这样做,您可能会阻塞为数不多的服务器线程之一。

试试这样的东西:

return binanceServerTimeApi.getServerTime().flatMap(responseServerTime -> {
    // ...
    return this.webClient.get().uri(payload).accept(MediaType.APPLICATION_JSON)
            .retrieve().bodyToMono(AccountInformation.class).log();
});

这将以非阻塞方式链接操作。如果此后情况没有改善,请尝试添加一些 log 运算符以了解时间花在了哪里。