

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

# Elastic Beanstalk 工作线程环境
<a name="using-features-managing-env-tiers"></a>

如果您的 Amazon Elastic Beanstalk 应用程序执行的操作或工作流程需要很长时间才能完成，则可以将这些任务卸载到专门*的工作环境中*。确保您的应用程序能够在负载下保持响应的常见方法是，将 Web 应用程序前端与执行阻止操作的过程分离开。

长时间运行的任务是指大大增加完成请求所需的时间的操作，例如，处理图像或视频、发送电子邮件或生成 ZIP 存档。这些操作可能只需花费 1 秒或 2 秒的时间即可完成，但对于要在 500 毫秒内完成的 Web 请求来说，几秒的延迟时间也是非常长的。

一种选择是在本地生成工作进程，返回成功值并异步处理任务。如果您的实例能够与其收到的所有任务保持同步，此选择便有效。不过，在高负载下，实例会填满后台任务并且不会响应优先级更高的请求。如果单个用户能够生成多个任务，负载增加可能不会对应用户增加，这会导致难以有效地向外扩展 Web 服务器。

为避免在本地运行长时间运行的任务，您可以使用适用于您的编程语言的 Amazon 软件开发工具包将它们发送到亚马逊简单队列服务 (Amazon SQS) Simple Queue Service 队列，然后运行在单独的一组实例上执行这些任务的流程。然后，您采取适当的设计，让工作线程实例仅在能够运行项目时才从队列中提取项目，从而阻止项目将实例填满。

