2016-10-30 71 views
1

我想使用Heroku,但是他们每24小时随机重新启动dynos的事实让事情变得有点困难。如何在Heroku上处理长时间运行的作业?

我有一系列处理付款处理的工作非常重要,我希望他们支持数据库,因此他们100%可靠。出于这个原因,我选择了速度慢的DJ。

因为我选择了DJ,这意味着我也不能只将5,000,000个事件一次推送到数据库(每个电子邮件发送1次)。

因为这样,我有更长时间的运行作业(几个小时内发送200,000条短信)。

随着这些长时间运行的工作,如果它们在中间被切断,让它们工作更具挑战性。

看来,heroku发送SIGTERM,然后期望过程在30秒内关闭。这对于我的长期工作不会发生。

现在我不知道如何处理它们......我能想到的唯一方法是在发送文本后立即更新数据库(例如,sms_sent_at列),但这只是意味着我破坏数据库性能,而不是为每个批次发送单个更新查询。

如果我可以安排重新启动,这将会好很多,至少我可以在晚上做到这一点,当我99%可能不会运行任何不超过30秒关闭的任何工作下。

或者......另一种方式,我可以在长时间运行的DJ中'听'SIGTERM,并且至少要尽早中止循环,以便稍后恢复?

回答

0

下面是一个正确的答案,你听SIGTERM(我使用DJ在这里),然后优雅地抢救。这些工作是幂等的,这很重要。

Long running delayed_job jobs stay locked after a restart on Heroku

class WithdrawPaymentsJob 

    def perform 
    begin 
     term_now = false 
     old_term_handler = trap('TERM') { term_now = true; old_term_handler.call } 

     loop do 

     puts 'doing long running job' 
     sleep 1 

     if term_now 
      raise 'Gracefully terminating job early...' 
     end 
     end 

    ensure 
     trap('TERM', old_term_handler) 
    end 
    end 

end 

这里是你如何与Que解决它:

if Que.worker_count.zero? 
     raise 'Gracefully terminating job early...' 
    end 
1

手动重新启动将重置24小时时钟 - heroku ps:restart在您的首选时间应该给你你正在寻找的控制。

更多信息可以在这里找到:Dynos and the Dyno Manager

相关问题