根据项目的进展,我们需要实现后台进行定时读取信息的功能,而最关键的实现部分是周期性功能,根据调研,决定使用whenever来实现这一功能。 
github:https://github.com/javan/whenever

开发前需要明确的问题

  • whenever是怎样一种周期性机制?
  • whenever能为我们提供什么功能?
  • whenever为周期性任务提供了哪些控制方式?

问题解决

whenever周期性机制

我们来看一下github上面是怎么说的:

Whenever is a Ruby gem that provides a clear syntax for writing and deploying cron jobs.

意思就是说,whenever是一个ruby gem,但同时它是基于cron jobs的。 
那么什么是cron jobs呢?我们来看一下维基百科的定义:

Cron 
crontab命令常见于Unix类Unix操作系统之中,用于设置周期性被执行的指令。该命令从标准输入设备读取指令,并将其存放于“crontab”文件中,以供之后读取和执行。该词来源于希腊语chronos(χρόνος),原意是时间。 
通常,crontab储存的指令被守护进程激活,crond常常在后台运行,每一分钟检查是否有预定的作业需要执行。这类作业一般称为cron jobs

也就是说,crontab是在unix和类unix系统中用来实现周期性功能的指令。在网上搜一下,我们就会看到很多crontab指令相关的语法。 
根据上述的分析,我们可以得出这样的结论: 
whenever事实上是一个cron翻译器,它将rails中的ruby代码翻译成cron脚本,从而将周期性的任务交给cron来执行。 这样,通过whenever我们可以使用ruby语言来写周期性任务代码,在ruby层控制代码,而不需要与shell脚本进行切换;另一方面,我们会发现,由于cron命令的强大,它的语法也因此变得很复杂,通过whenever,我们可以很方便的实现周期性任务。

whenever功能

从github中我们可以看到,我们用来实现定时功能的代码都已经集成在config/schedule.rb文件中了,以下为github中的whenever实例:

every 3.hours do
# 1.minute 1.day 1.week 1.month 1.year is also supported
runner "MyModel.some_process"
rake "my:rake:task"
command "/usr/bin/my_great_command"
end every 1.day, :at => '4:30 am' do
runner "MyModel.task_to_run_at_four_thirty_in_the_morning"
end every :hour do
# Many shortcuts available: :hour, :day, :month, :year, :reboot
runner "SomeModel.ladeeda"
end every :sunday, :at => '12pm' do
# Use any day of the week or :weekend, :weekday
runner "Task.do_something_great"
end every '0 0 27-31 * *' do
command "echo 'you can use raw cron syntax too'"
end # run this task only on servers with the :app role in Capistrano
# see Capistrano roles section below
every :day, :at => '12:20am', :roles => [:app] do
rake "app_server:task"
end

从上述实例中,我们可以看到whenever为我们提供的三种方法,runnerrakecommand,事实上,还有script方法也是whenever默认支持的。除了这四种方法外,wheneverr也提供自定义方法的功能,具体做法参照github上的方法来做即可。

whenever控制方法

whenever是十分亲民的,它的指令没有cron命令那么复杂。下面提供几种whenever比较常用的方法:

whenever (不带参数)将schedule.rb 文件中的周期性任务转化成cron命令显示出来,但不读取或者写入到crontab文件中
whenever -i [identifier] 更新新定时任务,默认更新 schedule.rb 文件中的全部
whenever -w, --write-crontab, --update-crontab, [identifier] 写定时任务,默认更新 schedule.rb 文件中的全部
whenever -c, --clear-crontab [identifier] 清除 crontab

除此之外,cron命令也是可以是用的,比较常用的是:

crontab -l [UserName]: 列出目前的时程表
crontab -e [UserName]: 执行文字编辑器(第一次由自己选择编辑器)来配置crontab的具体执行方法

一个十分简单的whenever demo

1.添加whenever(Gemfile)

gem 'whenever', :require => false

2.生成config/schedule.rb文件 
执行命令:

wheneverize

3.添加自己的周期性任务 
config/schedule.rb文件中添加:

set :environment, :development
every 2.minutes do
runner "Timetest.mytime"
end

其中,set :environment, :development是设置执行任务时的环境,默认情况下环境为production 
上述代码实现的是每两分钟读取当前时间并存入到数据库的功能。其中,runner方法执行的方法如下:

class Timetest < ApplicationRecord
def self.mytime
a = Timetest.new
a.time_now = Time.now
a.save
end
end

这样,在rails中实现whenever的代码就算是写完了,真的是简单到不行啊!(实在忍不住感慨一句) 
下面就要执行周期性任务了。

4.执行周期性任务 
在rails工程文件夹下进行一下操作

  • 更新schedule.rb中的任务到cronjob中
whenever -i

可以看到这样的打印结果:

[write] crontab file updated
  • 执行周期性任务
whenever -w

可以看到:

[write] crontab file written

此时我们的周期性任务便在后台运行了,此时查看我们的任务:

crontab -l

可以看到以下打印:

# Begin Whenever generated tasks for: /home/vito/rails/test_of_rails/test_rails/config/schedule.rb
0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58 * * * * /bin/bash -l -c 'cd /home/vito/rails/test_of_rails/test_rails && bundle exec bin/rails runner -e development '\''Timetest.mytime'\'''
# End Whenever generated tasks for: /home/vito/rails/test_of_rails/test_rails/config/schedule.rb

这样,我们的周期性任务就算是在顺利执行了。

需要注意的一点是运行时crontab的环境(rails和crontab环境不匹配时whenever无法执行),一般调试时多使用的是development环境,而不设置时默认的是production环境,如果你使用crontab -l发现是production环境,可以使用

crontab -e

直接修改为development,或者直接将-e production删掉即可。

