We are pleased to announce the preview release of AWS Common Runtime (CRT) HTTP Client – a new HTTP client supported in the AWS SDK for Java 2.x. AWS CRT HTTP Client is an asynchronous, non-blocking HTTP client built on top of the Java bindings of the AWS Common Runtime. You can use the CRT HTTP client to benefit from features such as improved performance, connection health checks, and post-quantum TLS support. It is the second first-party asynchronous HTTP client supported by the SDK for Java after Netty NIO HTTP client.
Using the AWS CRT HTTP Client
To use the HTTP client, first add
aws-crt-client dependency to your pom.xml
<dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>aws-crt-client</artifactId> <version>2.14.13-PREVIEW</version> </dependency>
Then, configure your service to use the CRT HTTP client in one of the following ways.
Option 1: Specify the CRT HTTP client through the client builder
This is the preferred option. It allows you to customize configurations such as max connections based on your use-case.
// Creating an asynchronous client with an CRT HTTP client that is managed by the SDK S3AsyncClient.builder() .httpClientBuilder(AwsCrtAsyncHttpClient.builder() .maxConcurrency(50)) .build(); // Creating an CRT HTTP Client that can be shared across multiple SDK clients. SdkAsyncHttpClient crtClient = AwsCrtAsyncHttpClient.create() S3AsyncClient.builder() .httpClient(crtClient) .build();
Option 2: Remove other async HTTP clients from the classpath
If HTTP client is not specified on the SDK client builder, the SDK will use ServiceLoader to find HTTP implementations on the classpath. With the default configuration, the SDK includes Netty HTTP client dependency, and by removing the
netty-nio-client dependency and including
aws-crt-client on the classpath, the SDK will use the CRT HTTP client automatically. Below is the sample POM file for an application that only has CRT HTTP client on the classpath.
<dependencies> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>s3</artifactId> <version>2.14.13</version> <exclusions> <exclusion> <groupId>software.amazon.awssdk</groupId> <artifactId>netty-nio-client</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>aws-crt-client</artifactId> <version>2.14.13-PREVIEW</version> </dependency> </dependencies>
Option 3: Change the default HTTP client using a system property at JVM startup
This option will create an CRT HTTP client with default configurations.
# Specify the default asynchronous HTTP client as AwsCrtAsyncHttpClient java -Dsoftware.amazon.awssdk.http.async.service.impl= software.amazon.awssdk.http.crt.AwsCrtSdkHttpService MyService.jar
Option 4: Change the default HTTP client using a system property in Java code.
This option will create an CRT HTTP client with default configurations.
// Set the default asynchronous HTTP client to AwsCrtAsyncHttpClient System.setProperty("software.amazon.awssdk.http.async.service.impl", "software.amazon.awssdk.http.crt.AwsCrtSdkHttpService");
Improved cold-start time and throughput
The CRT further improves the startup time performance of the SDK for Java, which remains one of the most common customer feature requests. The CRT HTTP client has faster cold-start time compared to other HTTP clients supported in the SDK.
Current customers of the NettyNioAsyncHttpClient can see performance improvements up to 46% depending on your application configuration. Below is a graph comparing the Lambda cold start duration, using the S3 service client to invoke ListBuckets with the ApacheHttpClient, HttpUrlConnectionClient, NettyNioAsyncHttpClient and CRT HTTP clients.
In addition to cold-start improvement, when we compared the CRT HTTP client with NettyNioAsyncClient in our local testing using the Java Microbenchmark Harness (JMH), we’ve seen throughput improvements up to 17% for concurrent API calls and up to 32% for sequential API calls.
Benchmark Mode Cnt Score Error Units AwsCrtClientBenchmark.concurrentApiCall thrpt 10 15436.039 ? 121.457 ops/s AwsCrtClientBenchmark.sequentialApiCall thrpt 10 4165.730 ? 53.552 ops/s NettyHttpClientH1Benchmark.concurrentApiCall thrpt 10 13083.555 ? 68.426 ops/s NettyHttpClientH1Benchmark.sequentialApiCall thrpt 10 3141.245 ? 37.782 ops/s
DNS load balancing support
The Java virtual machine (JVM) caches DNS name lookups for a specific period of time, known as the time-to-live(TTL). Because DNS name entries used by AWS services can occasionally change, it’s important to set the TTL to a smaller value so that it periodically refreshes its cached IP information. Customers often need to set the TTL value manually via the system property
networkaddress.cache.ttl with other existing HTTP clients, and finding out an appropriate value often requires extensive research and testing. The CRT HTTP client has an asynchronous DNS resolver that polls each requested DNS address at a regular interval, so customers do not need configure the TTL value themselves. In addition, the CRT HTTP client has first-class IPv6 support. It implements Happy Eyeballs; when the client sends out a new request, it will attempt to connect to the IPv6 first and falls back to the IPV4 address if IPv6 is not supported.
Slow connection detection and configuration
The CRT HTTP client provides HTTP connection monitoring options that allow you to configure HTTP connection health checks. You can set a throughput threshold for a connection to be considered healthy. If the connection falls below this threshold for a configured amount of time, the connection is considered unhealthy and will be shut down. If your application is hitting a network path that results in dramatically slower throughput speeds, this configuration will help the application recover by closing the slow connection and establishing a fresh connection for new requests.
In the following configuration example, a connection with throughput lower than 32000 bytes per second will be shut down after 3 seconds
AwsCrtAsyncHttpClient.builder() .connectionHealthChecksConfiguration( b -> b.minThroughputInBytesPerSecond(32000L) .allowableThroughputFailureInterval(Duration.ofSeconds(3))) .build();
Post-quantum TLS support for KMS
Post-quantum hybrid key exchange for Transport Layer Security (TLS) connections is a feature supported in AWS Key Management Service (AWS KMS) that adds new, post-quantum cipher suites when connecting to AWS KMS API endpoints. Post-quantum TLS provides additional security protections that protects your TLS traffic from being decrypted by a large-scale quantum computer in the future. You can find more information in the Post-quantum TLS now supported in AWS KMS blog post.
To use this feature with the KMS client, you can configure the CRT HTTP Client to use the
TLS_CIPHER_KMS_PQ_TLSv1_0_2019_06 cipher preference as follows
SdkAsyncHttpClient awsCrtHttpClient = AwsCrtAsyncHttpClient.builder() .tlsCipherPreference(TlsCipherPreference.TLS_CIPHER_KMS_PQ_TLSv1_0_2019_06) .build(); KmsAsyncClient kms = KmsAsyncClient.builder() .httpClient(awsCrtHttpClient) .build();
At the time of this release, the CRT HTTP Client only supports the HTTP/1.1 protocol, so you can’t use the CRT HTTP Client with SDK clients that require HTTP/2 support such as
TranscribeStreamingAsyncClient. While client-side metrics are generally available, specific HTTP metrics for the CRT are not yet implemented. We are planning to implement this feature, which allows you to detect, diagnose issues and monitor the resources in the CRT HTTP Client, in the near future.
For more information on using the CRT HTTP client, visit our API References. You can also check out the aws-crt-client module on GitHub. Try out this new CRT HTTP client today and let us know what you think via the GitHub issues page!