简体   繁体   English

自动重启我的 heroku 应用程序

[英]Restart my heroku application automatically

This terminal command restarts my heroku application:此终端命令重新启动我的 heroku 应用程序:

heroku restart

Is there a way to run a script that will run this command and restart my application every hour?有没有办法运行一个脚本来运行这个命令并每小时重新启动我的应用程序?

I actually just had to solve this problem for my apps and wrote a post on it with more details.我实际上只需要为我的应用程序解决这个问题,并写了一篇关于它的更多细节的帖子。 Basically, you need the heroku-api gem now since the heroku gem is replaced by the CLI.基本上,您现在需要 heroku-api gem,因为 heroku gem 已被 CLI 取代。 Then you need a rake task, a couple of config variables and the heroku scheduler plugin (free except for minimal dyno time).然后你需要一个 rake 任务、几个配置变量和 heroku 调度程序插件(免费,除了最短的 dyno 时间)。

The rake task looks like this: rake 任务如下所示:

namespace :heroku do
  desc 'restarts all the heroku dynos so we can control when they restart'
  task :restart do
    Heroku::API.
      new(username: ENV['HEROKU_USERNAME'], password: ENV['HEROKU_PASSWORD']).
      post_ps_restart(ENV['HEROKU_APP_NAME'])
  end
end

You can also set it up to use your API token instead of putting your username and password into the config.您还可以将其设置为使用您的 API 令牌,而不是将您的用户名和密码放入配置中。 This only matters if you don't want your co-contributors/coworkers knowing your password or the password to your main account on Heroku.这仅在您不希望您的共同贡献者/同事知道您的密码或您在 Heroku 上的主帐户的密码时才重要。

heroku config:set HEROKU_USERNAME=[username] HEROKU_PASSWORD=[password] HEROKU_APP_NAME=[app_name] -a [app_name]

Now, go ahead and deploy and test:现在,继续部署和测试:

git push [heroku_remote_name] [feature_branch]:master
heroku run rake heroku:restart -a [app_name]

Lastly, we'll need to set up the task to run this on schedule.最后,我们需要设置任务以按计划运行。 I've chosen to go with the free Heroku cron add-on:我选择使用免费的 Heroku cron 附加组件:

heroku addons:add scheduler:standard -a [app_name]
heroku addons:open scheduler -a [app_name]

This will open up the scheduler UI in your browser and you can create a scheduled worker to run the rake task whenever you'd like.这将在您的浏览器中打开调度程序 UI,您可以创建一个调度工作程序来随时运行 rake 任务。 We only need it once per day and we're choosing to run it before our first scheduled job of the day.我们每天只需要一次,我们选择在当天的第一个预定工作之前运行它。

My original post with frigged up CSS (see update2 below):我的原始帖子带有 frigged 的​​ CSS(请参阅下面的更新 2):

https://web.archive.org/web/20150612091315/http://engineering.korrelate.com/2013/08/21/restart-heroku-dynos-on-your-terms/ https://web.archive.org/web/20150612091315/http://engineering.korrelate.com/2013/08/21/restart-heroku-dynos-on-your-terms/

UPDATE更新

I changed the name of the task from "implode" to "restart" to be way more clear as to what is happening.我将任务名称从“内爆”更改为“重新启动”,以便更清楚地了解正在发生的事情。 Implode is a fun name but pretty much useless otherwise. Implode 是一个有趣的名字,但除此之外几乎毫无用处。

UPDATE2更新2

Apparently my company removed the blog post.显然,我的公司删除了博文。 I'm adding more of the code here and I've updated the link, but the CSS looks like a dog threw it up.我在这里添加了更多代码并且我已经更新了链接,但是 CSS 看起来像一条狗把它扔了。 My apologies.我很抱歉。

You could create a heroku cron job that uses the Heroku api on your application to restart itself...您可以创建一个 heroku cron 作业,它在您的应用程序上使用 Heroku api 来重新启动自己...

One question though - why?一个问题——为什么?

We solved this by using a buildpack to get the heroku command available to the dyno itself, then using Heroku Scheduler.我们通过使用 buildpack 来获取heroku本身可用的heroku命令,然后使用 Heroku Scheduler 解决了这个heroku

