heroku,rails,需要超过30秒

时间:2018-01-02 16:36:04

标签: ruby-on-rails api heroku cron

我在Heroku上有一个正在运行的RoR应用程序。我有一个代码片段,它将连接到外部API并将这些数据保存到我的数据库中。

然而,在Heroku的文档部分中,它说,如果请求超过30秒,则返回503错误。

我的数据库中有300个用户。每个用户平均有近30种车型。所以它应该发送带有for循环的9000(300 * 30)个请求并将数据保存到我的数据库中。

它只适用于localhost。但我无法弄清楚在Heroku上处理这个问题的有效方法。

我想到的那些;

  1. 将现有数据库从Heroku保存到本地。然后将9.000辆汽车保存到我的数据库,然后再次将数据库导入Heroku。

  2. 运行cron job来处理Heroku上的代码片段。这当然需要超过30秒。

  3. 感谢任何帮助!

    谢谢

2 个答案:

答案 0 :(得分:0)

抱歉,我没有足够的声誉在这里发表评论。

如果你在这里发布一些代码会很好,因为你很难理解你想要做什么。

如果您只需运行一次脚本来填充数据,我建议您创建一个自定义rake任务,并使其生成一些可读输出,以便您知道其日志中发生了什么。而且你可以运行超过30秒。

在这里,您可以阅读有关佣金任务http://guides.rubyonrails.org/command_line.html#custom-rake-tasks

的信息

考虑到您的描述,我可以想象您的代码如下所示:

namespace :car_types do
  desc "Update car types from external api"
  task update_from_api: :environment do
    failed_to_update_ids = []

    CarType.find_each do |car_type|
      new_data = request_new_data_from_api_here(car_type)
      car_type.update(new_data)

      puts "Updated #{car_type.id}"
    rescue => e
      failed_to_update_ids << car_type.id
      puts "Was not able to update #{car_type.id}: #{e.inspect}"
    end

    puts 'Failed to update ids:'
    puts failed_to_update_ids
  end
end

你这样运行:

heroku run rake car_types:update_from_api --app=your_heroku_instance

最好不要将代码存储在rake任务中,而是存储在某个类或库中,然后您就可以从任何地方运行此代码:从控制台或应用程序的任何部分,只需记住此代码是耗时的,必须在后台运行。

如果您需要定期运行,可以使用Heroku Scheduler安排它:https://devcenter.heroku.com/articles/scheduler

答案 1 :(得分:0)

顺序执行9000次api调用效率非常低。你应该并行化它们。这是一种快速天真的方式:

threads = users.map { |user| Thread.new { api_call(user) } }  # Launch all api calls and returns an array of threads
thread.each(:join)  # Wait for all api calls are ended

有关文档中线程的更多详细信息:http://ruby-doc.org/core-2.5.0/Thread.html

但是,如果最长的请求超过30秒,则无法帮助您。在这种情况下,您应该将其移至background / cron作业。

还有这个好的库可以发出并行HTTP请求:https://github.com/typhoeus/typhoeus

如果不了解应用程序的运行方式,很难帮助您。但我认为线程和背景/ cron工作是解决问题的好线索。