

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

# Amazon EC2 API 中的分页
<a name="ec2-api-pagination"></a>

我们建议在调用可能返回大量结果的描述类操作（例如 `DescribeInstances`）时使用分页。使用分页可以限制每次描述调用返回的项目数量，并控制调用返回所需的时间。如果您拥有大量资源，未分页的调用可能会被限制速率，甚至可能超时。因此，相比未分页调用，分页调用通常更稳定成功，从而带来更好的整体延迟表现。

有关更多信息，请参阅《Amazon EC2 API 参考**》中的[分页](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Query-Requests.html#api-pagination)。

## 最佳实践
<a name="pagination-best-practices"></a>

在可能的情况下，在描述调用中指定资源 ID 列表。这是描述大量资源的最快捷方式。请注意，单次调用中不应指定超过 1000 个 ID。示例如下：

```
private List<Reservation> describeMyInstances(List<String> ids){
    if (ids == null || ids.isEmpty()) {
        return ImmutableList.of();
    }
        
    final DescribeInstancesRequest request = new DescribeInstancesRequest()
            .withInstanceIds(ids);

    return ec2.describeInstances(request).getReservations();
}
```

如果您无法在描述调用中指定资源 ID，我们强烈建议使用分页。示例如下：

```
private List<Reservation> describeMyInstances(final Collection<Filter> filters){
    final DescribeInstancesRequest request = new DescribeInstancesRequest()
            .withFilters(filters)
            .withMaxResults(1000);

    List<Reservation> reservations = new ArrayList<>();
    String nextToken = null;
    do {
        request.setNextToken(nextToken);
        final DescribeInstancesResult response = ec2.describeInstances(request);
        reservations.addAll(response.getReservations());
        nextToken = response.getNextToken();
    } while (nextToken != null);

    return reservations;
}
```

如果需要重试分页调用，请使用[带抖动的指数退避算法](ec2-api-throttling.md#api-backoff)。

## 常见问题
<a name="pagination-common-issues"></a>

以下是一些无意间发起未分页调用的代码示例。

**Example 问题示例：传递一个空的资源 ID 列表**  
下面的代码使用了 ID 列表。然而，如果该列表为空，最终会导致发起未分页的调用。  

```
private List<Reservation> describeMyInstances(List<String> ids){
    final DescribeInstancesRequest request = new DescribeInstancesRequest()
            .withInstanceIds(ids);

    return ec2.describeInstances(request).getReservations();
}
```
要修正此问题，请确保在执行描述调用之前列表不为空。  

```
private List<Reservation> describeMyInstances(List<String> ids){
    if (ids == null || ids.isEmpty()) {
        return ImmutableList.of();
        // OR
        return Lists.newArrayList();
        // OR
        return new ArrayList<>();
    }
        
    final DescribeInstancesRequest request = new DescribeInstancesRequest()
            .withInstanceIds(ids);

    return ec2.describeInstances(request).getReservations();
}
```

**Example 问题示例：未设置 MaxResults**  
以下代码虽然检查并使用了 `nextToken`，但并未设置 `MaxResults`。  

```
private List<Reservation> describeMyInstances(final Collection<Filter> filters){
    final DescribeInstancesRequest request = new DescribeInstancesRequest()
            .withFilters(filters);

    List<Reservation> reservations = new ArrayList<>();
    String nextToken = null;
    do {
        request.setNextToken(nextToken);
        final DescribeInstancesResult response = ec2.describeInstances(request);
        reservations.addAll(response.getReservations());
        nextToken = response.getNextToken();
    } while (nextToken != null);

    return reservations;
}
```
要解决此问题，请按以下方式添加 `withMaxResults`。  

```
private List<Reservation> describeMyInstances(final Collection<Filter> filters){
    final DescribeInstancesRequest request = new DescribeInstancesRequest()
            .withFilters(filters)
            .withMaxResults(1000);

    List<Reservation> reservations = new ArrayList<>();
    String nextToken = null;
    do {
        request.setNextToken(nextToken);
        final DescribeInstancesResult response = ec2.describeInstances(request);
        reservations.addAll(response.getReservations());
        nextToken = response.getNextToken();
    } while (nextToken != null);

    return reservations;
}
```