We added the https://github.com/gregburek/heroku-buildpack-toolbelt buildpack per its instructions:我们根据其说明添加了https://github.com/gregburek/heroku-buildpack-toolbelt buildpack:

heroku buildpacks:add https://github.com/gregburek/heroku-buildpack-toolbelt.git
heroku config:add HEROKU_TOOLBELT_API_EMAIL=`heroku whoami`
heroku config:add HEROKU_TOOLBELT_API_PASSWORD=`heroku auth:token`

Then made sure the app slug was rebuilt per the instructions:然后确保按照说明重建了应用程序段:

git push heroku master

In Heroku Scheduler, we added this as a hourly job:在 Heroku Scheduler 中,我们将其添加为每小时工作:

vendor/heroku-toolbelt/bin/heroku ps:restart -a $HEROKU_APP_NAME

You can determine if it's working by looking for Scheduler output in the Heroku logs, and of course by the memory graph of the app in the Heroku dashboard (if you're restarting to work around a memory leak).您可以通过在 Heroku 日志中查找调度程序输出来确定它是否正常工作,当然也可以通过 Heroku 仪表板中应用程序的内存图来确定它是否正常工作(如果您正在重新启动以解决内存泄漏问题)。

A script isn't necessary, just "crash" your application and Heroku will restart it.不需要脚本,只需“崩溃”您的应用程序,Heroku 将重新启动它。

Just don't do this more frequently than once every ten minutes or Heroku will subject you to a 10 minute timeout.这样做的频率不要超过每 10 分钟一次,否则 Heroku 会使您超时 10 分钟。

In node.js you do this with process.exit(0) .在 node.js 中,您可以使用process.exit(0)执行此操作。

From Chris at Heroku Support:来自 Heroku 支持的 Chris:

A crashed dyno will be restarted immediately.崩溃的 dyno 将立即重新启动。 If the dyno moves from a crashed state into an "up" state (meaning that the dyno bound to $PORT) then it's subject to being a normal running dyno.如果测功机从崩溃状态移动到“启动”状态(意味着测功机绑定到 $PORT),则它会成为正常运行的测功机。 If it crashes again during the boot or "starting" sequence then it won't be restarted again until after the TIMEOUT period.如果它在启动或“启动”序列期间再次崩溃,那么它不会在超时时间段之后再次重新启动。 The TIMEOUT period is currently 10 minutes but that is subject to change.超时期限目前为 10 分钟,但可能会发生变化。 This prevents dynos that are continually crashing from putting extraneous load on the platform.这可以防止不断崩溃的 dynos 给平台带来额外的负载。

However, as good as that sounds, it doesn't work in practice.然而,尽管听起来不错,但在实践中却行不通。 You will hit the timeout every time you exit because the dyno manager expects your app to be up:每次退出时都会超时,因为 dyno 管理器希望您的应用程序启动:

For your worker process management you're exiting the process cleanly but the platform is expecting the dyno to be up.对于您的工作进程管理,您正在干净地退出进程,但平台希望 dyno 启动。 It sounds like you're essentially crashing the dyno as a result.听起来您实际上是在使测功机崩溃。

So again, if you need to restart periodically -- and that period can be set to > 10 minutes -- this is a easy and simple way to manage memory clearing.再说一次,如果您需要定期重新启动——并且该时间段可以设置为 > 10 分钟——这是一种管理内存清除的简单方法。 If you need to reboot dynamically (for example, when idle is detected) or frequently you will need to explore other options.如果您需要动态重启(例如,当检测到空闲时)或频繁重启,您将需要探索其他选项。

You can access the name of the dyno (ex. "worker.3", "web.1") through the environment variable "PS" and issue a heroku API restart command programmatically.您可以通过环境变量“PS”访问 dyno 的名称(例如“worker.3”、“web.1”)并以编程方式发出 heroku API 重启命令。

Inspired by https://www.stormconsultancy.co.uk/blog/development/ruby-on-rails/automatically-restart-struggling-heroku-dynos-using-logentries/灵感来自https://www.stormconsultancy.co.uk/blog/development/ruby-on-rails/automatically-restart-struggling-heroku-dynos-using-logentries/

# Setup
heroku plugins:install https://github.com/heroku/heroku-oauth
heroku authorizations:create -s write
heroku config:add RESTART_API_KEY=<API KEY>
heroku config:add APP_NAME=<App Name>

