AWS-Java-SDK2优化

  1. HTTP异步配置
    1. 基于netty的异步非阻塞io
    2. 请求/响应摘要日志记录

SDK 官方文档

[TOC]

HTTP异步配置

基于netty的异步非阻塞io

1
2
3
4
5
 <dependency>
<artifactId>netty-nio-client</artifactId>
<groupId>software.amazon.awssdk</groupId>
<version>2.0.0</version>
</dependency>

最大连接数:

可以通过使用 maxConcurrency 方法来设置允许打开的最大 HTTP 连接数。您可以使用 maxPendingConnectionAcquires 方法设置在达到最大并发数后,允许排队的最大请求数。

maxConcurrency 默认值:50

maxPendingConnectionAcquires 默认值:10_000

将最大连接数设置为并发事务的数量可避免连接争用和性能不佳。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
KinesisAsyncClient client = KinesisAsyncClient.builder()
// netty http client
.httpClientBuilder(NettyNioAsyncHttpClient.builder()
.maxConcurrency(100)
.maxPendingConnectionAcquires(10_000))
.build();
```



```java
SdkAsyncHttpClient httpClient = NettyNioAsyncHttpClient.builder()
.maxConcurrency(100)
.maxPendingConnectionAcquires(10_000)
.build();

KinesisAsyncClient kinesisClient = KinesisAsyncClient.builder()
.httpClient(httpClient)
.build();

httpClient.close();
```

## 开发包启动时间

AWS SDK for Java 2.0 中的改进之一是 Lambda 中 Java 函数的开发工具包启动时间。这是 Java Lambda 函数启动并响应其第一个请求所需的时间。

版本 2.x 中采用了 3 项更改来促成了这一改进:

使用 jackson-jr,它是一个序列化库,可以改进初始化时间。

对日期和时间对象使用 java.time.libraries。

为记录 facade 切换到 Slf4j。

您可以通过在客户端生成器上设置特定配置值,实现更多的开发工具包启动时间改进。通过减少应用程序需要为初始化找到的信息量,它们均可以节省一些启动时间。

注意

指定这些值时,您的代码的可移植性会差一些。例如,通过指定 AWS 区域,代码在其他区域中未经修改就无法运行。

#### 示例:最短开发工具包启动时间客户端配置

```java
S3Client client = S3Client.builder()
.region(Region.US_WEST_2)
.credentialsProvider(EnvironmentVariableCredentialsProvider.create())
.httpClientBuilder(UrlConnectionHttpClient.builder())
.build();
```

## **异步非阻塞(反应式)编程**

AWS SDK for Java 2.0 具有真正的**非阻塞异步客户端**,可以**跨多个线程实现高并发度**。
AWS SDK for Java 1.11.x 具有异步客户端,**该客户端是围绕线程池和阻塞同步客户端(未提供非阻塞 I/O 的所有优势)的包装程序。**

同步方法会阻止执行您的线程,直到客户端接收到服务的响应。**异步方法会立即返回,并控制调用的线程,而不必等待响应。**

由于异步方法在收到响应之前返回,所以需要通过某种方法接收返回的响应。AWS SDK for Java 2.0 异步客户端方法**将返回 CompletableFuture 对象**,该对象可让您在响应准备就绪时访问响应。

#### 非流式操作

对于非流式操作,异步方法调用与同步方法类似,只不过AWS SDK for Java中的异步方法会返回 CompletableFuture 对象,该对象包含之后的异步操作的结果。

当结果可用时,使用要完成的操作调用 CompletableFuture whenComplete() 方法。CompletableFuture 实现 Future 接口,以便您还可以通过调用 get() 方法来获得响应对象。

以下示例演示一个调用 DynamoDB 函数以获取表列表的异步操作,该操作收到可包含 ListTablesResponse 对象的 CompletableFuture。在调用 whenComplete() 时定义的操作仅在异步调用完成时完成。

```java
public class DynamoDBAsync {

public static void main(String[] args) throws InterruptedException {
// Creates a default async client with credentials and regions loaded from the environment
DynamoDbAsyncClient client = DynamoDbAsyncClient.create();
CompletableFuture<ListTablesResponse> response = client.listTables(ListTablesRequest.builder()
.build());

// Map the response to another CompletableFuture containing just the table names
CompletableFuture<List<String>> tableNames = response.thenApply(ListTablesResponse::tableNames);
// When future is complete (either successfully or in error) handle the response
tableNames.whenComplete((tables, err) -> {
try {
if (tables != null) {
tables.forEach(System.out::println);
} else {
// Handle error
err.printStackTrace();
}
} finally {
// Lets the application shut down. Only close the client when you are completely done with it.
client.close();
}
});

tableNames.join();
}
}
```

#### 流式操作

对于流式操作,您必须提供 AsyncRequestBody 来以递增方式提供内容,或者提供 AsyncResponseTransformer 以接收和处理响应。

下面是使用 PutObject 操作将文件异步上传到 Amazon S3 的示例。

```java
public class S3AsyncOps {

private static final String BUCKET = "sample-bucket";
private static final String KEY = "testfile.in";

public static void main(String[] args) {
S3AsyncClient client = S3AsyncClient.create();
CompletableFuture<PutObjectResponse> future = client.putObject(
PutObjectRequest.builder()
.bucket(BUCKET)
.key(KEY)
.build(),
AsyncRequestBody.fromFile(Paths.get("myfile.in"))
);
future.whenComplete((resp, err) -> {
try {
if (resp != null) {
System.out.println("my response: " + resp);
} else {
// Handle error
err.printStackTrace();
}
} finally {
// Lets the application shut down. Only close the client when you are completely done with it.
client.close();
}
});

future.join();
}
}
```

下面是使用 GetObject 操作从 Amazon S3 中异步获取文件的示例。

```java
public class S3AsyncStreamOps {

private static final String BUCKET = "sample-bucket";
private static final String KEY = "testfile.out";

public static void main(String[] args) {
S3AsyncClient client = S3AsyncClient.create();
final CompletableFuture<GetObjectResponse> futureGet = client.getObject(
GetObjectRequest.builder()
.bucket(BUCKET)
.key(KEY)
.build(),
AsyncResponseTransformer.toFile(Paths.get("myfile.out")));
futureGet.whenComplete((resp, err) -> {
try {
if (resp != null) {
System.out.println(resp);
} else {
// Handle error
err.printStackTrace();
}
} finally {
// Lets the application shut down. Only close the client when you are completely done with it
client.close();
}
});

futureGet.join();
}
}

