简体   繁体   English

使用 Java 11 HttpClient 同步与异步的外部服务调用

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM