xref: /aosp_15_r20/external/aws-sdk-java-v2/docs/BestPractices.md (revision 8a52c7834d808308836a99fc2a6e0ed8db339086)
1*8a52c783SCole Faust##  AWS Java SDK 2.x Best Practices
2*8a52c783SCole Faust
3*8a52c783SCole FaustHere are the best practices of using AWS Java SDK 2.x.
4*8a52c783SCole Faust
5*8a52c783SCole Faust### Reuse SDK client if possible
6*8a52c783SCole Faust
7*8a52c783SCole FaustEach SDK client maintains its own HTTP connection pool so that connections can be reused by a new request
8*8a52c783SCole Faustto cut down the time to establish a new connection. It is recommended to share a single instance of the client to
9*8a52c783SCole Faustavoid the overhead of having too many connection pools that are not being utilized effectively. All SDK clients are thread safe.
10*8a52c783SCole Faust
11*8a52c783SCole FaustIf it is not desirable to share a client instance, invoke `client.close()` to release the resources once the client is not needed.
12*8a52c783SCole Faust
13*8a52c783SCole Faust### Close input streams from client operations
14*8a52c783SCole Faust
15*8a52c783SCole FaustFor streaming operations such as `S3Client#getObject`,  if you are working with `ResponseInputStream` directly, we have the following recommendations:
16*8a52c783SCole Faust
17*8a52c783SCole Faust- Read all the data from the input stream as soon as possible
18*8a52c783SCole Faust- Close the input stream as soon as possible
19*8a52c783SCole Faust
20*8a52c783SCole FaustThis is because the input stream is a direct stream of data from the HTTP connection and the underlying HTTP connection cannot be
21*8a52c783SCole Faustreused until all data from the stream has been read and the stream is closed. If these rules are not followed, the client can
22*8a52c783SCole Faustrun out of resources by allocating too many open, but unused, HTTP connections.
23*8a52c783SCole Faust
24*8a52c783SCole Faust### Close input streams of responseBody() from Custom Client based on SdkHttpClient
25*8a52c783SCole FaustWhile implementing custom clients from  `SdkHttpClient` interface
26*8a52c783SCole Faust- 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.
27*8a52c783SCole Faust- SDK Requirement: The SDK requires the closing of the input stream to manage HTTP connections effectively.
28*8a52c783SCole Faust- Handling Error Responses: Even in the case of error responses, the SDK client creates an input stream for reading error data.
29*8a52c783SCole Faust- Consistent Practice: Ensure that consumers close the input stream in the "responseBody" attribute for both success and error cases.
30*8a52c783SCole Faust
31*8a52c783SCole Faust### Tune HTTP configurations based on performance tests
32*8a52c783SCole Faust
33*8a52c783SCole FaustThe 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.
34*8a52c783SCole Faust
35*8a52c783SCole Faust### Use OpenSSL for Netty async client
36*8a52c783SCole Faust
37*8a52c783SCole FaustBy default, `NettyNioAsyncHttpClient` uses JDK as the SslProvider. In our local tests, we found that using `OpenSSL`
38*8a52c783SCole Faustis more performant than JDK. Using OpenSSL is also the recommended approach by Netty community, see [Netty TLS with OpenSSL].
39*8a52c783SCole FaustNote that you need to add `netty-tcnative` to your dependency in order to use OpenSSL, see [Configuring netty-tcnative]
40*8a52c783SCole Faust
41*8a52c783SCole FaustOnce you have `netty-tcnative` configured correctly, `NettyAsyncHttpClient` will select OpenSSL automatically, or you can set the
42*8a52c783SCole Faust`SslProvider` explicitly on the NettyNioAsyncHttpClient builder.
43*8a52c783SCole Faust
44*8a52c783SCole Faust```
45*8a52c783SCole Faust   NettyNioAsyncHttpClient.builder()
46*8a52c783SCole Faust                          .sslProvider(SslProvider.OPENSSL)
47*8a52c783SCole Faust                          .build();
48*8a52c783SCole Faust```
49*8a52c783SCole Faust
50*8a52c783SCole Faust### Utilize timeout configurations
51*8a52c783SCole Faust
52*8a52c783SCole FaustThe SDK provides timeout configurations on requests out of box and they can be configured via `ClientOverrideConfiguration#apiCallAttemptTimeout` and `ClientOverrideConfiguration#ApiCallTimeout`.
53*8a52c783SCole Faust
54*8a52c783SCole Faust```java
55*8a52c783SCole Faust  S3Client.builder()
56*8a52c783SCole Faust          .overrideConfiguration(b -> b.apiCallTimeout(Duration.ofMillis(API_CALL_TIMEOUT))
57*8a52c783SCole Faust                                       .apiCallAttemptTimeout(Duration.ofMillis(API_CALL_ATTEMPT_TIMEOUT))
58*8a52c783SCole Faust          .build();
59*8a52c783SCole Faust```
60*8a52c783SCole Faust
61*8a52c783SCole Faust- `ApiCallAttemptTimeout` tracks the amount of time for a single http attempt and the request can be retried if timed out on api call attempt.
62*8a52c783SCole Faust- `ApiCallTimeout` configures the amount of time for the entire execution including all retry attempts.
63*8a52c783SCole Faust
64*8a52c783SCole FaustBy 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.
65*8a52c783SCole Faust
66*8a52c783SCole Faust[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
67*8a52c783SCole Faust[Netty TLS with OpenSSL]: https://netty.io/wiki/requirements-for-4.x.html#tls-with-openssl
68*8a52c783SCole Faust[Configuring netty-tcnative]: https://netty.io/wiki/forked-tomcat-native.html