How do I monitor performance and latency of Java 11 HTTP requests?

Monitoring the performance and latency of Java 11 HTTP requests is essential when utilizing the java.net.http package introduced with the new Java 11 HttpClient API. It helps identify bottlenecks, optimize network calls, and ensure efficient resource usage for your application.

Here’s how you can do it:

1. Measure Latency Using Timestamps

You can manually measure the time taken to send and receive HTTP requests by recording timestamps before and after executing the HTTP call.

package org.kodejava.net.http;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.time.Instant;

public class HttpPerformanceMonitor {
    public static void main(String[] args) throws Exception {
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(new URI("https://example.com"))
                .GET()
                .build();

        // Record start time
        Instant start = Instant.now();

        // Send request and get response
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

        // Record end time
        Instant end = Instant.now();

        // Calculate latency
        Duration latency = Duration.between(start, end);
        System.out.println("Response time: " + latency.toMillis() + " ms");
        System.out.println("Response status code: " + response.statusCode());
    }
}

This approach calculates the time taken for the entire HTTP operation, including connection establishment, sending the request, and receiving the response.

2. Use a Custom Executor to Monitor Thread Usage

HttpClient allows you to set a custom Executor for handling its asynchronous operations. You can measure how efficiently the threads are being utilized.

package org.kodejava.net.http;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;

public class HttpClientWithCustomExecutor {
    public static void main(String[] args) throws Exception {
        ExecutorService executor = Executors.newFixedThreadPool(4); // Monitor thread usage

        HttpClient client = HttpClient.newBuilder()
                .executor(executor)
                .build();

        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://example.com"))
                .GET()
                .build();

        long startTime = System.currentTimeMillis();

        client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
                .thenAccept(response -> {
                    long endTime = System.currentTimeMillis();
                    System.out.println("Response time: " + (endTime - startTime) + " ms");
                    System.out.println("Response status code: " + response.statusCode());
                })
                .join(); // Wait for the async call to complete

        executor.shutdown();
    }
}

By setting a custom Executor, you can track thread pool utilization and capture latency.

3. Enable Logging for HTTP Headers and Debugging

Java 11 supports configuring logging for the HTTP Client. You can enable debug-level logging to capture low-level details:

  • Add the following JVM options to enable java.net.http.HttpClient debugging:
-Djdk.httpclient.HttpClient.log=requests,headers,frames:all

This will output detailed log information, including HTTP request/response headers and frames.

4. Monitor HTTP Client Metrics Using Libraries

Libraries that support metrics collection (like Micrometer) can be integrated with Java 11 HttpClient to collect throughput, response times, and errors.
Example: Using Micrometer You can create custom timers and counters to record metrics manually.

package org.kodejava.net.http;

import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.TimeUnit;

public class HttpClientWithMetrics {
    public static void main(String[] args) throws Exception {
        MeterRegistry registry = new SimpleMeterRegistry(); // Replace with a distributed registry like Prometheus

        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(new URI("https://example.com"))
                .GET()
                .build();

        registry.timer("http.requests").record(() -> {
            try {
                Instant start = Instant.now();
                HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
                Instant end = Instant.now();

                System.out.println("Response time: " + Duration.between(start, end).toMillis() + " ms");
                System.out.println("Response status code: " + response.statusCode());
            } catch (Exception e) {
                e.printStackTrace();
            }
        });

        registry.get("http.requests").timers().forEach(timer -> {
            System.out.println("Timer count: " + timer.count());
            System.out.println("Total time: " + timer.totalTime(TimeUnit.MILLISECONDS) + " ms");
        });
    }
}

5. Use Dependency Injection Frameworks

Combine the Java 11 HttpClient with Spring Boot’s actuator (if you’re already using it). Actuator provides built-in metrics and HTTP tracing capabilities.

6. Profiling with External Tools

You can observe Java application performance (including HTTP requests) using APM tools, such as:

  • Java Flight Recorder (JFR)
    • Use JFR to monitor detailed HTTP request timings and underlying JVM performance.
  • Java VisualVM
    • Profile application threads and network usage.
  • Third-Party APMs
    • Tools like New Relic, AppDynamics, or Datadog can report on HTTP client usage.

Summary of Approaches

Approach Tools/Techniques Notes
Manual Timing Instant + Duration Tracks latency at the request level.
Custom Executors ExecutorService Measures thread usage and async execution.
Logging JVM Debugging (HttpClient.log) Debugs detailed network activity.
Metrics Libraries Micrometer (manual instrumentation) Can feed metrics into observability tools.
Framework Integration Spring Boot Actuator Collects trace and performance metrics.
External Profiling/Monitoring JFR, APM Tools, VisualVM Monitors JVM, HTTP, and app performance.

Choose the approach based on your application’s complexity and monitoring needs!


Maven Dependencies

<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-core</artifactId>
    <version>1.15.0</version>
</dependency>

Maven Central

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.