使用Spring WebFlux时遇到问题。实际上我的项目由
组成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×tamp=" + 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();
}
我的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();
}
这是我的主要课程
@Bean
public RouterFunction<ServerResponse> route(AccountHandler handler) {
return RouterFunctions .route(GET("/route/accountInformation").and(accept(MediaType.APPLICATION_JSON)),handler::getAccountPortfolio);
}
当我到达此路线 / route / accountInformation 时,第一个呼叫正常,但其他呼叫正在等待(服务器从不发送响应)。
请注意,对端点的第一次调用持续2000 ms。 这是我对WebFlux项目的第一种方法,我试图弄清楚它是如何工作的。
答案 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
运算符以了解花费的时间。