heroku addons:add scheduler:standard -a <App Name>
heroku addons:open scheduler -a <App Name>
add `rake restart`

# Gemfile
gem 'platform-api', require: false

# Rakefile
task :restart do
  require 'platform-api'
  app_name = ENV.fetch('APP_NAME')
  key = ENV.fetch('RESTART_API_KEY')
  connection = PlatformAPI.connect_oauth(key)
  connection.dyno.list(app_name).map do |info|
    if info['type'] == 'web' && info['state'] == 'up'
      puts "Restarting #{info.inspect}"
      connection.dyno.restart(app_name, info['name'])
    else
      puts "Skipping #{info.inspect}"
    end
  end
end

I solved this with a very simple curl command script within the repo that is triggered using the free Heroku scheduler .我在 repo 中使用一个非常简单的 curl 命令脚本解决了这个问题,该脚本使用免费的 Heroku scheduler触发。

#!/bin/sh curl -X DELETE "https://api.heroku.com/apps/${HEROKU_APP_NAME}/dynos" \\ --user "${HEROKU_CLI_USER}:${HEROKU_CLI_TOKEN}" \\ -H "Content-Type: application/json" \\ -H "Accept: application/vnd.heroku+json; version=3"

See https://gist.github.com/mattheworiordan/f052b7693aacd025f025537418fa5708 .https://gist.github.com/mattheworiordan/f052b7693aacd025f025537418fa5708

We've given our app a long-running token to use to authenticate with the Heroku API, and simply included a curl request in our code to restart the app.我们为我们的应用程序提供了一个长期运行的令牌,用于对 Heroku API 进行身份验证,并在我们的代码中简单地包含一个 curl 请求以重新启动应用程序。

Create a long-running API token:创建一个长期运行的 API 令牌:

$ heroku authorizations:create --description="Long-lived token for app restarts"
Creating OAuth Authorization... done
Client:      <none>
ID:          abcdabcd-abcd-4bcd-abcd-abcdabcdabcd
Description: Long-lived token for app restarts
Scope:       global
Token:       12341234-1234-4234-1234-123412341234
Updated at:  Tue May 11 2021 09:16:38 GMT-0400 (Eastern Daylight Time) (less than a minute ago)

Note the Token .注意Token We've stored it in the ENV via heroku config, along with the app name:我们已经通过 heroku 配置将它与应用程序名称一起存储在 ENV 中:

$ heroku config:set HEROKU_API_TOKEN=12341234-1234-4234-1234-123412341234 HEROKU_APP_NAME=not-really-an-app

In our code we have the following method to restart the app via Heroku's API, using this API call :在我们的代码中,我们有以下方法通过 Heroku 的 API 重新启动应用程序,使用这个 API 调用

def restart!
  # Using puts to log output, replace with your logging system if needed
  puts `curl -v -s -n -X DELETE https://api.heroku.com/apps/#{ENV["HEROKU_APP_NAME"]}/dynos -H "Content-Type: application/json" -H "Accept: application/vnd.heroku+json; version=3" -H "Authorization: Bearer #{ENV["HEROKU_API_TOKEN"]}"`
end

Finally, as you're interested in automatic restarts every hour, the restart!最后,当您对每小时自动重启感兴趣时, restart! method above can be scheduled using Heroku's Scheduler , rufus-scheduler , as a Sidekiq job , or otherwise.上面的方法可以使用Heroku 的 Schedulerrufus-scheduler作为Sidekiq 作业或其他方式进行调度

Note: Heroku has some limits/timing logic around app restarts, mostly centered around dyno crashes.注意:Heroku 有一些关于应用程序重启的限制/时间逻辑,主要集中在 dyno 崩溃。 Reading the docs may help inform your app restart strategy.阅读文档可能有助于告知您的应用程序重启策略。

As far as I can tell, simply running heroku ps:restart --app APPNAME in the Heroku Scheduler add-on works fine.据我所知,只需在 Heroku Scheduler 附加组件中运行heroku ps:restart --app APPNAME就可以正常工作。 It's unclear to me why the additional steps in other answers are necessary.我不清楚为什么其他答案中的额外步骤是必要的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM