| ## 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](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/HttpExecuteResponse.html#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`. |
| |
| ```java |
| 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. |
| |
| [default http configurations]: https://github.com/aws/aws-sdk-java-v2/blob/master/http-client-spi/src/main/java/software/amazon/awssdk/http/SdkHttpConfigurationOption.java |
| [Netty TLS with OpenSSL]: https://netty.io/wiki/requirements-for-4.x.html#tls-with-openssl |
| [Configuring netty-tcnative]: https://netty.io/wiki/forked-tomcat-native.html |