[英]External service call with Java 11 HttpClient sync vs async
My microservice is calling an external service POST call and I want to use Java 11 Httpclient.我的微服务正在调用外部服务 POST 调用,我想使用 Java 11 Httpclient。 Here how shall the send() and sendAsync() methods can make difference?
这里 send() 和 sendAsync() 方法应该如何发挥作用? I have tested with multiple amount of request, almost same latency.
我已经测试了多个请求,几乎相同的延迟。 I tried executing 100 endpoint call for my service with 10 or 20 thread or more.
我尝试使用 10 或 20 个或更多线程为我的服务执行 100 个端点调用。 The result for both methods are almost same.
两种方法的结果几乎相同。
I use sendAsync() with thenApply().get in response receive.我使用 sendAsync() 和 thenApply().get 来响应接收。 I would like to know what is preferred way and why?
我想知道什么是首选方式,为什么? Is using async is also fast(which is not as per my current result)?
使用异步也很快(这不是我目前的结果)?
Thanks in advance for your answers!提前感谢您的回答!
Here's a test of both methods:这是两种方法的测试:
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpRequest.Builder;
import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodyHandlers;
import java.time.Duration;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executors;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class HttpClientTest {
static final int REQUEST_COUNT = 100;
static final String URI_TEMPLATE = "https://jsonplaceholder.typicode.com/posts/%d";
public static void main(final String[] args) throws Exception {
final List<HttpRequest> requests = IntStream.rangeClosed(1, REQUEST_COUNT)
.mapToObj(i -> String.format(URI_TEMPLATE, i))
.map(URI::create)
.map(HttpRequest::newBuilder)
.map(Builder::build)
.collect(Collectors.toList());
final HttpClient client = HttpClient.newBuilder()
.executor(Executors.newFixedThreadPool(REQUEST_COUNT))
.build();
final ThrowingFunction<HttpRequest, String> sendSync =
request -> client.send(request, BodyHandlers.ofString()).body();
final ThrowingFunction<CompletableFuture<HttpResponse<String>>, String> getSync =
future -> future.get().body();
benchmark("sync", () -> requests.stream()
.map(sendSync)
.collect(Collectors.toList()));
benchmark("async", () -> requests.stream()
.map(request -> client.sendAsync(request, BodyHandlers.ofString()))
.collect(Collectors.toList()) // materialize to send the requests
.stream()
.map(getSync)
.collect(Collectors.toList()));
}
static void benchmark(final String name, final Supplier<List<String>> supplier) {
new Thread(() -> {
final long start = System.nanoTime();
System.out.printf("%s: start%n", name);
final List<String> result = supplier.get();
final Duration duration = Duration.ofNanos(System.nanoTime() - start);
final int size = result.stream()
.mapToInt(String::length)
.sum();
System.out.printf("%s: end, got %d chars, took %s%n", name, size, duration);
}, name).start();
}
@FunctionalInterface
static interface ThrowingFunction<T, R> extends Function<T, R> {
default R apply(final T t) {
try {
return applyThrowing(t);
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
R applyThrowing(T t) throws Exception;
}
}
Example output:示例输出:
sync: start
async: start
async: end, got 26118 chars, took PT1.6102532S
sync: end, got 26118 chars, took PT4.3368509S
The higher the parallelism level of the API, the better the asynchronous method will perform. API 的并行级别越高,异步方法的性能就越好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.