【发布时间】:2021-06-28 09:42:46
【问题描述】:
我正在使用一个从 SQL Server 数据库公开 6212514 行的 Rest API。 REST API 的响应是 JSON,代表数据库行。
要调用此 API REST 并获取孔数据,我在每次迭代中使用通过参数 offset 和 limit 进行分页: 例子:
- 呼叫 1:
http://localhost:8080/myapi/dwcopa/getSlice?**limit**=8000&**offset**=1&buCd=XXX
- 呼叫 2:
http://localhost:8080/myapi/dwcopa/getSlice?**limit**=8000&**offset**=2&buCd=XXX
。 . .
- 拨打760:
http://localhost:8080/myapi/dwcopa/getSlice?**limit**=8000&**offset**=760&buCd=XXX
limit 是每次调用 API REST 返回的对象数,offset 是页码
例子:limit = 8000 and offset 1:调用会返回页码1的前8000个json对象
要获得 6212514 行,我需要执行 776 分页/调用客户端 API REST (= 6212514 /8000) 以获取我需要存储在数据库 SQL 服务器表中或使用这些 6212514 行创建 csv 文件的所有结果.
实际上,我在 Spring Boot 应用程序(2.5.1 版)(独立 Spring Boot 而非 REST API)(Java 11 / Spring webflux / Webclient)中使用此代码来使用客户端 REST API 并通过分页获取所有数据:
在服务 JAVA 类中:
我的 Spring Webclient 使用 REST API:
public DwCopaServiceImpl() {
this.webClient = WebClient.builder()
.codecs(codecs ->codecs.defaultCodecs().maxInMemorySize(memSize) )
.baseUrl(API_BASE_URL)
.defaultHeader(HttpHeaders.CONTENT_TYPE, API_MIME_TYPE)
.build();
}
我正在使用 Reactive Mono 来不阻塞调用 API 并迭代所有分页工具,response.isLast() 为 false(此字段表示此页 REST API 是最后一页)
DwCopaEntity 是一个实体,它呈现一行 (JSON) 并包含许多字符串字段:
public Mono<List<DwCopaEntity>> getItems() {
String url = "/dwcopa/getSlice?limit="+limit+"&offset="+offset+"&buCd="+BUCD;
return fetchItems(url).expand(response -> {
if (**response.isLast()** ) {
return Mono.empty();
}
offset += 1 ;
return fetchItems("/dwcopa/getSlice?limit="+limit+"&offset="+offset+"&buCd="+BUCD);
}).flatMap(response -> Flux.fromIterable(response.getContent())).collectList();
}
private Mono<ResponseApiNeo> fetchItems(String url) {
System.out.println(url);
return webClient.get().uri(url).retrieve().bodyToMono(ResponseApiNeo.class);
}
之后得到所有结果:
writeStreamToFile ( myService.getItems().block().parallelStream().map(data -> data.toString()), "C:\\Users\\myfolder\\Documents\\optfile.txt") ;
我是 webflux 和 Webclient 的新手。此解决方案需要 25 分钟才能获取所有 Api REST 页面并创建一个未经客户端验证的文件 txt:
多线程有没有更好的解决方案:
- 分页一个孔休息API REST(760页):(大数据响应:JSON 6 GB)
- 将所有响应插入 SQL 数据库或创建 csv 文件?
- 性能至关重要(获取所有数据最多需要 5 分钟)
- 我应该更正我的代码以提高速度/添加线程吗?
非常感谢您的帮助。
【问题讨论】:
标签: java spring-boot performance stream reactive