端点发送响应花费的时间太长
Endpoint takes too much time to send the response
我在使用 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();
}
这里是我的主要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
运算符以了解时间花在了哪里。
我在使用 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(); }
这里是我的主要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
运算符以了解时间花在了哪里。