

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 在AWS SDK for Java 2.x 中配置超时
<a name="timeouts"></a>

AWS SDK for Java 2.x 提供了多层超时配置，可协助您构建弹性应用程序。SDK 提供不同类型的超时，它们协同作用来优化应用程序的性能和可靠性。

SDK 中的超时主要分为两大类：
+ **服务客户端超时** - 控制 API 操作的高级别超时
+ **HTTP 客户端超时** - 控制网络通信的低级别超时

## 服务客户端超时
<a name="service-client-timeouts"></a>

服务客户端超时在 API 级别运行，用于控制服务操作的整体行为，包括重试和多次尝试。

### API 调用超时
<a name="api-call-timeout"></a>

API 调用超时设置整个 API 操作的最大时间，包括所有重试尝试。此超时为应用程序等待完整操作完成的时间设定了硬性限制。

```
S3Client s3Client = S3Client.builder()
    .overrideConfiguration(ClientOverrideConfiguration.builder()
        .apiCallTimeout(Duration.ofMinutes(2))  // Total time for entire operation, such as when you call the getObject method.
        .build())
    .build();
```

主要特性：
+ 包括所有重试尝试。
+ 包括两次重试之间等待所花费的时间。
+ 提供绝对的最长等待时间。
+ 防止操作无限期运行。

### API 调用尝试超时
<a name="api-call-attempt-timeout"></a>

API 调用尝试超时设置单次 API 操作尝试的最长时间。如果超过此超时时间，SDK 会重试该操作（如果配置了重试），而不是使整个调用失败。

```
S3Client s3Client = S3Client.builder()
    .overrideConfiguration(ClientOverrideConfiguration.builder()
        .apiCallAttemptTimeout(Duration.ofSeconds(30))  // Time for single attempt.
        .build())
    .build();
```

主要特性：
+ 仅适用于单个尝试。
+ 为慢速请求启用快速失败和重试。
+ 必须比 API 调用超时更短。
+ 有助于识别暂时性问题并从问题中恢复。

### 配置服务客户端超时
<a name="service-timeout-configuration"></a>

您可以为所有操作全局配置服务客户端超时，也可以按请求配置：

**全局配置：**

```
S3Client s3Client = S3Client.builder()
    .overrideConfiguration(b -> b
        .apiCallTimeout(Duration.ofSeconds(105L))
        .apiCallAttemptTimeout(Duration.ofSeconds(25L)))
    .build();
// When you use the s3Client for an API operation, the SDK uses the configured timeout values.
```

**按请求配置：**

```
S3Client basicS3Client = S3Client.create();

// The following configuration uses the same settings as shown before, but these settings
// apply to only the `putObject` call. When you use `basicS3Client` in another API call without
// supplying the override configuration, there are no API timeout limits. No timeout limits is the default for the SDK.
AwsRequestOverrideConfiguration overrideConfiguration = AwsRequestOverrideConfiguration.builder()
    .apiCallTimeout(Duration.ofSeconds(105L))
    .apiCallAttemptTimeout(Duration.ofSeconds(25L))
    .build();

basicS3Client.putObject(b -> b
        .bucket("amzn-s3-demo-bucket")
        .key("example-key")
        .overrideConfiguration(overrideConfiguration),
    RequestBody.fromString("test"));
```

### API 超时的最佳实践
<a name="timeout-best-practice"></a>

适用于 Java 的 SDK 2.x 默认不设置 API 调用超时或单个 API 调用尝试超时。为单个尝试和整个请求设置超时。当暂时性问题导致请求尝试要花费更长时间或发生致命的网络问题时，这样可以有助于您的应用程序快速失效。

## HTTP 客户端超时
<a name="http-client-timeouts"></a>

HTTP 客户端超时在网络级别运行，用于控制 HTTP 通信的各个方面。这些超时根据您使用的 HTTP 客户端实现而有所不同。

### 连接超时
<a name="connection-timeout"></a>

连接超时用于控制与 AWS 服务 端点建立新连接时需要等待多长时间。

```
// Available with all HTTP clients.
ApacheHttpClient.builder()
    .connectionTimeout(Duration.ofSeconds(5L))
    .build();
```

目的：
+ 防止因网络连接问题而挂起。
+ 当服务无法访问时，会快速失效。
+ 对于需要响应式错误处理的应用程序来说是必不可少的。

### 套接字超时（Apache 和 URLConnection 客户端）
<a name="socket-timeout"></a>

套接字超时控制在已建立的连接上等待数据的时间。

