[英]External service call with Java 11 HttpClient sync vs async
我的微服務正在調用外部服務 POST 調用,我想使用 Java 11 Httpclient。 這里 send() 和 sendAsync() 方法應該如何發揮作用? 我已經測試了多個請求,幾乎相同的延遲。 我嘗試使用 10 或 20 個或更多線程為我的服務執行 100 個端點調用。 兩種方法的結果幾乎相同。
我使用 sendAsync() 和 thenApply().get 來響應接收。 我想知道什么是首選方式,為什么? 使用異步也很快(這不是我目前的結果)?
提前感謝您的回答!
這是兩種方法的測試:
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;
}
}
示例輸出:
sync: start
async: start
async: end, got 26118 chars, took PT1.6102532S
sync: end, got 26118 chars, took PT4.3368509S
API 的並行級別越高,異步方法的性能就越好。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.