70

JTimer:crontab 的替代品,工程师的福音

 5 years ago
source link: http://www.10tiao.com/html/146/201806/2650081956/2.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.


作为程序员,在日常工作中免不了与各种任务打交道,有一些任务的执行是具有重复性质的,比如工作人员每天登录系统之后进行一系列基础操作:


(1)先确认一下系统时间

(2)查看之前登录的用户

(3)再打开某个监控日志


……这些操作基本上是固定项目,每次一登录就需要一个一个地执行,那么,如何节省工程师宝贵的时间,把这些操作捆绑起来,只通过一次输入就全部执行呢?在 Unix/Linux 环境下,shell 脚本出现了,它负责处理批量任务,类似于 Windows 环境下的批处理 .bat 文件,都是按照先后顺序,依次执行文件中的每一个任务条目。


而再进一步,工程师又想让任务能够定时自动执行,不必等到每次想让任务执行时再操作,大名鼎鼎的 crontab 工具就满足了他们的愿望。crontab 是 Linux 下的一个与 Windows 下的计划任务类似的命令,它被用来管理用户需要周期性执行的任务,由守护进程 crond 驱动,crond 定期检查是否有任务需要执行,如果有那么就执行相应任务。更具体一点,通过 crontab 命令参数与相应格式的设置,它能够做到对定时任务进行按需管理。


然而,还是有追求极致体验与性能的开发者不够满意 crontab,他们非要自己改造/创造一个新的替代工具,以适应自己的工作方式。本次采访嘉宾周君就开发了一个号称 crontab 替代品的 JTimer,我们请他分享了 JTimer 的开发背景与相关技术细节。


1、定时任务具体是指什么?定时任务管理是什么?介绍一下整个工作场景。


定时任务是指在用户指定的时间点执行用户指定的任务。而随着业务的增加与变动,定时任务常常需要修改,定时任务的管理就是对定时任务的 CRUD 等操作。


大多数业务系统都会有使用定时任务的需求,以此来代替人工的驻守与繁琐的重复操作,例如某系统有每天生成业务报表的需求,但是由于数据量过于庞大,为了避免对生产环境用户造成影响,应选择在凌晨访问量较少时执行生成报表的操作,定时任务不仅节省了人力,免去了人工可能导致的“忘了执行任务”的尴尬场面,也能让开发人员不用半夜起床工作。


2、一个定时任务管理器的优劣主要可以从哪些方面考量?


通常,我们对定时任务管理器的要求最主要的考量有以下两方面:


  • 定时器的稳定性、高可用性

  • 管理上的便捷性


第一点考量是最为重要的,定时任务是按时执行用户指定的业务任务,定时器的不稳定、延迟与宕机等问题都可能直接影响用户的业务,严重的甚至导致公司的经济损失。


至于上述的第二点考量,对运维和开发人员来说是一个痛点,如果管理不够便捷,那么也会严重影响到工程师的效率。


3、JTimer 号称 crontab 的替代品,那么与之相比,JTimer 有什么优势?二者还有哪些异同?


crontab 是开发人员耳熟能详的知名定时任务工具,也是业内目前最优秀的同类产品,但是在使用 crontab 的过程中也有许多不便之处:


  • 编辑任务时需要登录服务器,需要使用 vim 操作,虽然这对于开发人员和运维人员来说不是什么大问题,但是相对于使用 Web 界面操作来说还是麻烦了不少,如果能够使用 Web 界面可视化来操作,那会更加便捷与高效。

  • crontab 的定时只支持到分钟级别,而 JTimer 支持到秒级。

  • 在管理任务时,crontab 不支持分类管理,需要我们自己人为的分类,当任务数量很多时会显得有些杂乱,管理上略有不便。

  • 有时候我们需要查询任务的执行日志,而 crontab 的执行日志存放在一个日志文件中,我们无法快速并且直观的筛选中我们想要的内容。

  • 当有多台服务器需要部署或修改任务时,需要同时修改相应服务器配置。


JTimer 就是因为在使用 crontab 的过程中发现了这些不足,所以才研发出来的,那它的优势就很明显了。JTimer 的目的是提供更快速便捷的任务管理方式,以及任务日志的快速搜索。这是 JTimer 的优势和存在的意义,也是 JTimer 和 crontab 最大的不同之处。


JTimer 使用 Web 界面,让操作更加便捷、高效,下图展示了其管理页面:


任务列表:



编辑任务:



任务分类:



任务执行日志,可条件查询:



系统设置(Java 版暂无验证码与 ip 限制功能):



自动清除旧日志:



4、JTimer 的架构是怎么样的?工作流程又是怎么样的?


JTimer 可以大致分为两个模块,一是任务的管理模块,二是任务执行模块。


JTimer 分为 Java 版和 PHP 版,两者从管理模块上来说几乎完全一样,都提供了定时任务的 CRUD 和执行日志查询等功能,连 UI 都基本一致,不同之处在于任务执行模块的架构和实现机制。


JTimer for PHP


