I started the sidekiq by
bundle exec sidekiq -d -L log/sidekiq.log -C config/sidekiq.yml -e production
Sometime, Sidekiq was crushed, busy=0 and enqueue > 0.
How can I setup the sidekiq to restart after crushed/stopped?
You can use some automated packages, or write your own bash script to do that.
I personally prefer writing my own scripts so let me explain that:
Write a script that executes sidekiq if not running already
Write a cronjob to execute that script every minute
Note that this method is not instant, meaning that you might have a downtime up to 1 minute, since the cronjob works every minute. So if your project is sensitive on that, you might want to use one of the process management tools such as monit or god.
Your bash script should contain your command,
bundle exec sidekiq -d -L log/sidekiq.log -C config/sidekiq.yml -e production
But make sure you are using absolute paths if you are going to store your script outside your project directory.
Here is a helpful topic about writing the shell script to check whether the process already exists.
To run the script every minute, do the following:
Go to your terminal
Type crontab -e
Append * * * * * /bin/bash -l -c 'cd /PATH/TO/YOUR/DIR && sh SCRIPTNAME.sh'
Save and exit editor
By doing this, you are telling your computer to execute your script every minute.
Usually people prefer writing only * * * * * /path/to/script.sh to their crontab but this fails in some circumstances.
Hope this helps.
Related
I am trying a cron task inside a container from host but with no luck. From the host I am adding the following line on crontab -e
* * * * * docker exec -it sample_container bash -c 'touch /selected/directory/temp$(date +%H-%M)'
But this is not working. Interestingly, when I run the command independently outside crontab it is successfully executing. Can anyone explain what am I missing here?
Note: when debugging such problems with cron, you should look for errors in your local system mails or redirect those to your real mail by adding MAILTO=yourmail#yourdomain.com on top of your crontab file.
There are 2 problems with your crontab command
TLDR; the fixed cron expression
* * * * * docker exec sample_container bash -c 'touch /selected/directory/temp$(date +\%H-\%M)'
% has a special meaning in crontab
From man -s 5 crontab
Percent-signs (%) in the command, unless escaped with backslash (\),
will be changed into newline characters, and all data after the
first % will be sent to the command as standard input.
So you will need to escape those % signs in your date format string
Cron does not allocate a tty
Cron does not allocate a tty whereas your are trying to use one when executing your command (i.e. the -t option to docker exec). The command will therefore fail with the error the input device is not a TTY
You do not need to go interactive (-i) nor to allocate a tty for this command to do its job anyway, so you have to drop those options to launch it from cron.
I have an application which relies heavily on delayed jobs. So I have setup two servers, one of which servers up the application (m3.medium ec2 instance) while other one runs my delayed jobs(t2.micro ec2 instance). I have created a start and stop script for the delayed jobs. This is where I am facing issues. Delayed jobs run smoothly but the problem is that they stop automatically after some time. So everytime they stop I have to manually start them again. I have no clue whatsoever why they stop in the middle of processing a job.
So basically I have two questions:
What can I do so that the jobs don't stop, or if they do they start automatically immediately/or after some time?
How can I make them start automatically on instance reboot/start?
I have looked at many similar questions, but none seem to help.
Any advice appreciated.
Edit 1:
My start/stop script for the delayed jobs.
set -e
# drop privs if necessary
if [ "$(id -u)" == "0" ]; then
exec su $(stat -c %U $(dirname $(readlink -f $0))/../config/environment.rb) -c "/bin/bash $0 $#"
exit -1;
fi
# switch to app root
cd $(dirname $(readlink -f $0))/..
# set up config
if [ -e "config/GEM_HOME" ]; then
export GEM_HOME=$(cat config/GEM_HOME)
fi
#export GEM_HOME=/path/to/gem/home
export RAILS_ENV=production
# run delayed jobs
exec script/delayed_job $#
# following an article I have tried adding the following code restart on crash.
# restarting the service
respawn
#Give up if restart occurs 10 times in 90 seconds.
respawn limit 10 90
Its seem you might be having memory issue which is killing it. you can try Monit to automatically start job if its killed
ref: http://railscasts.com/episodes/375-monit
Alternative:
You may also use sidekiq instead of delayed job
I'm using Ubuntu 14.04.4 LTS
Crontab:
SHELL=/bin/bash
#reboot ~/Projects/MyAPI/startworkers.sh;
startup script:
# /Projects/MyAPI/startworkers.sh
#!/bin/bash
source /home/server-linux/.bashrc
cd ~/Projects/LucyAPI
# Start background workers
bin/delayed_job --pool=tracking:2 --pool=emailverify:6 start
I expect there to be 6 delayed jobs running after reboot. However, none of them start. However, if I manually execute start.sh everything works as expected.
What am I doing wrong?
I think you might need a /bin/bash as part of the crontab and also the absolute path to the user home. Crontab example:
#reboot /bin/bash -l -c '/home/your_user_name/Projects/MyAPI/startworkers.sh'
I would also strongly recommend using the whenever gem to handle your crontab. You can find it here Whenever Gem
I followed the instruction on Whenever gems website, and tried following it in both development and on production mode on server.
set :output, "/file/to/path/cron.log"
every 1.day, at: '11:59 pm' do
command "sudo touch /file/to/path"
runner "Location.transfer_data",:environment => 'production'
end
It doesn't create the file(which is a test for now since I have no data on production).
I have spent hours trying to debug it and crontab -l gives me this output
59 23 * * * /bin/bash -l -c 'sudo touch /file/to/path >> /file/to/path/cron.log 2>&1'
59 23 * * * /bin/bash -l -c 'cd /var/www/name && script/rails runner -e production '\''Location.transfer_data'\'' >> /file/to/path/cron.log 2>&1'
Regards,
Babar Rehman
I solved the issue, don't know which one solved it in particular but these were the step that I took
Added job name to whenever --update-cron command
whenever --update-cron jobName
Restarted the cron service
sudo service cron restart
Gave full access rights to the log file
sudo chmod 777 /path/to/file.log
Hope it will come in handy for others
Hi I have to restart Apache from rails controller I tried to do that with %x{} and system commands but it fails so I decided to do it with cron Is it possible to make cron task that will be executed only once ?
The run once version of cron is called at. See http://en.wikipedia.org/wiki/At_%28Unix%29 for an explanation, and note that specifying "now" as the time causes it to run immediately.
To schedule a cron job to run only once is a bit tricky but can be done by a self deleting script! Schedule your script in the cron for the next minute or for other preferable time,
* * * * * /path/to/self-deleting-script
The self deleting script will be like,
#!/bin/bash
# <your job here>
crontab -l | grep -v $0 | crontab - # to delete your script from the cron
#restart your cron service
rm -f $0 #delete the script now
It solves my problem in an openwrt router where I could not install at command.