我啥时候需要在 Heroku 中使用工作进程

Posted

技术标签:

【中文标题】我啥时候需要在 Heroku 中使用工作进程【英文标题】:When do I need to use worker processes in Heroku我什么时候需要在 Heroku 中使用工作进程 【发布时间】:2016-10-04 19:07:54 【问题描述】:

我有一个 Node.js 应用程序,其中包含一小部分用户,目前使用单个 Web 进程进行架构。我正在考虑添加一个保存后触发器,当将记录添加到我的一个表时将调用该触发器。执行保存触发器后,我想对外部 API 执行大量 IO 操作。 IO 操作的数量取决于记录上的数组列中的元素数量。因此,在将每条记录保存到此特定表中后,我可能会执行大量异步操作。

我考虑过按照Worker Dynos, Background Jobs and Queueing 中的建议将这项工作转移到后台工作中。文章根据经验给出了将耗时超过 500 毫秒的任务移至后台作业。但是,在使用 RabbitMQ (Asynchronous Web-Worker Model Using RabbitMQ in Node) 完成示例后,我不认为值得花时间设置所有内容。

所以,我的问题是:

对于并发用户数量有限的应用,是否可以将长时间运行的函数留在 Web 进程中? 如果我最终决定将这项工作发送到后台作业,那么更改我的保存后触发器似乎并不难。我错过了什么吗? 有没有比实现消息队列更容易的方法?

【问题讨论】:

运行多长时间? Heroku 的路由器将终止一个耗时超过 30 秒的请求。 devcenter.heroku.com/articles/request-timeout 不,肯定不会花那么长时间。我想应该不会超过 10 秒。 那么只要遇到那个长请求的用户不介意,你可以推迟到以后。 明白了。所以 500 毫秒的经验法则更像是创建响应式应用的最佳实践? 是的。这不是技术限制或 Heroku 强制执行的任何操作(与 30 秒限制不同)。这只是一个最佳实践。 【参考方案1】:

对于并发用户数量有限的应用,是否可以将长时间运行的函数留在 Web 进程中?

这更像是一个偏好问题,而不是任何事情。

一般来说,我说不 - 这不好......但这是基于构建在 heroku 工作人员中运行的 rabbitmq 服务的经验,并且不认为这是一件困难的事情。

稍加练习,您可能会发现这是更简单的解决方案,正如我所拥有的(它允许更简单的代码和更强大的代码,因为它将 Web 与后台处理器分开 - 允许每个人在不知道的情况下运行直接互相)

如果我最终决定将这项工作发送到后台作业,那么更改我的保存后触发器似乎并不难。我错过了什么吗?

你错过了什么吗?不是真的

只要您以结构良好和模块化的方式编写当前的网络进程内代码,将其移至后台进程通常没什么大不了的

人们不得不将代码移到后台而引起的大部分恐慌来自于他们的代码与 HTTP 请求/响应过程紧密耦合(我从个人经验中知道这有多痛苦)

有没有比实现消息队列更容易的方法?

分布式计算和后台处理有很多选择。我个人喜欢 RabbitMQ 和它使用的消息传递模式。

我建议尝试一下,看看它是否适合你。

其他选项包括带有 pub/sub 库的 redis,使用直接 HTTP API 调用到另一个 Web 服务器,或者仅在后台进程中使用计时器以给定频率检查数据库表并让代码基于运行在它找到的数据上。

附言如果您想深入了解带节点的 RMQ,您可能会发现我感兴趣的 RabbitMQ For Developers 课程:http://rabbitmq4devs.com

【讨论】:

哇,这非常有用。巧合的是,您的文章使用 Node 和 Express 正确处理 Webhook 是我昨天在深入探讨该主题时阅读并添加书签的文章之一。谢谢!另一个问题:如果我使用直接 http 调用到另一台服务器,我可以立即发送“200 Ok”响应然后继续执行其余的功能吗?在我的情况下,调用者不需要知道被调用者成功完成。 你可以这样做 - 立即发送 200 OK 然后完成处理。但这可能会导致其他问题。客户端永远不会知道服务器出错等。

以上是关于我啥时候需要在 Heroku 中使用工作进程的主要内容,如果未能解决你的问题,请参考以下文章

我啥时候使用 AppDomain?

我啥时候需要在 Java 中使用 AtomicBoolean?

我啥时候需要在 Gradle 依赖项中使用 Kapt?

我啥时候需要使用存储在数据库中的访问令牌?

我啥时候应该嘲笑?

我啥时候必须关闭数据库连接? (爪哇)