

# REL05-BP05 设置客户端超时
<a name="rel_mitigate_interaction_failure_client_timeouts"></a>

您应适当设置连接和请求的超时，对其进行系统性验证，不要依赖默认值，因为默认值并不了解具体的工作负载情况。

 **期望结果：**客户端超时应考虑当完成请求需要超长时间时，与等待请求相关的客户端、服务器和工作负载成本。由于无法知晓任何超时的确切原因，因此客户端必须运用对服务的了解，预测可能的原因和相应的超时时间。

 客户端会根据配置的值连接超时。遇到超时后，客户端会决定回退并重试，或者打开[断路器](https://martinfowler.com/bliki/CircuitBreaker.html)。这些模式可避免发出会加剧底层错误状况的请求。

 **常见反模式：**
+  不了解系统超时或默认超时。
+  不了解正常的请求完成时间。
+  不了解完成请求需要超长时间的可能原因，也不了解与等待完成这些请求相关的客户端、服务器或工作负载性能成本。
+  不了解网络受损只要在达到超时后就可能会导致请求失败，也不了解未采用更短的超时时间而招致的客户端和工作负载性能成本。
+  未针对连接和请求来测试超时场景。
+  将超时设置得过高，这会导致等待时间过长并增加资源使用。
+  将超时设置得过低，会导致人为故障。
+  忽略处理远程调用超时错误的模式，例如断路器和重试。
+  不考虑监控服务调用错误率、延迟的服务等级目标和延迟异常值。这些指标能够提供关于过长或不合理超时的洞察信息 

 **建立此最佳实践的好处：**配置了远程调用超时，且系统在设计上可以轻松处理超时，这样在远程调用响应异常缓慢时能够节省资源，且服务客户端可以轻松处理超时错误。

 **在未建立这种最佳实践的情况下暴露的风险等级：**高 

## 实施指导
<a name="implementation-guidance"></a>

 针对所有服务依赖项调用以及一般情况下的所有跨流程调用，设置连接超时和请求超时。许多框架具有内置超时功能，但仍需谨慎，因为一些超时的默认值为无限值，或者高于您的服务目标可以接受的值。过高的值会降低超时的实用性，因为客户端等待超时发生时，系统会继续消耗资源。过低的值可能会重试请求过多次，因而导致后端流量增加以及延迟变长。在有些情况下，由于要对全部请求进行重试，从而可能导致完全中断。

 在确定超时策略时，请考虑以下几点：
+  由于请求的内容、目标服务受损或网络分区故障，处理请求所需的时间可能比正常时间要长。
+  请求如果具有成本异常高的内容，就可能会消耗不必要的服务器和客户端资源。在这种情况下，让这些请求超时而不进行重试可以节省资源。服务还应利用限制和服务器端超时，来保护自身免受成本异常高的内容的侵害。
+  如果由于服务受损而导致请求用时超长，则可以使请求超时并进行重试。请求和重试的服务成本需要考虑在内，但如果原因是局部受损，则重试的成本可能不会太高，而且会减少客户端资源消耗。根据损害的性质，超时还可能会释放服务器资源。
+  如果由于网络未能传输请求或响应，导致请求完成用时很长，则可以使请求超时并进行重试。由于未能传输请求或响应，因此无论超时时间多长，结果都是失败。在这种情况下，超时不会释放服务器资源，但可以释放客户端资源并提高工作负载性能。

 利用重试和断路器等成熟的设计模式，可轻松地处理超时并支持快速失效机制方法。[AWSSDK](https://docs.aws.amazon.com/index.html#sdks) 和 [AWS CLI](https://aws.amazon.com/cli/) 允许配置连接和请求超时，以及使用指数回退和抖动进行重试。[AWS Lambda](https://aws.amazon.com/lambda/) 函数支持超时配置，所以借助 [AWS Step Functions](https://aws.amazon.com/step-functions/)，您可以利用与 AWS 服务和 SDK 的预构建集成，以低代码方式构建断路器。[AWS App Mesh](https://aws.amazon.com/app-mesh/)Envoy 提供超时和断路器功能。

## 实施步骤
<a name="implementation-steps"></a>
+  配置远程服务调用的超时，并利用内置语言超时功能或开源超时库。
+  当您的工作负载使用 AWS SDK 进行调用时，请查看文档以了解具体语言的超时配置。
  + [Python](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html)
  + [PHP](https://docs.aws.amazon.com/aws-sdk-php/v3/api/class-Aws.DefaultsMode.Configuration.html)
  + [.NET](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/retries-timeouts.html)
  + [Ruby](https://docs.aws.amazon.com/sdk-for-ruby/v3/developer-guide/timeout-duration.html)
  + [Java](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/best-practices.html#bestpractice5)
  + [Go](https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/retries-timeouts/#timeouts)
  + [Node.js](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Config.html)
  + [C\$1\$1](https://docs.aws.amazon.com/sdk-for-cpp/v1/developer-guide/client-config.html)
+  在工作负载中使用 AWS SDK 或 AWS CLI 命令时，可通过设置 `connectTimeoutInMillis` 和 `tlsNegotiationTimeoutInMillis` 的 AWS [配置默认值](https://docs.aws.amazon.com/sdkref/latest/guide/feature-smart-config-defaults.html)来配置默认超时值。
+  应用[命令行选项](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html) `cli-connect-timeout` 和 `cli-read-timeout` 来控制对 AWS 服务的一次性 AWS CLI 命令。
+  监控远程服务调用的超时，并针对持续性错误设置警报，这样您就能够主动处理错误情况。
+  实施对调用错误率、延迟的服务等级目标和延迟异常值的 [CloudWatch Metrics](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/working_with_metrics.html) 和 [CloudWatch 异常检测](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Anomaly_Detection.html)，有助于深入了解如何管理过长或不合理的超时。
+  配置 [Lambda 函数](https://docs.aws.amazon.com/lambda/latest/dg/configuration-function-common.html#configuration-timeout-console)的超时时间。
+  处理超时的时候，API Gateway 客户端必须实施自己的重试。对于下游集成，API Gateway 支持 [50 毫秒到 29 秒的集成超时](https://docs.aws.amazon.com/apigateway/latest/developerguide/limits.html#api-gateway-execution-service-limits-table)，并且不会在集成请求超时时重试。
+  实施[断路器](https://martinfowler.com/bliki/CircuitBreaker.html)模式，避免在超时时进行远程调用。打开断路器避免调用失败，并在调用响应正常时关闭断路器。
+  对于基于容器的工作负载，请查看 [App Mesh Envoy](https://docs.aws.amazon.com/app-mesh/latest/userguide/envoy.html) 功能，以便充分利用内置的超时和断路器。
+  使用 AWS Step Functions，以低代码方式为远程服务调用构建断路器，尤其是在调用 AWS 原生 SDK 和所支持的 Step Functions 集成时，以此简化工作负载。

## 资源
<a name="resources"></a>

 **相关最佳实践：**
+  [REL05-BP03 控制与限制重试调用](rel_mitigate_interaction_failure_limit_retries.md) 
+  [REL05-BP04 快速失效机制和限制队列](rel_mitigate_interaction_failure_fail_fast.md) 
+  [REL06-BP07 对系统中的请求进行端到端跟踪监控](rel_monitor_aws_resources_end_to_end.md) 

 **相关文档：**
+  [AWS SDK: Retries and Timeouts](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/retries-timeouts.html) 
+  [Amazon Builders' Library：超时、重试和抖动回退](https://aws.amazon.com/builders-library/timeouts-retries-and-backoff-with-jitter/) 
+ [Amazon API Gateway 配额和重要说明](https://docs.aws.amazon.com/apigateway/latest/developerguide/limits.html)
+ [AWS Command Line Interface: Command line options](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html)
+ [AWS SDK for Java 2.x: Configure API Timeouts](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/best-practices.html#bestpractice5)
+ [AWS Botocore using the config object and Config Reference](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html#using-the-config-object)
+ [适用于 .NET 的 AWS SDK: Retries and Timeouts](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/retries-timeouts.html)
+ [AWS Lambda：配置 Lambda 函数选项](https://docs.aws.amazon.com/lambda/latest/dg/configuration-function-common.html)

 **相关示例：**
+ [Using the circuit breaker pattern with AWS Step Functions and Amazon DynamoDB](https://aws.amazon.com/blogs/compute/using-the-circuit-breaker-pattern-with-aws-step-functions-and-amazon-dynamodb/)
+ [Martin Fowler: CircuitBreaker](https://martinfowler.com/bliki/CircuitBreaker.html?ref=wellarchitected)

 **相关工具：**
+ [AWS SDK](https://docs.aws.amazon.com/index.html#sdks)
+ [AWS Lambda](https://aws.amazon.com/lambda/)
+ [Amazon SQS](https://aws.amazon.com/sqs/)
+ [AWS Step Functions](https://aws.amazon.com/step-functions/)
+ [AWS Command Line Interface](https://aws.amazon.com/cli/)