本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
Amazon EC2 API 中的分页
我们建议在调用可能返回大量结果的描述类操作(例如 DescribeInstances)时使用分页。使用分页可以限制每次描述调用返回的项目数量,并控制调用返回所需的时间。如果您拥有大量资源,未分页的调用可能会被限制速率,甚至可能超时。因此,相比未分页调用,分页调用通常更稳定成功,从而带来更好的整体延迟表现。
有关更多信息,请参阅《Amazon EC2 API 参考》中的分页。
最佳实践
在可能的情况下,在描述调用中指定资源 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; }
如果需要重试分页调用,请使用带抖动的指数退避算法。
常见问题
以下是一些无意间发起未分页调用的代码示例。
例 问题示例:传递一个空的资源 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(); }
例 问题示例:未设置 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; }