PHP 版任务执行模块使用了经典的 master-worker 进程模型。



  • 有1个 master 进程负责监控整个系统的运行,保证所有进程的高可用。

  • 有2个 worker 进程,其中一个负责监控任务的变化,另一个 worker 是一个定时器,负责任务的调度工作(使用了时间轮的算法),一旦有任务需要执行,就将任务传递给 task 进程执行,worker 本身不涉及任务的具体执行。两个 worker 之间以 tp 框架自带的文件缓存作为沟通的桥梁。

  • n个 task 进程,负责任务的具体执行。


JTimer for Java


从工作流程上来说,Java 版和 PHP 版相差不多,只是具体的实现方式上不同。PHP 版使用的是多进程,而 Java 版使用的多线程:


  • 两个线程,分别对应 PHP 版的的两个 worker,工作职责与 worker 一样。

  • 任务的调度使用了 Spring 框架 CronTrigger。

  • 任务的具体执行使用了 Java 原生的 Runtime.getRuntime().exec(),该方法本身是多进程方式执行任务,因此不需要我们参与进程的管理。


PHP 版与 Java 版相比较,Java 版在实现上大部分是使用了 Java 和 Spring 为我们提供的能力,因此较为简单。而 PHP 在这方面较为薄弱,无论是多进程方面还是定时器方面,都需要我们自己动手去实现,开发起来也复杂不少。


5、在 JTimer 研发的过程中,遇到的主要难点是什么?踩过什么坑?


开发 JTimer 的 PHP 版,从技术上来说并不难,并没有遇到太多困难。但在测试中遇到过一个问题,用了好几天才找到问题所在,下边简单讲一讲。


当时 JTimer 已经发布,有一位网友使用了 JTimer,但是在使用中,发现任务会被遗漏。例如有一个任务是每小时执行一次(整点执行),正常情况下一天会执行24次,但是实际上会被随机的遗漏掉1-2次,一天只执行了22或23次。


当这位网友把问题反馈给我之后,我查看了我这边的测试服务器上的 JTimer,却没有发现这个问题。后来这位网友说他的两台服务器,一台 CentOS 没有发现这个问题,一台 Ubuntu 却有这个问题。一开始我们以为是环境问题,排查了好几天,后来才发现是定时器的 bug。


导致 bug 的原因是:假设现在的时间是 00:00:00,当代码执行到“判断当前是否有任务需要执行”时,时间已经跳到 00:00:01 秒,导致判断错误,本应该在 00:00:00 执行的任务没有执行。


后来我解决这个问题的方法是在自己定义一个时钟,程序启动时获取当前时间戳保存下来,然后每秒加1。在要用到时间时都使用自己定义的这个时钟,而不用系统时间,这样就避免了时间差导致的任务丢失问题。


但是这样又产生了一个新的问题,理论上自定义的时钟和系统时间应该是一致的,但实际上每一秒会产生零点零零几毫秒的误差,累计下来几个小时就会产生一秒的误差。想要解决这个问题只能重构整个任务调度功能,该问题暂时还没有解决。不过仅 PHP 版有该问题,如果时间误差会影响业务,建议使用 Java 版。


6、目前在生产环境中使用该项目了吗?效果如果?或者测试效果如何?


目前已经有一个网友在生产环境中使用了 JTimer 的 PHP 版本,从效果上来说,除了上面所说的时间问题(Java 版没有该问题),暂时还没有发现别的问题。同时在此要感谢这位网友,在测试过程中帮我发现了一些问题(就是上个问题提到的网友)。


而从我自己的测试效果上来说,已经基本达到可以上线生产环境的标准。但毕竟测试样本太少,也许有尚未发现的 bug,广大开发者们在使用 JTimer 的过程中如果发现问题,希望能够反馈给我,帮助完善 JTimer。


7、介绍一下项目接下来的计划。


到目前为止项目的进展已经基本告一段落,并没有计划开发新的功能。JTimer 诞生的初衷是解决 crontab 管理不便的问题,该目的已经达到,我不希望将 JTimer 发展成一个庞大臃肿的项目,保持单一功能,能够解决同行们的痛点就够了。


不过前面提到的 PHP 版时间误差的问题仍需要解决的,这也是接下来唯一的计划,虽然 Java 版无此问题,但我还是希望能将 PHP 版做得更完美一些。同时,如果有意参与 JTimer 开发的开发者对它的发展有什么好的想法,也欢迎大家一起交流。


项目详情及源码地址获取:



嘉宾介绍

周君,资深后端工程师,博客作者,精通 PHP、Java、Web开发。多年实战经验,热衷分享。


开源中国征稿开始啦!


开源中国 www.oschina.net 是目前备受关注、具有强大影响力的开源技术社区,拥有超过 200 万的开源技术精英。我们传播开源的理念,推广开源项目,为 IT 开发者提供一个发现、使用、并交流开源技术的平台。


现在我们开始对外征稿啦!如果你有优秀的技术文章想要分享,热点的行业资讯需要报道等等,欢迎联系开源中国进行投稿。投稿详情及联系方式请参见:我要投稿




推荐阅读

Kotlin 威胁、Python 逆袭,2018 年程序员需要升级哪些技能?

Fuchsia 操作系统将支持运行 Linux 应用程序

遭 Airbnb 嫌弃,React Native 还值得我们使用吗?

腾讯成为 Linux 基金会白金会员,贡献两大自研项目

Github 用户喊话微软:放弃 ICE 吧,不然会失去我们的

点击“阅读原文”查看更多精彩内容

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK