我们需要开发一种服务,该服务应能够处理大量流量,即大约5TPS。我们必须进行3-4个并行的下游Rest调用(下面提到的是带有2个Rest调用的POC)->汇总所有响应->做一些处理->将响应发送回使用者。服务端点已同步。
我正在尝试使用Completable future实现它,以进行异步rest调用和join方法来汇总响应,如下所示:{ ResponseWrapper response = null;
CompletableFuture<Student> s = CompletableFuture.supplyAsync(() -> {
return studentService.getStudentDetails(requestContext, id, name, correlationId);
},pool
).exceptionally(ex -> {
log.error("Something went wrong in devicedm: ", ex);
Student wrapper = new Student();
wrapper.setStatus("500");
Errors err = new Errors();
err.setDescription(ex.getCause().toString());
wrapper.setError(err);
return wrapper;
}
);
CompletableFuture<Employee> s1 = CompletableFuture.supplyAsync(() -> {
return employeeService.getEmployeeDetails(requestContext, id, name, correlationId);
},pool
).exceptionally(ex -> {
log.error("Something went wrong in Employee: ", ex);
Employee wrapper = new Employee();
wrapper.setStatus(500);
Errors err = new Errors();
err.setDescription(ex.getCause().toString());
wrapper.setError(err);
return wrapper;
}
);
CompletableFuture<ResponseWrapper> combinedDataCompletionStage = CompletableFuture.allOf(s, s1)
.thenApply(ignoredVoid -> combine(s.join(), s1.join()));
try {
response = combinedDataCompletionStage.get();
} catch (InterruptedException | ExecutionException e) {
Errors error = new Errors();
error.setDescription(e.getCause().toString());
response.setError(error);
}
private ResponseWrapper combine(Student s, Employee s1) {
ResponseWrapper response = new ResponseWrapper();
response.setStudentInfo(s);
response.setEmployeeInfo(s1);
return response;
}
}
因此,需要帮助以了解在我们使用完全完成的将来并且可用于处理其他请求时,是否在休息调用完成后立即释放两个线程s和s1?
join方法的行为如何,从java doc看来,它将等待s和s1返回响应,然后将执行join操作。这是通话阻塞吗?
并且一旦汇总了响应,我们就必须进行get调用,这将向我们返回最终的响应,如下所示:
响应= CombinedDataCompletionStage.get();
我曾尝试使用Jmeter进行性能测试,但无法得出结论,想知道这种方法是否可以实现所需的吞吐量,或者是否需要对上述代码进行任何修改,或者考虑到这么多Java都存在局限性IO通话?如果是,那么在NodeJ中可行吗?
任何建议将不胜感激!
因此,您希望最大化并行度较低的吞吐量。最好的方法是使用线程而不是CompletableFuture。当然,Node.js并不是更好的变体。
让主线程(处理请求)启动并行线程,这些并行线程进行下游的rest调用。让线程将结果保存在特殊对象中,该对象在所有其余调用完成时通知主线程。然后,主线程进行处理并将响应发送回使用者。
异步I / O的性能较低,并且仅当线程数太多而无法容纳可用的核心内存时才必须使用。