```

## HTTP2

HTTP/2 是 HTTP 协议的一个主要修订。这一新版本具有多个增强功能以提高性能:

* 二进制数据编码提供了更高效的数据传输。

* 标头压缩可减少客户端下载的开销字节数,同时帮助客户端更快地获取内容。这对于受带宽限制的移动客户端尤其有用。

* **双向异步通信(多路复用)可让客户端和 AWS 之间的多个请求和响应消息同时通过单一连接(而不是通过多个连接)进行传输,这样可以提高性能。**

升级到最新开发工具包的开发人员将自动使用 HTTP/2(如果他们使用的服务支持)。新编程接口无缝地利用 HTTP/2 功能并提供新的方法来构建应用程序。

AWS SDK for Java 2.0 提供了新的实施 HTTP/2 协议的 API 进行事件流式传输。有关如何使用这些新 API 的示例,请参阅使用适用于 Java 的 AWS 开发工具包的 Kinesis 示例。

## 异常处理

#### SdkServiceException(和子类)

SdkServiceException 是在使用AWS SDK for Java时最常遇到的异常。该异常是指来自 AWS 服务的错误响应。例如,如果您尝试终止不存在的 Amazon EC2 实例,EC2 会返回错误响应,而且引发的 SdkServiceException 中会包含该错误响应的所有详细信息。在某些情况下,会引发 SdkServiceException 的一个子类,使开发人员能够通过捕获模块精细控制如何处理错误情况。

当您遇到 SdkServiceException 时,您就会知道,您的请求已成功发送到 AWS 服务,但无法成功处理。这可能是因为请求的参数中存在错误,或者是因为服务端的问题。

SdkServiceException 为您提供很多信息,例如:

* 返回的 HTTP 状态代码
* 返回的 AWS 错误代码
* 来自服务的详细错误消息
* 已失败请求的 AWS 请求 ID

#### SdkClientException

SdkClientException 指示在尝试将请求发送到 AWS 或者在尝试解析来自 AWS 的响应时,Java 客户端代码内出现问题。在一般情况下,SdkClientException 比 SdkServiceException 严重,前者指示出现严重问题,导致客户端无法对 AWS 服务进行服务调用。例如,如果您在尝试对一个客户端执行操作时网络连接不可用,AWS SDK for Java会引发 SdkClientException。

## 日志记录

#### 特定服务的错误消息和警告

我们建议您始终将“software.amazon.awssdk”记录器层次结构设置为“WARN”,以保证不会错过来自客户端库的任何重要消息。例如,如果 Amazon S3 客户端检测到应用程序没有正确关闭 InputStream 而且可能会泄漏资源,那么 S3 客户端将通过向日志中记录警告消息来进行报告。另外,由此可确保客户端在处理请求或响应遇到任何问题时会记录相应消息。

```text
<Configuration status="WARN">
<Appenders>
<Console name="ConsoleAppender" target="SYSTEM_OUT">
<PatternLayout pattern="%d{YYYY-MM-dd HH:mm:ss} [%t] %-5p %c:%L - %m%n" />
</Console>
</Appenders>

<Loggers>
<Root level="WARN">
<AppenderRef ref="ConsoleAppender"/>
</Root>
<Logger name="software.amazon.awssdk" level="WARN" />
</Loggers>
</Configuration>

请求/响应摘要日志记录

对 AWS 服务的所有请求都会生成一个 AWS 请求 ID,如果您遇到与 AWS 服务处理请求有关的问题,可以使用它。如果调用任何服务失败,可以通过开发工具包中的 Exception 对象以编程方式访问 AWS 请求 ID,还可以通过“software.amazon.awssdk.request”记录器中的 DEBUG 日志级别报告 AWS 请求 ID。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<Configuration status="WARN">
<Appenders>
<Console name="ConsoleAppender" target="SYSTEM_OUT">
<PatternLayout pattern="%d{YYYY-MM-dd HH:mm:ss} [%t] %-5p %c:%L - %m%n" />
</Console>
</Appenders>

<Loggers>
<Root level="WARN">
<AppenderRef ref="ConsoleAppender"/>
</Root>
<Logger name="software.amazon.awssdk" level="WARN" />
<Logger name="software.amazon.awssdk.request" level="DEBUG" />
</Loggers>
</Configuration>

以下是日志输出的示例:

1
2018-01-28 19:31:56 [main] DEBUG software.amazon.awssdk.request:Logger.java:78 - Sending Request: software.amazon.awssdk.http.DefaultSdkHttpFullRequest@3a80515c

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 wshten@gmail.com

文章标题:AWS-Java-SDK2优化

本文作者:KevinTen

发布时间:2019-09-19, 00:00:00

最后更新:2019-09-20, 12:15:10

原始链接:http://github.com/kevinten10/2019/09/19/AWS/sdk/Aws-Java-SDK2优化/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录
×

喜欢就点赞,疼爱就打赏

csdn zhihu github