Skip to content

Latest commit

 

History

History
68 lines (47 loc) · 4.21 KB

BestPractices.md

File metadata and controls

68 lines (47 loc) · 4.21 KB

AWS Java SDK 2.x Best Practices

Here are the best practices of using AWS Java SDK 2.x.

Reuse SDK client if possible

Each SDK client maintains its own HTTP connection pool so that connections can be reused by a new request to cut down the time to establish a new connection. It is recommended to share a single instance of the client to avoid the overhead of having too many connection pools that are not being utilized effectively. All SDK clients are thread safe.

If it is not desirable to share a client instance, invoke client.close() to release the resources once the client is not needed.

Close input streams from client operations

For streaming operations such as S3Client#getObject, if you are working with ResponseInputStream directly, we have the following recommendations:

  • Read all the data from the input stream as soon as possible
  • Close the input stream as soon as possible

This is because the input stream is a direct stream of data from the HTTP connection and the underlying HTTP connection cannot be reused until all data from the stream has been read and the stream is closed. If these rules are not followed, the client can run out of resources by allocating too many open, but unused, HTTP connections.

Close input streams of responseBody() from Custom Client based on SdkHttpClient

While implementing custom clients from SdkHttpClient interface

  • Close the responseBody Input Stream: Always close the "responseBody" input stream to release the HTTP Connection, even when handling error responses.
  • SDK Requirement: The SDK requires the closing of the input stream to manage HTTP connections effectively.
  • Handling Error Responses: Even in the case of error responses, the SDK client creates an input stream for reading error data.
  • Consistent Practice: Ensure that consumers close the input stream in the "responseBody" attribute for both success and error cases.

Tune HTTP configurations based on performance tests

The SDK provides a set of default http configurations that apply to general use cases. Customers are recommended to tune the configurations for their applications based on their use cases.

Use OpenSSL for Netty async client

By default, NettyNioAsyncHttpClient uses JDK as the SslProvider. In our local tests, we found that using OpenSSL is more performant than JDK. Using OpenSSL is also the recommended approach by Netty community, see Netty TLS with OpenSSL. Note that you need to add netty-tcnative to your dependency in order to use OpenSSL, see Configuring netty-tcnative

Once you have netty-tcnative configured correctly, NettyAsyncHttpClient will select OpenSSL automatically, or you can set the SslProvider explicitly on the NettyNioAsyncHttpClient builder.

   NettyNioAsyncHttpClient.builder()
                          .sslProvider(SslProvider.OPENSSL)
                          .build();

Utilize timeout configurations

The SDK provides timeout configurations on requests out of box and they can be configured via ClientOverrideConfiguration#apiCallAttemptTimeout and ClientOverrideConfiguration#ApiCallTimeout.

  S3Client.builder()
          .overrideConfiguration(b -> b.apiCallTimeout(Duration.ofMillis(API_CALL_TIMEOUT))
                                       .apiCallAttemptTimeout(Duration.ofMillis(API_CALL_ATTEMPT_TIMEOUT))
          .build();
  • ApiCallAttemptTimeout tracks the amount of time for a single http attempt and the request can be retried if timed out on api call attempt.
  • ApiCallTimeout configures the amount of time for the entire execution including all retry attempts.

By default, timeouts are disabled. Using them together is helpful to set a hard limit on total time spent on all attempts across retries and each individual HTTP request to fail fast on one slow request.