Spring 启动异步休息调用
Spring boot Async rest call
我正在尝试创建一个调度程序,它向 Web 服务发送获取请求并获取我们需要的项目数。然后将总计除以 per_page 然后发送所需的任意数量的请求,但请求是异步的。
我的代码在我的测试中运行良好 class 但在主应用程序中我收到两个基于 JDK 版本
的错误
这是我的 API 服务:
public interface RestService {
@Async
CompletableFuture<UpcomingEventsResponse> getUpcomingEvents(int page,String day, String token);
UpcomingEventsResponse getUpcomingEvents(String day,String token);
}
我的 RestService 实现:
@Service
@RequiredArgsConstructor
@Slf4j
public class RestServiceImpl implements RestService {
public static final String UPCOMING_EVENTS_URL = "HTTP://localhost/test";
private final RestTemplate restTemplate;
@Override
public CompletableFuture<UpcomingEventsResponse> getUpcomingEvents(int page,String day, String token) {
String url = createUrl(UPCOMING_EVENTS_URL,createQuery("day",day),createQuery("page", page), createQuery("token", token));
return makeCallAsync(url,HttpMethod.GET,null,UpcomingEventsResponse.class);
}
@Override
public UpcomingEventsResponse getUpcomingEvents(String day,String token) {
String url = createUrl(UPCOMING_EVENTS_URL,createQuery("day",day), createQuery("page", 1), createQuery("token", token));
return makeCall(url,HttpMethod.GET,null,UpcomingEventsResponse.class);
}
private <T> T makeCall(String url,
HttpMethod method,
HttpEntity<Object> httpEntity,
Class<T> outClass) {
return restTemplate.exchange(url, method, httpEntity, outClass).getBody();
}
private <T> CompletableFuture<T> makeCallAsync(String url,
HttpMethod method,
HttpEntity<Object> httpEntity,
Class<T> outClass) {
return CompletableFuture.completedFuture(restTemplate.exchange(url, method, httpEntity, outClass).getBody());
}
}
这是我的调度程序 class :
@Component
@RequiredArgsConstructor
@Slf4j
public class EventScheduler {
private final RestService restService;
//TODO change time
@Scheduled(cron = "0 */2 * * * *")
public void getAllEvents(){
long start = System.currentTimeMillis();
//TODO add token from database or env
UpcomingEventsResponse upcomingEvents = restService.getUpcomingEvents(null, "token");
List<ResultsItem> resultsItems = new ArrayList<>(upcomingEvents.getResults());
List<CompletableFuture<UpcomingEventsResponse>> completableFutures = new ArrayList<>();
int repeatTimes = upcomingEvents.getPager().getTotal() / upcomingEvents.getPager().getPerPage();
for (int i = 0; i < repeatTimes; i++) {
int page = i + 2;
CompletableFuture<UpcomingEventsResponse> events = restService.getUpcomingEvents(page, null, "token");
completableFutures.add(events);
}
CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0])).join();
log.info("Elapsed time: " + (System.currentTimeMillis() - start));
completableFutures.forEach(completableFuture -> {
try {
resultsItems.addAll(completableFuture.get().getResults());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
});
log.info("Size " + resultsItems.size());
log.info("Total " + upcomingEvents.getPager().getTotal());
}
}
这是我在 JDK 8 中遇到的错误:
peer not authenticated; nested exception is javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
这是 JDK 10 或 11 上的错误:
javax.net.ssl.SSLException: No PSK available. Unable to resume
有更好的方法吗?问题是什么?这是一个错误吗?
问题出在Web Service上,虽然在不同的JDK中我实在搞不懂错误的原因。据我所知,这是一个已知错误,您可以阅读更多相关信息
这个实现工作得很好,你可以使用 Apache HTTP Client with resttemplate but you can't use OkHttp or Apache HttpClient with Spring webflux WebService
我正在尝试创建一个调度程序,它向 Web 服务发送获取请求并获取我们需要的项目数。然后将总计除以 per_page 然后发送所需的任意数量的请求,但请求是异步的。
我的代码在我的测试中运行良好 class 但在主应用程序中我收到两个基于 JDK 版本
的错误这是我的 API 服务:
public interface RestService {
@Async
CompletableFuture<UpcomingEventsResponse> getUpcomingEvents(int page,String day, String token);
UpcomingEventsResponse getUpcomingEvents(String day,String token);
}
我的 RestService 实现:
@Service
@RequiredArgsConstructor
@Slf4j
public class RestServiceImpl implements RestService {
public static final String UPCOMING_EVENTS_URL = "HTTP://localhost/test";
private final RestTemplate restTemplate;
@Override
public CompletableFuture<UpcomingEventsResponse> getUpcomingEvents(int page,String day, String token) {
String url = createUrl(UPCOMING_EVENTS_URL,createQuery("day",day),createQuery("page", page), createQuery("token", token));
return makeCallAsync(url,HttpMethod.GET,null,UpcomingEventsResponse.class);
}
@Override
public UpcomingEventsResponse getUpcomingEvents(String day,String token) {
String url = createUrl(UPCOMING_EVENTS_URL,createQuery("day",day), createQuery("page", 1), createQuery("token", token));
return makeCall(url,HttpMethod.GET,null,UpcomingEventsResponse.class);
}
private <T> T makeCall(String url,
HttpMethod method,
HttpEntity<Object> httpEntity,
Class<T> outClass) {
return restTemplate.exchange(url, method, httpEntity, outClass).getBody();
}
private <T> CompletableFuture<T> makeCallAsync(String url,
HttpMethod method,
HttpEntity<Object> httpEntity,
Class<T> outClass) {
return CompletableFuture.completedFuture(restTemplate.exchange(url, method, httpEntity, outClass).getBody());
}
}
这是我的调度程序 class :
@Component
@RequiredArgsConstructor
@Slf4j
public class EventScheduler {
private final RestService restService;
//TODO change time
@Scheduled(cron = "0 */2 * * * *")
public void getAllEvents(){
long start = System.currentTimeMillis();
//TODO add token from database or env
UpcomingEventsResponse upcomingEvents = restService.getUpcomingEvents(null, "token");
List<ResultsItem> resultsItems = new ArrayList<>(upcomingEvents.getResults());
List<CompletableFuture<UpcomingEventsResponse>> completableFutures = new ArrayList<>();
int repeatTimes = upcomingEvents.getPager().getTotal() / upcomingEvents.getPager().getPerPage();
for (int i = 0; i < repeatTimes; i++) {
int page = i + 2;
CompletableFuture<UpcomingEventsResponse> events = restService.getUpcomingEvents(page, null, "token");
completableFutures.add(events);
}
CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0])).join();
log.info("Elapsed time: " + (System.currentTimeMillis() - start));
completableFutures.forEach(completableFuture -> {
try {
resultsItems.addAll(completableFuture.get().getResults());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
});
log.info("Size " + resultsItems.size());
log.info("Total " + upcomingEvents.getPager().getTotal());
}
}
这是我在 JDK 8 中遇到的错误:
peer not authenticated; nested exception is javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
这是 JDK 10 或 11 上的错误:
javax.net.ssl.SSLException: No PSK available. Unable to resume
有更好的方法吗?问题是什么?这是一个错误吗?
问题出在Web Service上,虽然在不同的JDK中我实在搞不懂错误的原因。据我所知,这是一个已知错误,您可以阅读更多相关信息
这个实现工作得很好,你可以使用 Apache HTTP Client with resttemplate but you can't use OkHttp or Apache HttpClient with Spring webflux WebService