经过上述流程,我们便可以成功地实现周期性任务了。如果此时你发现自己的周期性任务还是没有执行,那你就得好好看看你自己的任务代码了,很可能是执行的任务代码本身有问题,而与whenever的实现没有太大的关系了

Rails 定时任务——whenever实现周期性任务的更多相关文章

  1. 2018-01-08 学习随笔 SpirngBoot整合Mybatis进行主从数据库的动态切换,以及一些数据库层面和分布式事物的解决方案

    先大概介绍一下主从数据库是什么?其实就是两个或N个数据库,一个或几个主负责写(当然也可以读),另一个或几个从只负责读.从数据库要记录主数据库的具体url以及BigLOG(二进制日志文件)的参数.原理就 ...

  2. Android 线程池的类型、区别以及为何要用线程池

    每个 Android 应用进程在创建时,会同时创建一个线程,我们称之为主线程,负责更新 UI 界面以及和处理用户之间的交互,因此,在 Android 中,我们又称之为 UI 线程.一个进程中 UI 线 ...

  3. spider_keeper

    一 简介 spider_keeper 是一款开源的spider管理工具,可以方便的进行爬虫的启动,暂停,定时,同时可以查看分布式情况下所有爬虫日志,查看爬虫执行情况等功能. 二 安装 部署 安装环境 ...

  4. 一文说通Dotnet Core的后台任务

    这是一文说通系列的第二篇,里面有些内容会用到第一篇中间件的部分概念.如果需要,可以参看第一篇:一文说通Dotnet Core的中间件   一.前言 后台任务在一些特殊的应用场合,有相当的需求. 比方, ...

  5. 深入Netty逻辑架构,从Reactor线程模型开始

    本文是Netty系列第6篇 上一篇文章我们从一个Netty的使用Demo,了解了用Netty构建一个Server服务端应用的基本方式.并且从这个Demo出发,简述了Netty的逻辑架构,并对Chann ...

  6. python使用sched模块执行周期性任务和定时任务

    执行周期性任务 sched模块是一个通用的事件调度程序,可以对任务进行延迟调度,基于此,可以用它来实现周期性任务. # coding:utf8 import time import sched # 初 ...

  7. 关于windows服务器创建一个ps1脚本的周期性定时任务

    测试环境: Windows Server 2008 R2 Standard  & Windows Server 2012 R2 Standard 周期运行的ps脚本:Clean_up_Secu ...

  8. java关于Timer schedule执行定时任务 1、在应用开发中,经常需要一些周期性的操作,比如每5分钟执行某一操作等

    1.在应用开发中,经常需要一些周期性的操作,比如每5分钟执行某一操作等.对于这样的操作最方便.高效的实现方式就是使用java.util.Timer工具类. private java.util.Time ...

  9. ScheduledExecutorService周期性的定时任务

    从j2se的api文档上查看ScheduledExecutorService的方法都是推迟一段时间然后相隔一段时间之后再去执行,没有想Timer定时器一样的可以在定点时间执行的api,如果也想像Tim ...

随机推荐

  1. 书籍--嵌入式C语言

    1,C语言嵌入式编程修炼 [C/C++]C语言嵌入式编程修炼·背景篇·软件架构篇·内存操作篇

  2. ls -l 显示年份

    默认情况下ls -l命令只显示月和日,不显示年份: $ ls -llrwxrwxrwx 1 root root 7 Feb 27 16:12 bin -> usr/bin 如要要显示年份,就要使 ...

  3. (python)剑指Offer(第二版)面试题14:剪绳子

    题目 给你一根长度为n的绳子,请把绳子剪成m段 (m和n都是整数,n>1并且m>1)每段绳子的长度记为k[0],k[1],…,k[m].请问k[0]k[1]…*k[m]可能的最大乘积是多少 ...

  4. 用css以写代码形式画一个皮卡丘

    我的个人网站是通过写代码的形式来形成一个网站的,前一阵子在某个大神的github上看到他用写代码的形式来完成一个皮卡丘,于是心血来潮花了半个小时,也完成了一个作品. 这其中涉及到的知识点也不是很复杂, ...

  5. Python Cookbook(第3版)中文版:15.15 C字符串转换为Python字符串

    15.15 C字符串转换为Python字符串¶ 问题¶ 怎样将C中的字符串转换为Python字节或一个字符串对象? 解决方案¶ C字符串使用一对 char * 和 int 来表示, 你需要决定字符串到 ...

  6. 第二篇:使用Spark对MovieLens的特征进行提取

    前言 在对数据进行了初步探索后,想必读者对MovieLens数据集有了感性认识.而在数据挖掘/推荐引擎运行前,往往需要对数据预处理.预处理的重要性不言而喻,甚至比数据挖掘/推荐系统本身还重要. 然而完 ...

  7. 在laravel环境下将图片存入MongoDB数据库

    html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,bi ...

  8. [Luogu2444][POI2000]病毒

    Luogu sol 如果存在一个合法的无限长的串,那势必说明在\(AC\)自动机上存在一个合法的环.由此转化为判环,只要判断搜到的点是否已经在搜索栈中即可. code #include<cstd ...

  9. 圆方树简介(UOJ30:CF Round #278 Tourists)

    我写这篇博客的原因 证明我也是学过圆方树的 顺便存存代码 前置技能 双联通分量:点双 然后就没辣 圆方树 建立 新建一个图 定义原图中的所有点为圆点 对于每个点双联通分量(只有两个点的也算) 建立一个 ...

  10. 在Debian系列Linux系统Ubuntu上安装配置yum的试验

    用习惯了Red Hat系统的都知道我们习惯于三种安装方式:一种是rpm包的方式安装,一种就是tar包的方式来安装,还有一种方式就是yum源的安装. 首先rpm包的用法,我们一般是在Red Hat光驱里 ...