

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 以程式設計方式存取 Amazon EC2
<a name="ec2-api-intro"></a>

您可以使用 AWS 管理主控台 或程式設計界面來建立和管理 Amazon EC2 資源。如需有關使用 Amazon EC2 主控台的資訊，請參閱《[Amazon EC2 使用者指南](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/)》。

**運作方式**
+ [Amazon EC2 端點](ec2-endpoints.md)
+ [最終一致性](eventual-consistency.md)
+ [冪等性](ec2-api-idempotency.md)
+ [請求限流](ec2-api-throttling.md)
+ [分頁](ec2-api-pagination.md)

**程式設計界面**
+ [AWS Command Line Interface (AWS CLI)](ec2-aws-cli.md)
+ [AWS CloudFormation](ec2-cloudformation.md)
+ [AWS SDKs](sdk-general-information-section.md)
+ [低階 API](ec2-low-level-api.md)

**開始使用**
+ [程式碼範例](service_code_examples.md)
+ [Console-to-Code](console-to-code.md)

**監控**
+ [AWS CloudTrail](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitor-with-cloudtrail.html)
+ [監控請求](monitor.md)

# Amazon EC2 服務端點
<a name="ec2-endpoints"></a>

端點是做為 AWS Web 服務進入點的 URL。Amazon EC2 支援下列端點類型：
+ [IPv4 端點](#ipv4)
+ [雙堆疊端點](#ipv6) （同時支援 IPv4 和 IPv6)
+ [FIPS 端點](https://docs.aws.amazon.com/general/latest/gr/rande.html#FIPS-endpoints)

當您提出請求時，您可以指定要使用的端點。如果您沒有指定端點，則預設使用 IPv4 端點。若要使用不同的端點類型，您必須在請求中將其指定。如需如何執行此作業的範例，請參閱 [指定端點](#examples)。如需可用端點的資料表，請參閱 [依區域的服務端點](#service-endpoints)。

## IPv4 端點
<a name="ipv4"></a>

IPv4 端點僅支援 IPv4 流量。IPv4 端點適用於所有區域。

如果您指定一般端點、`ec2.amazonaws.com`，我們會使用 `us-east-1` 的端點。若要使用不同的區域，請指定其相關聯的端點。例如，如果您指定 `ec2.us-east-2.amazonaws.com` 做為端點，我們會將您的請求導向 `us-east-2` 端點。

IPv4 端點名稱使用以下命名慣例：
+ `service.region.amazonaws.com`

例如，`eu-west-1` 區域的 IPv4 端點名稱是 `ec2.eu-west-1.amazonaws.com`。

## 雙堆疊 (IPv4 和 IPv6) 端點
<a name="ipv6"></a>

雙堆疊端點同時支援 IPv4 和 IPv6 流量。當您請求雙堆疊端點時，端點 URL 會解析為 IPv6 或 IPv4 地址，具體視您的網路和用戶端使用的通訊協定而異。

Amazon EC2 僅支援區域雙堆疊端點，這表示您必須將區域指定為端點名稱的一部分。雙堆疊端點名稱使用以下命名慣例：
+ `ec2.region.api.aws`

例如，`eu-west-1` 區域的雙堆疊端點名稱是 `ec2.eu-west-1.api.aws`。

## 依區域的服務端點
<a name="service-endpoints"></a>

以下是 Amazon EC2 的服務端點。如需區域的詳細資訊，請參閱《*Amazon EC2 使用者指南*》中的[區域和可用區域](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html)。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/ec2/latest/devguide/ec2-endpoints.html)

## 指定端點
<a name="examples"></a>

本節提供一些在提出請求時如何指定端點的範例。

------
#### [ AWS CLI ]

下列範例示範如何使用 指定 `us-east-2`區域的端點 AWS CLI。
+ **雙堆疊**

  ```
  aws ec2 describe-regions --region us-east-2 --endpoint-url https://ec2.us-east-2.api.aws
  ```
+ **IPv4**

  ```
  aws ec2 describe-regions --region us-east-2 --endpoint-url https://ec2.us-east-2.amazonaws.com
  ```

------
#### [ AWS SDK for Java 2.x ]

下列範例示範如何使用 指定 `us-east-2`區域的端點 AWS SDK for Java 2.x。
+ **雙堆疊**

  ```
  Ec2Client client = Ec2Client.builder()
      .region(Region.US_EAST_2)
      .endpointOverride(URI.create("https://ec2.us-east-2.api.aws"))
      .build();
  ```
+ **IPv4**

  ```
  Ec2Client client = Ec2Client.builder()
      .region(Region.US_EAST_2)
      .endpointOverride(URI.create("https://ec2.us-east-2.amazonaws.com"))
      .build();
  ```

------
#### [ 適用於 Java 的 AWS SDK 1.x ]

下列範例示範如何使用 適用於 Java 的 AWS SDK 1.x 指定`eu-west-1`區域的端點。
+ **雙堆疊**

  ```
  AmazonEC2 s3 = AmazonEC2ClientBuilder.standard()
       .withEndpointConfiguration(new EndpointConfiguration(
            "https://ec2.eu-west-1.api.aws",
            "eu-west-1"))
       .build();
  ```
+ **IPv4**

  ```
  AmazonEC2 s3 = AmazonEC2ClientBuilder.standard()
       .withEndpointConfiguration(new EndpointConfiguration(
            "https://ec2.eu-west-1.amazonaws.com",
            "eu-west-1"))
       .build();
  ```

------
#### [ AWS SDK for Go ]

下列範例示範如何使用 指定 `us-east-1`區域的端點 適用於 Go 的 AWS SDK。
+ **雙堆疊**

  ```
  sess := session.Must(session.NewSession())
  svc := ec2.New(sess, &aws.Config{
      Region: aws.String(endpoints.UsEast1RegionID),
      Endpoint: aws.String("https://ec2.us-east-1.api.aws")
  })
  ```
+ **IPv4**

  ```
  sess := session.Must(session.NewSession())
  svc := ec2.New(sess, &aws.Config{
      Region: aws.String(endpoints.UsEast1RegionID),
      Endpoint: aws.String("https://ec2.us-east-1.amazonaws.com")
  })
  ```

------

# Amazon EC2 API 中的最終一致性
<a name="eventual-consistency"></a>

由於支援 API 之系統的分散式性質，Amazon EC2 API 遵循最終一致性模型。這表示您執行會影響 Amazon EC2 資源的 API 命令的結果，可能不會立即顯示給您執行的所有後續命令。在執行緊接先前 API 命令的 API 命令時，應謹記這一點。

最終一致性可能會影響您管理 資源的方式。例如，如果您執行命令來建立資源，最終其他命令將可見該資源。這表示，如果您執行命令來修改或描述您剛建立的資源，其 ID 可能尚未在整個系統中傳播，而且您會收到回應資源不存在的錯誤。

若要管理最終一致性，您可以執行下列操作：
+ 在執行命令來修改資源之前，請先確認資源的狀態。使用指數退避演算法執行適當的 `Describe` 命令，以確保您有足夠的時間讓上一個命令透過系統傳播。若要這樣做，請重複執行 `Describe`命令，從幾秒鐘的等待時間開始，然後逐漸增加到幾分鐘的等待時間。
+ 在後續命令之間增加等待時間，即使 `Describe` 命令傳回準確的回應。從幾秒鐘的等待時間開始套用指數退避演算法，並逐漸增加到幾分鐘的等待時間。

**最終一致性錯誤範例**  
以下是由於最終一致性而可能遇到的錯誤代碼範例。
+ `InvalidInstanceID.NotFound`

  如果您成功執行 `RunInstances`命令，然後立即使用 回應中提供的執行個體 ID 執行另一個命令`RunInstances`，則可能會傳回`InvalidInstanceID.NotFound`錯誤。這並不表示執行個體不存在。

  某些可能受影響的特定命令包括：
  + `DescribeInstances`：若要確認執行個體的實際狀態，請使用指數退避演算法執行此命令。
  + `TerminateInstances`：若要確認執行個體的狀態，請先使用指數退避演算法執行 `DescribeInstances`命令。
**重要**  
如果您在執行 後收到`InvalidInstanceID.NotFound`錯誤`TerminateInstances`，這並不表示執行個體已終止或將終止。您的執行個體可能仍在執行中。這就是為什麼首先使用 確認執行個體的狀態很重要`DescribeInstances`。
+ `InvalidGroup.NotFound`

  如果您成功執行 `CreateSecurityGroup`命令，然後立即使用 回應中提供的安全群組 ID 執行另一個命令`CreateSecurityGroup`，則可能會傳回`InvalidGroup.NotFound`錯誤。若要確認安全群組的狀態，請使用指數退避演算法執行 `DescribeSecurityGroups`命令。
+ `InstanceLimitExceeded`

  您已請求超過目前執行個體限制允許指定執行個體類型的執行個體數量。如果您快速啟動和終止執行個體，您可能會意外達到此限制，因為終止的執行個體在終止之後會計入執行個體限制一段時間。

# 確保 Amazon EC2 API 請求中的冪等性
<a name="ec2-api-idempotency"></a>

當您提出變動的 API 請求時，該請求一般會在操作的非同步工作流程完成之前傳回結果。即使請求已傳回結果，操作還是可能會在完成前就逾時或發生其他伺服器問題。這可能會讓您難以判斷請求是否成功，而且可能導致系統多次重試以確保操作能成功完成。但是，如果原始請求和後續的重試有成功，則操作會完成多次。這表示您可以建立比預期更多的資源。

等冪性**可確保 API 請求不會完成超過一次。使用等冪請求時，如果原始請求成功完成，則任何後續的重試都會成功完成，而不必執行任何進一步的動作。不過，結果可能包含更新的資訊，例如目前的建立狀態。

**Topics**
+ [Amazon EC2 中的冪等性](#client-tokens)
+ [RunInstances 等冪性](#run-instances-idempotency)
+ [範例](#Run_Instance_Idempotency_CLI)
+ [等冪請求的重試建議](#recommended-actions)

## Amazon EC2 中的冪等性
<a name="client-tokens"></a>

根據預設，下列 API 動作是等冪的，不需要額外的組態。根據預設，對應的 AWS CLI 命令也支援冪等性。

**依預設，無效**
+ AssociateAddress
+ CreateVpnConnection
+ DisassociateAddress
+ ReplaceNetworkAclAssociation
+ TerminateInstances

下列 API 動作可選擇性地使用*用戶端字符*支援冪等性。對應的 AWS CLI 命令也支援使用用戶端字符的冪等性。用戶端字符是唯一的區分大小寫字串，最多 64 個 ASCII 字元。若要使用其中一個動作提出等冪 API 請求，請在請求中指定用戶端字符。您不應該將相同的用戶端字符用於其他 API 請求。如果您重試使用相同用戶端字符和相同參數成功完成的請求，則重試會成功，而無需執行任何進一步的動作。如果您使用相同的用戶端字符重試成功的請求，但一或多個參數不同，但區域或可用區域除外，則重試會失敗並顯示`IdempotentParameterMismatch`錯誤。

**使用用戶端字符的等冪**
+ AllocateHosts
+ AllocateIpamPoolCidr
+ AssociateClientVpnTargetNetwork
+ AssociateIpamResourceDiscovery
+ AttachVerifiedAccessTrustProvider
+ AuthorizeClientVpnIngress
+ CopyFpgaImage
+ CopyImage
+ CreateCapacityReservation
+ CreateCapacityReservationFleet
+ CreateClientVpnEndpoint
+ CreateClientVpnRoute
+ CreateEgressOnlyInternetGateway
+ CreateFleet
+ CreateFlowLogs
+ CreateFpgaImage
+ CreateInstanceConnectEndpoint
+ CreateIpam
+ CreateIpamPool
+ CreateIpamResourceDiscovery
+ CreateIpamScope
+ CreateLaunchTemplate
+ CreateLaunchTemplateVersion
+ CreateManagedPrefixList
+ CreateNatGateway
+ CreateNetworkAcl
+ CreateNetworkInsightsAccessScope
+ CreateNetworkInsightsPath
+ CreateNetworkInterface
+ CreateReplaceRootVolumeTask
+ CreateReservedInstancesListing
+ CreateRouteTable
+ CreateTrafficMirrorFilter
+ CreateTrafficMirrorFilterRule
+ CreateTrafficMirrorSession
+ CreateTrafficMirrorTarget
+ CreateVerifiedAccessEndpoint
+ CreateVerifiedAccessGroup
+ CreateVerifiedAccessInstance
+ CreateVerifiedAccessTrustProvider
+ CreateVolume
+ CreateVpcEndpoint
+ CreateVpcEndpointConnectionNotification
+ CreateVpcEndpointServiceConfiguration
+ DeleteVerifiedAccessEndpoint
+ DeleteVerifiedAccessGroup
+ DeleteVerifiedAccessInstance
+ DeleteVerifiedAccessTrustProvider
+ DetachVerifiedAccessTrustProvider
+ ExportImage
+ ImportImage
+ ImportSnapshot
+ ModifyInstanceCreditSpecification
+ ModifyLaunchTemplate
+ ModifyReservedInstances
+ ModifyVerifiedAccessEndpoint
+ ModifyVerifiedAccessEndpointPolicy
+ ModifyVerifiedAccessGroup
+ ModifyVerifiedAccessGroupPolicy
+ ModifyVerifiedAccessInstance
+ ModifyVerifiedAccessInstanceLoggingConfiguration
+ ModifyVerifiedAccessTrustProvider
+ ProvisionIpamPoolCidr
+ PurchaseHostReservation
+ RequestSpotFleet
+ RequestSpotInstances
+ RunInstances
+ StartNetworkInsightsAccessScopeAnalysis
+ StartNetworkInsightsAnalysis

**冪等性類型**
+ 區域 – 請求在每個區域中都是等冪的。不過，您可以在不同的區域中使用相同的請求，包括相同的用戶端字符。
+ 區域 – 請求在區域中的每個可用區域中都是等冪的。例如，如果您在相同區域中的 對 的兩個呼叫**AllocateHosts**中指定相同的用戶端字符，則如果呼叫為 **AvailabilityZone** 參數指定不同的值，則呼叫會成功。

## RunInstances 等冪性
<a name="run-instances-idempotency"></a>

[RunInstances](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_RunInstances.html) API 動作同時使用區域和區域冪等性。

使用的冪等性類型取決於您在 RunInstances API 請求中指定可用區域的方式。在下列情況下，請求使用**區域冪等性**：
+ 如果您使用**置放**資料類型中的 **AvailabilityZone** 參數明確指定可用區域
+ 如果您使用 **SubnetId** 參數隱含指定可用區域

如果您未明確或隱含指定可用區域，請求會使用**區域冪等性**。

### 區域冪等性
<a name="zonal-idempotency"></a>

區域冪等性可確保區域中每個可用區域中的 RunInstances API 請求都冪等。這可確保具有相同用戶端字符的請求只能在區域中的每個可用區域內完成一次。不過，相同的用戶端字符可用於在 區域中的其他可用區域中啟動執行個體。

例如，如果您傳送等冪請求來啟動`us-east-1a`可用區域中的執行個體，然後在`us-east-1b`可用區域中的請求中使用相同的用戶端字符，我們會在每個可用區域中啟動執行個體。如果一或多個參數不同，則在這些可用區域中具有相同用戶端字符的後續重試會成功傳回，而不會執行任何進一步動作或失敗並發生錯誤`IdempotentParameterMismatch`。

### 區域冪等性
<a name="regional-idempotency"></a>

區域冪等性可確保區域中的 RunInstances API 請求具有冪等性。這可確保具有相同用戶端字符的請求只能在區域內完成一次。不過，具有相同用戶端字符的完全相同請求可用來啟動不同區域中的執行個體。

例如，如果您傳送等冪性請求以在 `us-east-1`區域中啟動執行個體，然後在 `eu-west-1`區域中的請求中使用相同的用戶端字符，我們會在每個區域中啟動執行個體。如果一或多個參數不同，則在這些區域中使用相同用戶端字符的後續重試會成功傳回，而不會執行任何進一步的動作，或失敗並發生錯誤`IdempotentParameterMismatch`。

**提示**  
如果請求區域中的其中一個可用區域無法使用，則使用區域冪等性的 RunInstances 請求可能會失敗。若要利用 AWS 基礎設施提供的可用區域功能，建議您在啟動執行個體時使用區域冪等性。使用區域冪等性並將可用可用區域設為目標的 RunInstances 請求成功，即使請求區域中的其他可用區域無法使用。

## 範例
<a name="Run_Instance_Idempotency_CLI"></a>

### AWS CLI 命令範例
<a name="cli-example"></a>

若要讓 AWS CLI 命令成為等冪，請新增 `--client-token`選項。

**範例 1：冪等性**  
下列 [allocate-hosts](https://docs.aws.amazon.com/cli/latest/reference/ec2/allocate-hosts.html) 命令使用冪等性，因為它包含用戶端字符。

```
aws ec2 allocate-hosts  --instance-type m5.large  --availability-zone eu-west-1a  --auto-placement on  --quantity 1 --client-token 550e8400-e29b-41d4-a716-446655440000
```

**範例 2：run-instances 區域冪等性**  
下列 [run-instances](https://docs.aws.amazon.com/cli/latest/reference/ec2/run-instances.html) 命令使用區域冪等性，因為它包含用戶端字符，但不明確或隱含指定可用區域。

```
aws ec2 run-instances --image-id ami-b232d0db --count 1 --key-name my-key-pair --client-token 550e8400-e29b-41d4-a716-446655440000
```

**範例 3：run-instances 區域冪等性**  
下列 [run-instances](https://docs.aws.amazon.com/cli/latest/reference/ec2/run-instances.html) 命令使用區域冪等性，因為它包含用戶端字符和明確指定的可用區域。

```
aws ec2 run-instances  --placement "AvailabilityZone=us-east-1a" --image-id ami-b232d0db --count 1 --key-name my-key-pair --client-token 550e8400-e29b-41d4-a716-446655440000
```

### API 請求範例
<a name="api-example"></a>

若要讓 API 請求具有等冪性，請新增 `ClientToken` 參數。

**範例 1：冪等性**  
下列 [AllocateHosts](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_AllocateHosts.html) API 請求使用冪等性，因為它包含用戶端字符。

```
https://ec2.amazonaws.com/?Action=AllocateHosts
&AvailabilityZone=us-east-1b
&InstanceType=m5.large
&Quantity=1
&AutoPlacement=off
&ClientToken=550e8400-e29b-41d4-a716-446655440000
&AUTHPARAMS
```

**範例 2：RunInstances 區域冪等性**  
下列 [RunInstances](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_RunInstances.html) API 請求使用區域冪等性，因為它包含用戶端字符，但不明確或隱含指定可用區域。

```
https://ec2.amazonaws.com/?Action=RunInstances
&ImageId=ami-3ac33653
&MaxCount=1
&MinCount=1
&KeyName=my-key-pair
&ClientToken=550e8400-e29b-41d4-a716-446655440000
&AUTHPARAMS
```

**範例 3：RunInstances 區域冪等性**  
下列 [RunInstances](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_RunInstances.html) API 請求使用區域等冪，因為它包含用戶端字符和明確指定的可用區域。

```
https://ec2.amazonaws.com/?Action=RunInstances
&Placement.AvailabilityZone=us-east-1d
&ImageId=ami-3ac33653
&MaxCount=1
&MinCount=1
&KeyName=my-key-pair
&ClientToken=550e8400-e29b-41d4-a716-446655440000
&AUTHPARAMS
```

## 等冪請求的重試建議
<a name="recommended-actions"></a>

下表顯示您可能會從等冪 API 請求得到的一些常見回應，並提供重試建議。


| 回應 | 建議 | 說明 | 
| --- | --- | --- | 
|  200 (OK)  |  請勿重試  |  原始請求已成功完成。任何後續的重試都會成功傳回。  | 
|  400 系列回應代碼 ([用戶端錯誤](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/errors-overview.html#CommonErrors))  |  請勿重試  |  請求有下列方面的問題： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/ec2/latest/devguide/ec2-api-idempotency.html) 如果請求涉及處於變更狀態過程的資源，則重試請求有可能會成功。  | 
|  500 系列回應代碼 ([伺服器錯誤](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/errors-overview.html#api-error-codes-table-server))  |  重試  |  錯誤是由 AWS 伺服器端問題造成，通常是暫時性的。請使用適當的退避策略來重複請求。  | 

# Amazon EC2 API 的請求限流
<a name="ec2-api-throttling"></a>

Amazon EC2 會根據區域調節每個 AWS 帳戶的 EC2 API 請求。我們這樣做是為了協助服務的效能，並確保所有 Amazon EC2 客戶的公平使用。調節可確保對 Amazon EC2 API 的請求不超過允許的 API 請求限制上限。API 請求受請求限制的約束，無論其來源是：
+ 第三方應用程式
+ 命令列工具
+ Amazon EC2 主控台

如果您超過 API 限流限制，您會收到`RequestLimitExceeded`錯誤碼。

**Topics**
+ [如何套用限流](#throttling-how)
+ [請求字符限制](#throttling-limits-rate-based)
+ [資源字符限制](#throttling-limits-cost-based)
+ [監控 API 限流](#throttling-monitor)
+ [重試和指數退避](#api-backoff)
+ [請求 提高限制](#throttling-increase)

## 如何套用限流
<a name="throttling-how"></a>

Amazon EC2 使用[字符儲存貯體演算法](https://en.wikipedia.org/wiki/Token_bucket)來實作 API 限流。透過此演算法，您的帳戶會有一個儲存*貯*體，其中包含特定數量*的字符*。儲存貯體中的字符數目代表您在任何指定秒的限流限制。

Amazon EC2 實作兩種類型的 API 限流：

**Topics**
+ [請求率限制](#throttling-rate-based)
+ [資源速率限制](#throttling-cost-based)

### 請求率限制
<a name="throttling-rate-based"></a>

使用請求速率限制時，每個 API 都會個別評估，而且您根據每個 API 提出的請求數量受到限流。您提出的每個請求都會從 API 的儲存貯體中移除一個字符。例如，`DescribeHosts`*非變動 * API 動作的字符儲存貯體大小為 100 個字符。一秒內最多可以提出 100 個`DescribeHosts`請求。如果您在一秒內超過 100 個請求，則會對該 API 進行調節，而且該秒內剩餘的請求會失敗，不過，對其他 API 的請求不會受到影響。

儲存貯體會自動以設定的速率重新填充。如果儲存貯體低於容量上限，則每秒會新增一組字符數量，直到達到容量上限為止。如果補充字符送達時儲存貯體已滿，則會捨棄它們。儲存貯體不能保留超過其字符數量上限。例如，`DescribeHosts`*非變動* API 動作的 儲存貯體大小為 100 個字符，而重新填充速率為每秒 20 個字符。如果您在一秒內提出 100 個`DescribeHosts`請求，儲存貯體會減少為零 (0) 個字符。然後，儲存貯體每秒會重新填充 20 個字符，直到達到其 100 個字符的最大容量為止。這表示如果在此期間沒有提出任何請求，空儲存貯體會在 5 秒後達到其最大容量。

您不需要等待儲存貯體完全填滿，即可提出 API 請求。您可以使用新增至儲存貯體的重新填充字符。如果您立即使用重新填充字符，則儲存貯體不會達到其容量上限。例如，`DescribeHosts`*非變動* API 動作的 儲存貯體大小為 100 個字符，而重新填充速率為每秒 20 個字符。如果您在一秒內提出 100 個 API 請求以耗盡儲存貯體，則可以使用新增至儲存貯體的重新填充字符，繼續每秒提出 20 個 API 請求。只有在每秒提出少於 20 個 API 請求時，儲存貯體才能重新填充至最大容量。

如需詳細資訊，請參閱[請求字符儲存貯體大小和重新填充率](#throttling-limits-rate-based)。

### 資源速率限制
<a name="throttling-cost-based"></a>

如下表所述`TerminateInstances`，某些 API 動作，例如 `RunInstances`和 ，除了請求速率限制之外，還會使用資源速率限制。這些 API 動作具有單獨的資源字符儲存貯體，根據受請求影響的資源數量耗盡。與請求字符儲存貯體一樣，資源字符儲存貯體具有可讓您爆量的儲存貯體上限，以及可讓您視需要維持穩定請求速率的重新填充速率。如果您超過 API 的特定儲存貯體限制，包括當儲存貯體尚未重新填充以支援下一個 API 請求時，即使您尚未達到總 API 節流限制，API 的動作也會受到限制。

例如， 的資源字符儲存貯體大小`RunInstances`為 1000 個字符，而重新填充速率為每秒兩個字符。因此，您可以使用任意數量的 API 請求，立即啟動 1000 個執行個體，例如 1 個請求的 1000 個執行個體，或 4 個請求的 250 個執行個體。在資源字符儲存貯體為空之後，您可以每秒啟動最多兩個執行個體，針對兩個執行個體使用一個請求，或針對一個執行個體使用兩個請求。

如需詳細資訊，請參閱[資源字符儲存貯體大小和重新填充率](#throttling-limits-cost-based)。

## 請求字符儲存貯體大小和重新填充率
<a name="throttling-limits-rate-based"></a>

為了限制請求率，API 動作會分組為下列類別：
+ **非變動動作** — 擷取資源相關資料的 API 動作。此類別通常包含所有 `Describe*`、`Search*`、 `List*`和 `Get*` API 動作，例如 `DescribeRouteTables`、 `SearchTransitGatewayRoutes`和 `GetIpamPoolCidrs`。這些 API 動作通常具有最高的 API 限流限制。
+ **未篩選和未分頁的非變動動作** — 非變動 API 動作的特定子集，在未指定[分頁](https://docs.aws.amazon.com/cli/latest/userguide/cli-usage-pagination.html)或[篩選條件](https://docs.aws.amazon.com//AWSEC2/latest/UserGuide/Using_Filtering.html#Filtering_Resources_CLI)的情況下，使用較小的字符儲存貯體中的字符。建議您使用分頁和篩選，以便從標準 （大型） 字符儲存貯體中扣除字符。
+ **變動動作** — 建立、修改或刪除資源的 API 動作。此類別通常包含未分類為*非變動動作的所有 API 動作*，例如 `AllocateHosts`、 `ModifyHosts`和 `CreateCapacityReservation`。這些動作的限流限制低於非變動 API 動作。
+ **資源密集型動作** — 將花費最多時間且耗用最多資源的 API 動作進行轉換。相較於*變動*動作，這些動作的限流限制甚至更低。它們與其他*變動動作*分開調節。
+ **主控台非變動動作** — 從 Amazon EC2 主控台請求的非變動 API 動作。這些 API 動作會與其他非變動的 API 動作分開調節。
+ **未分類的動作** — 這些是接收自己的字符儲存貯體大小和重新填充率的 API 動作，即使根據定義，它們適合其他類別之一。


| API 動作類別 | 動作 | 儲存貯體容量上限 | 儲存貯體重新填充率 | 
| --- | --- | --- | --- | 
| 非變動動作 |  不包含在另一個類別中的 `Search*`、、 `Describe*` `List*`和 `Get*` API 動作。  | 100 | 20 | 
| 未篩選和未分頁的非變動動作 |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/ec2/latest/devguide/ec2-api-throttling.html)  | 50 | 10 | 
| 變動動作 | 所有非*資源密集型動作**或未分類動作的變動 API 動作*。 | 50 | 5 | 
| 資源密集型動作 |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/ec2/latest/devguide/ec2-api-throttling.html)  | 50 | 5 | 
| 主控台非變動動作 |  `Describe*`、`Search*`、 `List*`和 `Get*` API 動作，由 Amazon EC2 主控台呼叫，但不包含在另一個類別中。  | 100 | 10 | <a name="uncategorized"></a>


| 未分類的動作 | 儲存貯體容量上限 | 儲存貯體重新填充率 | 
| --- | --- | --- | 
| AcceptVpcEndpointConnections | 10 | 1 | 
| AdvertiseByoipCidr | 1 | 0.1 | 
| AssignIpv6Addresses | 100 | 5 | 
| AssignPrivateIpAddresses | 100 | 5 | 
| AssignPrivateNatGatewayAddress | 10 | 1 | 
| AssociateCapacityReservationBillingOwner | 1 | 0.5 | 
| AssociateEnclaveCertificateIamRole | 10 | 1 | 
| AssociateIamInstanceProfile | 100 | 5 | 
| AssociateNatGatewayAddress | 10 | 1 | 
| AttachVerifiedAccessTrustProvider | 10 | 2 | 
| AuthorizeClientVpnIngress | 5 | 2 | 
| CancelDeclarativePoliciesReport | 1 | 1 | 
| CopyImage | 100 | 1 | 
| CreateClientVpnRoute | 5 | 2 | 
| CreateCoipCidr | 5 | 1 | 
| CreateCoipPool | 5 | 1 | 
| CreateDefaultSubnet | 1 | 1 | 
| CreateDefaultVpc | 1 | 1 | 
| CreateLaunchTemplateVersion | 100 | 5 | 
| CreateNatGateway | 10 | 1 | 
| CreateNetworkInterface | 100 | 5 | 
| CreateRestoreImageTask | 50 | 0.1 | 
| CreateSnapshot | 100 | 5 | 
| CreateSnapshots | 100 | 5 | 
| CreateSpotDatafeedSubscription | 50 | 3 | 
| CreateStoreImageTask | 50 | 0.1 | 
| CreateSubnetCidrReservation | 5 | 1 | 
| CreateTags | 100 | 10 | 
| CreateVerifiedAccessEndpoint | 20 | 4 | 
| CreateVerifiedAccessGroup | 10 | 2 | 
| CreateVerifiedAccessInstance | 10 | 2 | 
| CreateVerifiedAccessTrustProvider | 10 | 2 | 
| CreateVolume | 100 | 5 | 
| CreateVpcEndpoint | 4 | 0.3 | 
| CreateVpcEndpointServiceConfiguration | 10 | 1 | 
| DeleteClientVpnRoute | 5 | 2 | 
| DeleteCoipCidr | 5 | 1 | 
| DeleteCoipPool | 5 | 1 | 
| DeleteCoipPoolPermission | 5 | 1 | 
| DeleteNatGateway | 10 | 1 | 
| DeleteNetworkInterface | 100 | 5 | 
| DeleteSnapshot | 100 | 5 | 
| DeleteSpotDatafeedSubscription | 50 | 3 | 
| DeleteSubnetCidrReservation | 5 | 1 | 
| DeleteQueuedReservedInstances | 5 | 5 | 
| DeleteTags | 100 | 10 | 
| DeleteVerifiedAccessEndpoint | 20 | 4 | 
| DeleteVerifiedAccessGroup | 10 | 2 | 
| DeleteVerifiedAccessInstance | 10 | 2 | 
| DeleteVerifiedAccessTrustProvider | 10 | 2 | 
| DeleteVolume | 100 | 5 | 
| DeleteVpcEndpoints | 4 | 0.3 | 
| DeleteVpcEndpointServiceConfigurations | 10 | 1 | 
| DeprovisionByoipCidr | 1 | 0.1 | 
| DeregisterImage | 100 | 5 | 
| DescribeAggregateIdFormat | 10 | 10 | 
| DescribeByoipCidrs | 1 | 0.5 | 
| DescribeCapacityBlockExtensionOfferings | 10 | 0.15 | 
| DescribeCapacityBlockOfferings | 10 | 0.15 | 
| DescribeDeclarativePoliciesReports | 5 | 5 | 
| DescribeHostReservations | 5 | 2 | 
| DescribeHostReservationOfferings | 5 | 2 | 
| DescribeIdentityIdFormat | 10 | 10 | 
| DescribeIdFormat | 10 | 10 | 
| DescribeInstanceTopology | 1 | 1 | 
| DescribeMovingAddresses | 1 | 1 | 
| DescribePrincipalIdFormat | 10 | 10 | 
| DescribeReservedInstancesOfferings | 10 | 10 | 
| DescribeSecurityGroupReferences | 20 | 5 | 
| DescribeSpotDatafeedSubscription | 100 | 13 | 
| DescribeSpotFleetInstances | 100 | 5 | 
| DescribeSpotFleetRequestHistory | 100 | 5 | 
| DescribeSpotFleetRequests | 50 | 3 | 
| DescribeStaleSecurityGroups | 20 | 5 | 
| DescribeStoreImageTasks | 50 | 0.5 | 
| DescribeVerifiedAccessInstanceLoggingConfigurations | 10 | 2 | 
| DetachVerifiedAccessTrustProvider | 10 | 2 | 
| DisableFastLaunch | 5 | 2 | 
| DisableImageBlockPublicAccess | 1 | 0.1 | 
| DisableSnapshotBlockPublicAccess | 1 | 0.1 | 
| DisassociateCapacityReservationBillingOwner | 1 | 0.5 | 
| DisassociateEnclaveCertificateIamRole | 10 | 1 | 
| DisassociateIamInstanceProfile | 100 | 5 | 
| DisassociateNatGatewayAddress | 10 | 1 | 
| EnableFastLaunch | 5 | 2 | 
| EnableImageBlockPublicAccess | 1 | 0.1 | 
| EnableSnapshotBlockPublicAccess | 1 | 0.1 | 
| GetAssociatedEnclaveCertificateIamRoles | 10 | 1 | 
| GetDeclarativePoliciesReportSummary | 5 | 5 | 
| GetHostReservationPurchasePreview | 5 | 2 | 
| ModifyImageAttribute | 100 | 5 | 
| ModifyInstanceMetadataDefaults | 2 | 2 | 
| ModifyInstanceMetadataOptions | 100 | 5 | 
| ModifyLaunchTemplate | 100 | 5 | 
| ModifyNetworkInterfaceAttribute | 100 | 5 | 
| ModifySnapshotAttribute | 100 | 5 | 
| ModifyVerifiedAccessEndpoint | 20 | 4 | 
| ModifyVerifiedAccessEndpointPolicy | 20 | 4 | 
| ModifyVerifiedAccessGroup | 10 | 2 | 
| ModifyVerifiedAccessGroupPolicy | 20 | 4 | 
| ModifyVerifiedAccessInstance | 10 | 2 | 
| ModifyVerifiedAccessInstanceLoggingConfiguration | 10 | 2 | 
| ModifyVerifiedAccessTrustProvider | 10 | 2 | 
| ModifyVpcEndpoint | 4 | 0.3 | 
| ModifyVpcEndpointServiceConfiguration | 10 | 1 | 
| MoveAddressToVpc | 1 | 1 | 
| ProvisionByoipCidr | 1 | 0.1 | 
| PurchaseCapacityBlock | 10 | 0.15 | 
| PurchaseCapacityBlockExtension | 10 | 0.15 | 
| PurchaseHostReservation | 5 | 2 | 
| PurchaseReservedInstancesOffering | 5 | 5 | 
| RejectVpcEndpointConnections | 10 | 1 | 
| RestoreAddressToClassic | 1 | 1 | 
| RevokeClientVpnIngress | 5 | 2 | 
| RunInstances | 5 | 2 | 
| StartDeclarativePoliciesReport | 1 | 1 | 
| StartInstances | 5 | 2 | 
| TerminateInstances | 100 | 5 | 
| UnassignPrivateIpAddresses | 100 | 5 | 
| UnassignPrivateNatGatewayAddress | 10 | 1 | 
| WithdrawByoipCidr | 1 | 0.1 | 

## 資源字符儲存貯體大小和重新填充率
<a name="throttling-limits-cost-based"></a>

下表列出使用資源速率限制之 API 動作的資源字符儲存貯體大小和重新填充速率。


| API 動作 | 儲存貯體容量上限 | 儲存貯體重新填充率 | 
| --- | --- | --- | 
| RunInstances | 1000 | 2 | 
| TerminateInstances | 1000 | 20 | 
| StartInstances | 1000 | 2 | 
| StopInstances | 1000 | 20 | 

## 監控 API 限流
<a name="throttling-monitor"></a>

您可以使用 Amazon CloudWatch 來監控 Amazon EC2 API 請求，以及收集和追蹤 API 限流的相關指標。您也可以建立警示，在接近 API 限流限制時提醒您。如需詳細資訊，請參閱[使用 Amazon CloudWatch 監控 Amazon EC2 API 請求 Amazon CloudWatch使用 CloudWatch 監控 API 請求](monitor.md)。

## 重試和指數退避
<a name="api-backoff"></a>

您的應用程式可能需要重試 API 請求。例如：
+ 檢查資源狀態的更新
+ 列舉大量資源 （例如，所有磁碟區）
+ 在請求失敗並出現伺服器錯誤 (5xx) 或限流錯誤後重試請求

不過，對於用戶端錯誤 (4xx)，您必須先修改請求以修正問題，然後再嘗試請求。

**資源狀態變更**  
在您開始輪詢以檢查狀態更新之前，請給予可能完成的請求時間。例如，請等待幾分鐘，然後檢查您的執行個體是否處於作用中狀態。當您開始輪詢時，請在連續請求之間使用適當的休眠間隔，以降低 API 請求的速率。為了獲得最佳結果，請使用較長或可變的休眠間隔。

或者，您可以使用 Amazon EventBridge 來通知您一些資源的狀態。例如，您可以使用 **EC2 執行個體狀態變更通知**事件來通知您執行個體的狀態變更。如需詳細資訊，請參閱[使用 EventBridge 自動化 Amazon EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/automating_with_eventbridge.html)。

**重試**  
當您需要輪詢或重試 API 請求時，我們建議您使用指數退避演算法來計算 API 請求之間的休眠間隔。指數退避的背後概念是，對於連續錯誤回應，讓重試之間的等待時間漸進拉長。您應該實作延遲間隔上限，以及重試次數上限。您也可以使用抖動 （隨機延遲） 來防止連續的碰撞。如需詳細資訊，請參閱 [Timeouts, retries, and backoff with jitter](https://aws.amazon.com/builders-library/timeouts-retries-and-backoff-with-jitter/)。

每個 AWS SDK 都會實作自動重試邏輯。如需詳細資訊，請參閱 *AWS SDKs和工具參考指南*中的[重試行為](https://docs.aws.amazon.com/sdkref/latest/guide/feature-retry-behavior.html)。

## 請求 提高限制
<a name="throttling-increase"></a>

您可以請求提高 的 API 限流限制 AWS 帳戶。

**建議**
+ 在單一請求中，請求最多是現有限制的三倍。
+ 在增加儲存貯體最大容量之前，優先提高儲存貯體重新填充率。
+ 如果請求的儲存貯體重新填充率超過儲存貯體容量上限，請同時增加儲存貯體容量上限。
+ 提供需要增加的所有 API 動作。限制會套用至個別 API 動作，而非 API 動作類別。
+ 下列 API 動作有請求率和資源率限制：`RunInstances`、`StopInstances`、 `StartInstances`和 `TerminateInstances`。請務必指出應提高哪些限制

**請求存取此功能**

1. 開啟[AWS 支援 中心](https://console.aws.amazon.com/support/home#/)。

1. 選擇**建立案例**。

1. 選擇 **帳戶和帳單**。

1. 針對**服務**，選擇**一般資訊和入門**。

1. 針對**類別**，選擇**使用 AWS & 服務**。

1. 選擇 **Next step: Additional information** (下一步：其他資訊)。

1. 對於 **Subject (主旨)**，請輸入 **Request an increase in my Amazon EC2 API throttling limits**。

1. 針對**描述**，複製下列範本並提供必要資訊。

   ```
   Please increase the API throttling limits for my account. 
   Related page: https://docs.aws.amazon.com/ec2/latest/devguide/ec2-api-throttling.html
   Description: Brief notes about your use case. If available, include the IDs
       of a few Amazon EC2 requests that were throttled.
   Time window: One-hour window when peak throttling or usage occurred.
   region_1 request rate increases:
       action: new_bucket_maximum_capacity
       action: new_bucket_refill_rate
       action: new_bucket_maximum_capacity|new_bucket_refill_rate
   region_1 resource rate increases:
       action: new_bucket_maximum_capacity
       action: new_bucket_refill_rate
       action: new_bucket_maximum_capacity|new_bucket_refill_rate
   region_2 request rate increases:
       action: new_bucket_maximum_capacity
       action: new_bucket_refill_rate
       action: new_bucket_maximum_capacity|new_bucket_refill_rate
   region_2 resource rate increases:
       action: new_bucket_maximum_capacity
       action: new_bucket_refill_rate
       action: new_bucket_maximum_capacity|new_bucket_refill_rate
   ```

1. 選擇**下一步驟：立即解決或聯絡我們**。

1. 在**聯絡我們**索引標籤上，選擇您偏好的聯絡語言和聯絡方式。

1. 選擇**提交**。

# 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>

盡可能在描述呼叫中指定資源 IDs清單。這是描述大量資源最快的方式。請注意，您不應該在單一呼叫中指定超過 1，000 IDs。以下是範例。

```
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();
}
```

如果您無法在描述呼叫中指定資源 IDs，我們強烈建議您使用分頁。以下是範例。

```
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 範例問題：傳遞資源 IDs的空清單**  
下列程式碼使用 IDs清單。不過，如果清單是空的，則結果為未分頁的呼叫。  

```
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;
}
```