AWS Elastic Beanstalk 中的工作人员“dyno”

Posted

技术标签:

【中文标题】AWS Elastic Beanstalk 中的工作人员“dyno”【英文标题】:Worker "dyno" in AWS Elastic Beanstalk 【发布时间】:2014-10-02 14:31:15 【问题描述】:

Amazon Web Service 现在在其 Elastic Beanstalk 中有一个工作层。但是,它仍然让我们这些来自 Worker dyno 时代的人感到困惑。

作为比较,在 Heroku 中,可以为 web 和 worker 分别配置两个 dyno(类似于处理器?)。网络将适用于任何请求,并且通常会在 15 秒时超时。因此,如果您有一个持续时间更长的请求,您的请求将简单地超时,尽管本身并未终止。在这种情况下,您应该使用 worker 并且您的 web dyno 应该每分钟访问端点数次(也许)以检查是否有任何结果要返回给用户。要制作工人或网络测功机,您只需滑动滑块即可。有时,您可能需要一个 Procfile。但是没有什么花哨的东西,或者真正困难的东西,或者令人困惑的东西。

在 AWS EBS (Elastic Beanstalk) 中,从您点击 eb init 的第一天起,系统会询问您它是 Standard 还是 Worker。当你达到标准时,似乎没有办法让它成为工人。

在我们的情况下,worker 和标准 web 位于一个应用程序下。那么,我们如何将 EBS 实例同时用于 worker 和 standard。我们的工人正在使用 sidekiq 和 redis。请指出任何指导或帮助我们解决此问题。

【问题讨论】:

【参考方案1】:

AWS Elastic Beanstalk 有两种类型的环境 - Web 层和 Worker 层。

Web 层环境适用于 Web 应用程序 - http/https 请求处理。您在负载均衡器后面获得一个或多个 EC2 实例。您可以根据需要获取其他资源,例如数据库。您可以选择您想要的平台,例如Ruby、Python、Java、Node.js、php、Docker。

工作环境用于异步消息处理。当您创建工作环境时,您没有负载均衡器。您的所有 EC2 实例都在一个自动扩展组中。所有这些实例都在运行一个守护进程,该守护进程轮询单个 SQS 队列以获取消息。当守护程序从 SQS 队列中提取消息时,守护程序会在 localhost:80 上发送 HTTP Post 请求。您可以配置端口,但重要的是守护程序将消息作为 HTTP 请求发布到 localhost。您的工作应用程序实际上是一个 Web 应用程序,它接收发布请求并处理消息。成功处理消息后,worker 守护进程期望您在 localhost 上运行的 Web 应用程序返回 HTTP 200 OK 响应。然后守护程序从 SQS 队列中删除该消息。您可以为任何平台编写工作应用程序,就像标准 Web 服务器应用程序一样 - Ruby、Python、Java、Node.js、PHP、Docker。

根据我对您的用例的理解,我建议创建两个 Elastic Beanstalk 环境 - 一个 Standard 环境和一个 Worker 环境。标准 Web 服务器接收 HTTP 请求并同步处理它们。此环境将相关数据放入 SQS 队列中。第二个环境是一个工作者,在这个环境上运行的守护进程轮询这个 SQS 队列以获取消息。您的第二个环境是未向 Internet 开放的 Web 应用程序。工作程序守护程序将消息作为 HTTP 请求发布到工作程序环境。因此,您可以使用第二个工作环境异步处理长时间运行的工作负载。

通过工作线程环境,您可以使用自己的队列,或者 Elastic Beanstalk 可以为您生成队列。您可以根据需要配置消息可见性超时、http 连接等参数,也可以使用默认值。

以下是一些可能对您有用的链接:

http://aws.amazon.com/blogs/aws/background-task-handling-for-aws-elastic-beanstalk/

http://blogs.aws.amazon.com/application-management/post/Tx1Y8QSQRL1KQZC/Elastic-Beanstalk-Video-Tutorial-Worker-Tier

https://***.com/a/23942498/161628

这是否符合您的要求?如果您还有其他问题,请告诉我。

更新

您需要在两个地方上传源代码 - 一次用于工作环境,一次用于 Web 服务器环境。如果有人从头开始,那么他们可能有两个独立的代码库。但我认为在你的情况下,我认为在两个环境之间共享一个代码库应该是非常好的。假设您的 Web 请求到达“/register”,那么应用程序中的 register() 方法可以将消息发布到 SQS 队列并通过 HTTP 请求完成。现在,您的工作环境将轮询 SQS 队列并通过 localhost 上的 HTTP 将消息发布到 URL '/async_register',这将在您的应用程序中调用方法 async_register() 并执行异步处理。这两种方法可以存在于同一个源代码包中,可以由工作程序和 Web 服务器环境共享。 worker 和 web server 使用的代码路径会不同,因此 web server 环境会调用 register() 而 worker 环境会调用 async_register() 方法。

另一个需要注意的是,本地主机上的工作守护程序发送的 HTTP 请求将包含一个 HTTP 标头 - “User-Agent”:“aws-sqsd/1.1”。阅读更多here。因此,在您的 Web 应用程序中,您可以有一个侦听器来在“/register”上发布请求,并且取决于此标头是否存在,您可以在内部调用 register() 或 async_register() 方法。

另外我认为,如果您想在两个环境之间共享代码库,您可以只在一个地方上传代码库。您的环境在逻辑上按应用程序分组。因此,您可以拥有一个应用程序。您使用“CreateApplicationVersion”API 调用将源代码上传到此应用程序。假设您上传带有标签“v1”的应用程序版本。您现在可以在同一个应用程序下创建工作环境和 Web 服务器环境。创建环境时,您需要提供一个版本以部署到您的环境中。在这种情况下,您可以将 v1 部署到这两个环境。因此,您将为两种环境共享相同的源代码。当您有新版本“v2”时。您上传此版本,然后对两个环境执行更新,将其版本更改为“v2”。

可以将相同版本的源代码部署到两种环境。它们将在不同的 EC2 实例上运行,因为一个环境专用于响应 Web 请求,一个环境专用于响应异步 Web 请求(工作线程)。

【讨论】:

需要把源码上传给每个worker吗?与 Heroku 的情况一样,一个源代码同时用于 worker 和标准(web)dyno。 我认为,如果您可以提供一篇博文(无论是否在此处),通过真实的分步示例详细说明步骤,我认为这将对所有人都有帮助。因为我相信这个案例是人们从 Heroku(或类似体验)迁移到 AWS 之类的东西时将面临的最大问题。 更有趣的问题是如何确定应用程序(例如单个源代码 app.js)是作为工作人员运行还是作为服务器运行? 您可以从 DescribeEnvironments API 响应中的层版本中看出这一点。或者您可以在控制台中看到它。

以上是关于AWS Elastic Beanstalk 中的工作人员“dyno”的主要内容,如果未能解决你的问题,请参考以下文章

AWS Elastic Beanstalk 中的 HTTPS 配置

AWS Elastic Beanstalk 中的 Python:私有包依赖项

AWS Elastic Beanstalk 中的 mysqlclient 安装错误

一个 AWS 账户中的 Elastic Beanstalk 能否与另一个 AWS 账户中的 RDS 通信?

如何解决 AWS Elastic Beanstalk 中的“容器命令构建失败”一般错误?

AWS Elastic Beanstalk 中的 JDBC 连接字符串