我有一个关于Spring Reactive WebClient的问题...
几天前,我决定尝试使用Spring Framework中的新反应式内容,并为个人目的制作了一个小项目来爬取数据(对一个网页进行多次请求并组合结果)。
我开始使用新的反应式WebClient进行请求,但我发现的问题是客户端没有为每个请求发出响应。听起来很奇怪。以下是我获取数据所做的内容:
问题在于,如果我发出的请求稍微多一点,超过了100个,我就无法收到所有的响应,没有抛出错误,也没有返回错误响应代码,并且订阅方法被调用时的大小与请求数不同。
我的请求基于字符串列表(url)进行,当所有响应都被发出后,我应该将它们全部作为列表接收,因为我使用了
样本输出:
请给我一些建议,如何调试或者我做错了什么。感谢您的帮助。
更新:
日志显示,如果我传递了126个url,例如:
我开始使用新的反应式WebClient进行请求,但我发现的问题是客户端没有为每个请求发出响应。听起来很奇怪。以下是我获取数据所做的内容:
private Mono<String> fetchData(String uri) {
return this.client
.get()
.uri(uri)
.header("X-Fsign","SW9D1eZo")
.retrieve()
.bodyToMono(String.class)
.timeout(Duration.ofSeconds(35))
.log("category", Level.ALL, SignalType.ON_ERROR, SignalType.ON_COMPLETE, SignalType.CANCEL, SignalType.REQUEST);
}
调用 fetchData
的函数:
public Mono<List<Stat>> fetch() {
return fetchData(URL)
.map(this::extractUrls)
.doOnNext(System.out::println)
.doOnNext(s-> System.out.println("all ids are "+s.size()))
.flatMapIterable(q->q)
.map(s -> s.substring(7, 15))
.map(s -> "http://d.flashscore.com/x/feed/d_hh_" + s + "_en_1") // list of N-length urls
.flatMap(this::fetchData)
.map(this::extractHeadToHead)
.collectList();
}
和订阅者:
FlashScoreService bean = ctx.getBean(FlashScoreService.class);
bean.fetch().subscribe(s->{
System.out.println("finished !!! " + s.size()); //expecting same N-length list size
},Throwable::printStackTrace);
问题在于,如果我发出的请求稍微多一点,超过了100个,我就无法收到所有的响应,没有抛出错误,也没有返回错误响应代码,并且订阅方法被调用时的大小与请求数不同。
我的请求基于字符串列表(url)进行,当所有响应都被发出后,我应该将它们全部作为列表接收,因为我使用了
collectList()
。当我执行100个请求时,我期望收到100个响应的列表,但实际上我有时会收到100个,有时会收到96等……可能是某些地方默默地失败了。
这很容易复现,这是我的github项目link。样本输出:
all ids are 176
finished !!! 171
请给我一些建议,如何调试或者我做错了什么。感谢您的帮助。
更新:
日志显示,如果我传递了126个url,例如:
onNext(ReactorClientHttpResponse{request=[GET/some_url],status=200}) is called 121 times. May be here is the problem.
onComplete() is called 126 times which is the exact same length of the passed list of urls
但是如何可能在不调用onNext()或onError()的情况下完成一些请求呢?(在Mono中成功和错误)
我认为问题不在WebClient,而是在其他地方。环境或服务器阻止了请求,但我可能应该收到一些错误日志。
附言:感谢您的帮助!