端点需要太多时间来发送响应

时间:2018-01-29 13:48:28

标签: spring spring-boot spring-webflux

使用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. 这是我的主要课程

    @Bean
    
    public RouterFunction<ServerResponse> route(AccountHandler handler)     {
        return RouterFunctions                .route(GET("/route/accountInformation").and(accept(MediaType.APPLICATION_JSON)),handler::getAccountPortfolio);
    }
    
  4. 当我到达此路线 / route / accountInformation 时,第一个呼叫正常,但其他呼叫正在等待(服务器从不发送响应)。

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

1 个答案:

答案 0 :(得分:1)

如果没有更多信息,很难说出发生了什么(log运算符的输出应该在这里提供帮助)。但是在处理程序中间使用block运算符是可疑的;通过这样做,您可能会阻止少数服务器线程之一。

尝试类似:

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

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