```
ApacheHttpClient.builder()
    .socketTimeout(Duration.ofSeconds(30L))  // Time to wait for response data.
    .build();
```

### 读取和写入超时（Netty 客户端）
<a name="read-write-timeouts"></a>

Netty 客户端为读取和写入操作提供单独的超时：

```
NettyNioAsyncHttpClient.builder()
    .readTimeout(Duration.ofSeconds(30L))   // Reading response data.
    .writeTimeout(Duration.ofSeconds(30L))  // Writing request data.
    .build();
```

### TLS 协商超时（Netty 客户端）
<a name="tls-negotiation-timeout"></a>

控制 TLS/SSL 握手所允许的时间：

```
NettyNioAsyncHttpClient.builder()
    .tlsNegotiationTimeout(Duration.ofSeconds(3L))
    .build();
```

### 连接池超时
<a name="connection-pool-timeouts"></a>

某些 HTTP 客户端会为连接池操作提供超时：

```
ApacheHttpClient.builder()
    .connectionAcquisitionTimeout(Duration.ofSeconds(10L))  // Wait for pool connection.
    .connectionTimeToLive(Duration.ofMinutes(5L))           // Maximum connection age.
    .connectionMaxIdleTime(Duration.ofSeconds(60L))         // Maximum idle time.
    .build()
```

[配置 HTTP 客户端](http-configuration.md)包含有关AWS SDK for Java 2.x 中的 HTTP 客户端的更多信息

## 超时交互和层次结构
<a name="timeout-interactions"></a>

了解不同的超时如何交互，这对于正确配置至关重要：

### 超时层次结构
<a name="timeout-hierarchy"></a>

```
API Call Timeout (2 minutes)
├── Retry Attempt 1
│   ├── API Call Attempt Timeout (45 seconds)
│   └── HTTP Client Timeouts
│       ├── Connection Timeout (5 seconds)
│       ├── TLS Negotiation Timeout (3 seconds)
│       └── Read/Write Timeout (30 seconds)
├── Retry Attempt 2
│   └── [Same structure as Attempt 1]
└── Retry Attempt 3
    └── [Same structure as Attempt 1]
```

### 配置规则
<a name="configuration-rules"></a>

API 调用超时 ≥ API 调用尝试超时  

```
// Correct configuration.
.apiCallTimeout(Duration.ofMinutes(2))         // 120 seconds.
.apiCallAttemptTimeout(Duration.ofSeconds(30)) // 30 seconds.
```

API 调用尝试超时 ≥ HTTP 客户端超时  

```
// HTTP client timeouts must be less than attempt timeout.
.apiCallAttemptTimeout(Duration.ofSeconds(30L))   // 30 seconds.
// HTTP client configuration.
.connectionTimeout(Duration.ofSeconds(5L))        // 5 seconds.
.readTimeout(Duration.ofSeconds(25L))             // 25 seconds (< 30).
```

考虑多次尝试  

```
// If you have 3 retry attempts, each taking up to 30 seconds
// API call timeout must be at least 90 seconds plus overhead.
.apiCallTimeout(Duration.ofMinutes(2L))          // 120 seconds.
.apiCallAttemptTimeout(Duration.ofSeconds(30))   // 30 seconds per attempt.
```

## 使用智能配置默认值
<a name="smart-configuration-defaults"></a>

SDK 提供智能默认值，可自动配置适当的超时值：

```
// Enable smart defaults.
S3Client client = S3Client.builder()
    .defaultsMode(DefaultsMode.AUTO)  // Automatically choose appropriate defaults.
    .build();

// Available modes:
// - STANDARD: Balanced defaults
// - IN_REGION: Optimized for same-region calls
// - CROSS_REGION: Optimized for cross-region calls  
// - MOBILE: Optimized for mobile applications
// - AUTO: Automatically detect and choose appropriate mode
// - LEGACY: Provides settings that were used before smart defaults existed.
```

智能默认值会自动配置：
+ 连接超时值。
+ TLS 协商超时值。
+ 其他客户端设置。

## 摘要
<a name="timeout-summary"></a>

在AWS SDK for Java 2.x 中配置有效的超时需要了解服务客户端超时和 HTTP 客户端超时之间的交互：

1. **服务客户端超时**控制高级别 API 行为。

1. **HTTP 客户端超时**控制低级别网络行为。

1. **适当的层次结构**可确保超时有效协同工作。

1. **智能默认值**为大多数应用程序提供了良好的起点。

为您的使用案例适当配置超时，以便构建既能抵御网络问题又能快速响应用户的应用程序。