Elastic Beanstalk 工作线程环境通过管理 Amazon SQS 队列并在每个从队列中读取的实例上运行[守护程序进程](#worker-daemon)来简化此过程。当守护程序从队列中提取项目时，它会将 HTTP POST 请求本地发送到端口 80 上的 `http://localhost/` (正文中包含队列消息的内容)。您的应用程序只需执行长时间运行的任务来响应 POST 请求。可以[配置守护程序](#using-features-managing-env-tiers-worker-settings)以发布到其他路径，使用 application/JSON 之外的 MIME 类型，连接到现有队列或自定义连接（最大并发请求数）、超时和重试。

![Elastic Beanstalk 工件环境的 Amazon SQS 消息处理](http://docs.amazonaws.cn/elasticbeanstalk/latest/dg/images/aeb-messageflow-worker.png)


利用[定期任务](#worker-periodictasks)，您还可以将工作线程守护程序配置为根据 cron 计划对消息进行排队。每个定期任务均可向不同的路径发送 POST 请求。通过在定义每个任务的计划和路径的源代码中包含 YAML 文件来启用定期任务。

**注意**  
[Windows Server 平台上的 .NET](create_deploy_NET.md) 不支持工作线程环境。

**Topics**
+ [工作线程环境 SQS 守护程序](#worker-daemon)
+ [死信队列](#worker-deadletter)
+ [定期任务](#worker-periodictasks)
+ [使用 Amazon CloudWatch 在工作线程环境层中自动扩展](#worker-scaling)
+ [配置工作线程环境](#using-features-managing-env-tiers-worker-settings)

## 工作线程环境 SQS 守护程序
<a name="worker-daemon"></a>

工作线程环境运行 Elastic Beanstalk 提供的守护程序进程。此守护程序将定期更新以添加功能和修复 Bug。要获取最新版本的守护程序，请更新到最新的[平台版本](concepts.platforms.md)。

当工作线程环境中的应用程序返回 `200 OK` 响应以确认其已收到并成功处理了请求时，守护程序将向 Amazon SQS 队列发送 `DeleteMessage` 调用以便从队列中删除消息。如果应用程序返回 `200 OK` 之外的任何其他响应，则 Elastic Beanstalk 将会等待，然后在经过配置的 `ErrorVisibilityTimeout` 时间段后将消息放回到队列中。如果没有响应，则 Elastic Beanstalk 将会等待，在经过 `InactivityTimeout` 时间段后将消息放回到队列中，以便在处理期间可以对消息进行另一次尝试。

**注意**  
Amazon SQS 队列的属性（消息顺序、传 at-least-once送和消息采样）可能会影响您为工作环境设计 Web 应用程序的方式。有关更多信息，请参阅《Amazon Simple Queue Service 开发人员指南》[https://docs.amazonaws.cn/AWSSimpleQueueService/latest/SQSDeveloperGuide/Welcome.html](https://docs.amazonaws.cn/AWSSimpleQueueService/latest/SQSDeveloperGuide/Welcome.html)中的[分布式队列的属性](https://docs.amazonaws.cn/AWSSimpleQueueService/latest/SQSDeveloperGuide/DistributedQueues.html)。

Amazon SQS 会自动删除在队列中存在时间超过所配置的 `RetentionPeriod` 的消息。

守护程序将设置以下 HTTP 标头。


****  

|  **HTTP 标头**  | 
| --- |
| **名称** | **值** | 
| --- |--- |
| `User-Agent` | `aws-sqsd`<br />`aws-sqsd/1.1`1 | 
| `X-Aws-Sqsd-Msgid` | SQS 消息 ID，用于检测消息风暴 (异常多的新消息)。 | 
| `X-Aws-Sqsd-Queue` | SQS 队列的名称。 | 
| `X-Aws-Sqsd-First-Received-At` | 采用 [ISO 8601 格式](http://www.w3.org/TR/NOTE-datetime)的 UTC 时间（当首次收到消息时）。 | 
| `X-Aws-Sqsd-Receive-Count` | SQS 消息接收计数。 | 
| `X-Aws-Sqsd-Attr-{{message-attribute-name}}` | 分配给正在处理的消息的自定义消息属性。`message-attribute-name` 是实际消息属性名称。所有字符串和数字消息属性都将添加到标头。二进制属性已被放弃且未包含在标头中。 | 
| `Content-Type` | Mime 类型配置；默认情况下为 `application/json`。 | 

## 死信队列
<a name="worker-deadletter"></a>

Elastic Beanstalk 工作线程环境支持 Amazon Simple Queue Service (Amazon SQS) 死信队列。死信队列是其他 (源) 队列将因为某种原因而无法成功处理的消息发送到其中的队列。使用死信队列的主要好处是能够放弃和隔离未成功处理的消息。然后，您可以分析发送到死信队列的任何消息，以尝试确定它们未成功处理的原因。

如果您在创建工作线程环境层时指定了自动生成的 Amazon SQS 队列，则默认情况下会为工作线程环境启用死信队列。如果您为工作线程环境选择现有的 SQS 队列，则必须使用 SQS 单独配置死信队列。有关如何使用 SQS 配置死信队列的信息，请参阅[使用 Amazon SQS 死信队列](https://docs.amazonaws.cn/AWSSimpleQueueService/latest/SQSDeveloperGuide/SQSDeadLetterQueue.html)。

您不能禁用死信队列。无法交付的消息最终总会发送到死信队列。但是，您可以通过将 `MaxRetries` 选项设置为最大有效值 100 来有效禁用此功能。

如果没有为您的工作线程环境的 Amazon SQS 队列配置死信队列，则 Amazon SQS 会将消息保留在队列中，直至超过保留期。有关配置保留期的详细信息，请参阅[配置工作线程环境](#using-features-managing-env-tiers-worker-settings)。

**注意**  
Elastic Beanstalk `MaxRetries` 选项的功能与 SQS `MaxReceiveCount` 选项相同。如果您的工作线程环境不使用自动生成的 SQS 队列，请使用 SQS 中的 `MaxReceiveCount` 选项来有效禁用死信队列。有关更多信息，请参阅[使用 Amazon SQS 死信队列](https://docs.amazonaws.cn/AWSSimpleQueueService/latest/SQSDeveloperGuide/SQSDeadLetterQueue.html)。

有关 SQS 消息生命周期的更多信息，请转到[消息生命周期](https://docs.amazonaws.cn/AWSSimpleQueueService/latest/SQSDeveloperGuide/MessageLifecycle.html)。

## 定期任务
<a name="worker-periodictasks"></a>

您可以在源包中名为 `cron.yaml` 的文件中定义定期任务，以便定期自动将作业添加到工作线程环境的队列中。

例如，以下 `cron.yaml` 文件创建两个定期任务。第一个任务每 12 小时运行一次，第二个任务在 UTC 时间每天晚上 11 点运行一次。

**Example cron.yaml**  

```
version: 1
cron:
 - name: "backup-job"
   url: "/backup"
   schedule: "0 */12 * * *"
 - name: "audit"
   url: "/audit"
   schedule: "0 23 * * *"
```

对于每个任务，**name** 必须是唯一的。URL 是为触发作业而将 POST 请求发送到的路径。计划是一个用于确定任务运行时间的 [CRON 表达式](http://en.wikipedia.org/wiki/Cron#CRON_expression)。

当任务运行时，守护程序会向环境的 SQS 队列发送一条消息，其标头指示需要执行的作业。环境中的任何实例均可选择消息和处理作业。

**注意**  
如果您使用现有 SQS 队列配置工作线程环境并选择 [Amazon SQS FIFO 队列](https://docs.amazonaws.cn/AWSSimpleQueueService/latest/SQSDeveloperGuide/FIFO-queues.html)，则不支持定期任务。

Elastic Beanstalk 使用领导选择来确定工作线程环境中的哪个实例对定期任务进行排队。每个实例均尝试通过对 Amazon DynamoDB 表进行写入来变为领导。第一个获得成功的实例将成为领导，并且必须继续对表进行写入来维护领导状态。如果领导中断服务，则另一个实例将迅速成为领导。

对于定期任务，工作线程守护程序将另外设置以下领导。

 


****  

|  **HTTP 标头**  | 
| --- |
| **名称** | **值** | 
| --- |--- |
| `X-Aws-Sqsd-Taskname` | 对于定期任务，为要执行的任务的名称。 | 
| `X-Aws-Sqsd-Scheduled-At` | 为定期任务安排的时间 | 
| `X-Aws-Sqsd-Sender-Id` | Amazon 消息发件人的账号 | 

## 使用 Amazon CloudWatch 在工作线程环境层中自动扩展
<a name="worker-scaling"></a>

Amazon EC2 Auto Scaling 共同 CloudWatch 监控工作线程环境中正在运行的实例的 CPU 使用率。您为 CPU 容量配置的自动扩展限制将决定 Auto Scaling 组运行多少个实例来相应管理 Amazon SQS 队列中的消息吞吐量。每个 EC2 实例都会向发布其 CPU 使用率指标 CloudWatch。Amazon EC2 Auto Scaling 从 CloudWatch 工作线程环境中所有实例的平均 CPU 使用率中检索。您需要配置上限和下限阈值，以及要根据 CPU 容量添加或终止的实例的数量。当 Amazon EC2 Auto Scaling 检测到已达到 CPU 容量的指定上限阈值时，Elastic Beanstalk 会在工作线程环境中创建新实例。当 CPU 负载降到阈值之下时，将删除实例。

**注意**  
实例被终止时还未处理的消息将返回队列中，可由仍在运行的实例中的其他守护程序进行处理。

您还可以根据需要使用 Elastic Beanstalk 控制台、CLI 或选项文件设置其他 CloudWatch 警报。有关更多信息，请参阅[在亚马逊上使用 Elastic Beanstalk CloudWatch](AWSHowTo.cloudwatch.md)和[使用步进扩展策略创建 Auto Scaling 组](https://docs.amazonaws.cn/autoscaling/ec2/userguide/as-scaling-simple-step.html#policy-creating-asg-console)。

## 配置工作线程环境
<a name="using-features-managing-env-tiers-worker-settings"></a>

您可以编辑[环境管理控制台](environments-console.md)中的 **Configuration**（配置）页面上的 **Worker**（工件）类别来管理工件环境的配置。

![在 Elastic Beanstalk 控制台中修改工作线程配置页面](http://docs.amazonaws.cn/elasticbeanstalk/latest/dg/images/aeb-config-worker.png)


**注意**  
您可以配置发布工作线程队列消息的 URL 路径，但不能配置 IP 端口。Elastic Beanstalk 始终在端口 80 上发布工作线程队列消息。工作线程环境应用程序或其代理必须侦听端口 80。

**配置工作线程守护程序**

1. 打开 [Elastic Beanstalk](https://console.amazonaws.cn/elasticbeanstalk) 控制台，然后**在 “区域” 列表中，选择您**的。 Amazon Web Services 区域

1. 在导航窗格中，选择 **Environments**（环境），然后从列表中选择环境的名称。

1. 在导航窗格中，选择 **Configuration**（配置）。

1. 在 **Worker (工作线程)** 配置类别中，选择 **Edit (编辑)**。

**Modify worker (修改工作线程)** 配置页面具有以下选项。

在 **Queue (队列)** 部分中：
+ **工作线程队列** – 指定守护程序从中读取的 Amazon SQS 队列。如果您有现有队列，可以选择现有队列。如果您选择 **Autogenerated queue (自动生成的队列)**，则 Elastic Beanstalk 将创建新的 Amazon SQS 队列和相应的 **Worker queue URL (工作线程队列 URL)**。
**注意**  
选择 **Autogenerated queue (自动生成的队列)** 时，Elastic Beanstalk 创建的队列是[标准](https://docs.amazonaws.cn/AWSSimpleQueueService/latest/SQSDeveloperGuide/standard-queues.html) Amazon SQS 队列。选择现有队列时，可以提供标准或 [FIFO](https://docs.amazonaws.cn/AWSSimpleQueueService/latest/SQSDeveloperGuide/FIFO-queues.html) Amazon SQS 队列。请注意，如果提供 FIFO 队列，不支持[定期任务](#worker-periodictasks)。
+ **Worker queue URL (工作线程队列 URL)** – 如果您选择现有**工作线程队列**，则此设置将显示与该 Amazon SQS 队列关联的 URL。

在 **Messages (消息)** 部分中：
+ **HTTP path (HTTP 路径)** – 指定将从 Amazon SQS 队列接收数据的应用程序的相对路径。该数据将插入到 HTTP POST 消息的消息正文中。默认值为 `/`。
+ **MIME type (MIME 类型)** - 指示 HTTP POST 消息使用的 MIME 类型。默认值为 `application/json`。但是，因为您可以创建并指定您自己的 MIME 类型，所以任何值都是有效的。
+ **HTTP connections (HTTP 连接)** – 指定守护程序可与 Amazon EC2 实例中的任何应用程序建立的最大并发连接数量。默认值为 **50**。可以指定 **1** 到 **100**。
+ **Visibility timeout (可见性超时)** – 指示锁定来自 Amazon SQS 队列的传入消息进行处理的时间（以秒为单位）。配置的时间量过后，会再次使消息在队列中可见，以供其他守护程序读取。选择一个值，该值大于应用程序处理消息所需的预期值，最多为 **43200** 秒。
+ **Error visibility timeout (错误可见性超时)** – 指示在处理尝试由于显式错误而失败后，Elastic Beanstalk 将消息返回到 Amazon SQS 队列之前经过的时间（以秒为单位）。可以指定 **0** 到 **43200** 秒。

在 **Advanced options (高级选项)** 部分中：
+ **Max retries (最大重试次数)** – 指定 Elastic Beanstalk 在将消息移到[死信队列](#worker-deadletter)之前，尝试将消息发送到 Amazon SQS 队列的最大次数。默认值为 **10**。可以指定 **1** 到 **100**。
**注意**  
**Max retries**（最大重试次数）选项仅适用于配置了死信队列的 Amazon SQS 队列。对于未配置死信队列的任何 Amazon SQS 队列，Amazon SQS 会将消息保留在队列中并持续处理，直至 **Retention period**（保留期）选项指定的期间过期为止。
+ **Connection timeout (连接超时)** - 指定等待与应用程序成功建立连接的时间 (以秒为单位)。默认值为 **5**。可以指定 **1** 到 **60** 秒。
+ **Inactivity timeout (不活动超时)** - 指示等待与应用程序的现有连接传回响应的时间 (以秒为单位)。默认值为 **180**。可以指定 **1** 到 **36000** 秒。
+ **Retention period (保留期)** – 指示消息有效且正在进行处理的时间（以秒为单位）。默认值为 **345600**。可以指定 **60** 到 **1209600** 秒。

如果您使用现有的 Amazon SQS 队列，则您在创建工作线程环境时配置的设置可能会与直接在 Amazon SQS 中配置的设置冲突。例如，如果您在配置工作线程环境时所用的 `RetentionPeriod` 值高于在 Amazon SQS 中设置的 `MessageRetentionPeriod` 值，则 Amazon SQS 会在消息存在时间超过 `MessageRetentionPeriod` 时删除该消息。

反过来，如果您在工作线程环境设置中配置的 `RetentionPeriod` 值低于在 Amazon SQS 中设置的 `MessageRetentionPeriod` 值，则守护程序将先于 Amazon SQS 删除该消息。对于 `VisibilityTimeout`，您在工作线程环境设置中为守护程序配置的值将覆盖 Amazon SQS `VisibilityTimeout` 设置。请通过比较 Elastic Beanstalk 设置与 Amazon SQS 设置，确保合理地删除消息。