我们遇到过这个问题,我花了很多时间来解决它,但仍然感到非常沮丧。我会尽量着重说明关键点。有几个Heroku自动缩放解决方案,一开始看起来似乎不错。
已经提供的示例heroku-autoscaler实际上是用于自动缩放dynos的,而且基本上是唯一一个声称能够做到这一点的解决方案(而且它肯定做得不好)。大多数其他解决方案只会声称为您自动缩放workers。因此,让我们首先关注这一点。您将查看的自动缩放程序取决于您实际用于后台工作程序的内容,例如delayed_job,resque。这些是人们使用最普遍的后台处理库,因此自动缩放程序将尝试连接其中一个。您可以使用以下内容:
一些工具适用于Cedar堆栈,而有些可能需要进行微调。所有这些工具的问题在于它们就像试图用自己的头发把自己从沼泽中拔出来。让我们以Hirefire为例(它可能是最好的工具之一)。它修改了delayed_job,使得工作者可以查看队列并在必要时启动更多的工作者,如果队列中没有更多的作业,则工作者将关闭彼此。存在几个问题:
- 如果您想将作业放入队列以在未来执行而不是立即执行,则会遇到麻烦。当作业进入队列时,工作者会启动,但由于作业将在未来执行,因此工作者将关闭,并且除非另一个作业进入队列(这是唯一促使工作者启动的事情),否则不会重新启动。
- 您失去了重试失败作业的能力,这在delayed_job中默认是可能的,但是在失败作业被重试之前需要一段时间(并且逐渐变长),但是在此时间延迟期间,工作者将关闭,没有任何东西可以促使它们重新启动(实质上,这与第一个场景中的问题相同)。
解决此问题的方法是持续运行一个工作进程,因此可以定期监视队列并在必要时执行作业或甚至启动更多工作进程。但如果这样做,你并没有节省任何钱(你需要持续运行一个工作进程24/7,并为此付费),这就是Heroku上自动缩放器的全部前提。实质上,如果你只偶尔需要后台处理,或者你有可能失败但重试后成功的后台作业,或者你有不需要立即执行的后台作业,则没有自动缩放库可用于你使用。
以下是一种替代方案。编写Hirefire的人后来将其分离成一个Web应用程序(
Hirefire app),其本质是为您外部监视Heroku工作进程/动态,根据需要启动/关闭工作进程/动态。这在测试版中是免费的,但现在需要花钱,虽然比持续运行一个工作进程便宜,但如果您只偶尔需要几个后台作业,则仍然不可忽略。无论哪种方式,这都是确保后台作业基础架构按照您的意愿执行的唯一可行方式(还有一种方法是滚动自己的解决方案,这意味着拥有像EC2实例这样的机器,可以在其中放置一些脚本,这些脚本将ping您的Heroku应用程序并根据需要启动/关闭工作进程 - 需要相当大的努力)。
现在,Hirefire应用程序确实可以为您自动缩放dyno,它基于连接到您的Heroku请求队列的延迟来实现这一点。但是我发现这并不好用,也许如果您的Heroku应用程序实际位于Amazon数据中心附近(我们不在),您可能会有不同的体验。但是对于我们而言,它不必要地启动了大量dyno,并且无论我如何调整设置,都不会关闭它们。您可以将其归因于它是beta版,自那时以来可能已经改进,但那是我所经历的。
简而言之,如果您想自动缩放worker,请使用Hirefire应用程序,您将比预期节省更少的资金,但仍然是最便宜的选项。如果您想自动缩放dyno,则基本上没有机会。这只是在使用像Heroku这样方便的平台时所面临的限制之一。