手把手带你写一个 Web 框架
叶剑峰
腾讯高级工程师,前滴滴技术专家
22731 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 42 讲
特别放送 (1讲)
手把手带你写一个 Web 框架
15
15
1.0x
00:00/00:00
登录|注册

14|定时任务:如何让框架支持分布式定时脚本?

cron list
cron restart
cron state
cron stop
支持两种启动方式:挂起进程和后台deamon方式
启动cron常驻进程
支持秒级别的定时
支持丰富的时间描述语言
cron.New创建cron实例
遍历所有的定时任务,计算下一次执行时间
监听计时器中的事件
time.NewTimer初始化计时器
实现其他几个cron命令
实现分布式定时器的功能
使用cron包实现定时执行命令
为Command结构增加AddDistributedCronCommand方法
实现本地文件锁的分布式选择器
定义分布式服务接口
启动cron的思路与实现
使用cron包定时执行命令
使用timer定时执行命令
思考题
小结
如何实现分布式定时器
定时命令的思路与实现
框架支持分布式定时脚本
定时任务

该思维导图由 AI 生成,仅供参考

你好,我是轩脉刃。
上一节课,我们改造框架让它支持命令行工具了。这样业务开发者可以使用框架定义好的命令行工具来执行框架预设的一些行为,比如启动一个 Web 服务,也可以自己定义业务需要的命令行工具来执行业务行为,非常方便。
今天继续思考如何优化,因为业务在开发过程中,不可能每个命令都要手动操作,定时执行某个命令的需求应该是非常普遍的。比如设计一个定时扫描数据命令来发送统计报告,或者设计一个定时删除某些过期数据的命令。
那我们的框架是否能支持这个需求,如果要开发一个定时命令,能不能做到在业务中增加一行代码就行了?这节课我们就来挑战这个目标。

使用 timer 定时执行命令

怎么做到计时执行这个事情呢?Golang 有个标准库 time,里面提供一个计时器 timer 的结构,是否可以使用这个 timer 来执行呢?我们先来看看 timer 是怎么使用的:
func main() {
timer := time.NewTimer(3 * time.Second) // 定一个计时器,3s后触发
select {
now <-timer.C: // 监听计时器中的事件
fmt.Println("3秒执行任务, 现在时间", now) //3s后执行
}
}
首先 time.NewTimer 会初始化一个计时器,这个计时器到定时时间后,就从 C 这个 channel 中返回一个时间 Time。逻辑很简单。所以我们的 main 函数只需要监听 timer.C 这个 channel,一旦有时间从这个 channel 中出来,就说明到计时器时间了。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入介绍了分布式定时任务框架的实现方法及相关技术思路。首先介绍了使用Golang标准库中的timer和开源的cron库来实现定时执行命令的方法,展示了cron库丰富的时间描述语言和秒级别定时的能力。随后详细讨论了如何将cron库应用在hade框架中,实现了一行代码就能定时执行某个命令的目标。文章还介绍了cron的初始化和回调,以及启动cron的思路与实现。此外,还讨论了分布式选择器的实现方式,以及如何使用本地文件锁进行分布式选举。最后,通过示例验证了框架的分布式定时任务功能,展示了其容灾性和高可用性。整体而言,本文以技术实现为主线,深入浅出地介绍了定时任务的思路与实现,对读者快速了解分布式定时脚本的实现方式具有指导意义。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《手把手带你写一个 Web 框架》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(14)

  • 最新
  • 精选
  • www
    置顶
    跟到现在冒个泡,写得很详细,心都掏出来了,大赞
    2021-11-02
    4
  • qinsi
    疑问:linux cron 命令会把任务写入 crontab 文件,而这里的代码似乎没有存储cron任务,所以cron任务其实是写死在app里并从命令行启动的?这样似乎会带来一些额外的开发和运维工作,比如需要新增和修改cron任务时就需要升级app并重新部署。 在分布式调度cron任务时还会有个问题,在同一个环境中启动多个app实例去抢占执行cron任务的话就只会记下最后一个pid,那么那些管理cron任务的子命令就都失效了。所以分布式调度必然意味着需要分布式部署?

    作者回复: 第一个问题,是的,cron是写在app里面运行的,每次升级cron需要升级app。第二个问题是存在这样问题,这个之前没考虑到,同一个目录启动多个实例。标准办法应该是每个实例启动一个runtimefolder,把runtimefolder从环境变量中传递进去才行

    2021-10-18
    2
  • 清睿夕
    一个节点是一台服务器还是运行一次程序就是一个节点,多个节点怎么

    作者回复: 多个节点即可以是一个服务器一个,也可以是多个进程。不过一般现在容器化这么普遍的情况,基本上一个节点在实际上上一个pod的概念

    2021-10-20
    1
  • Geek_b6655a
    for _, entry := entries { entry.Next = next(entry) } 这段代码, entries前面少了一个range进行遍历吧吧

    作者回复: 是的,感谢留言。已联系小编修改中

    2022-08-05归属地:北京
  • 这篇太干货了 看了半天

    作者回复: 感谢

    2021-12-09
  • woJA1wCgAAxrBgpYJOnLFfx5VBLZeS...
    分布式文件锁不是存在多个独立运行环境上吗,为何是通过抢占文件来做select呢?这似乎是单机多进程。
    2022-04-16
    2
  • Geek_bda8af
    学了两天 可算搞明白了 感谢~!
    2022-06-03
    1
  • 宙斯
    fork和os.StartProcess没看出来,选择哪个更好,也就是意味着选择这二者其一都可以。
    2021-10-26
    1
  • Jackkee
    请问Windows环境下,是不能用syscall.Kill()这个方法吗
    2022-10-05归属地:福建
  • 牛玉富
    一如既往的干货 分布式任务下应该注意,时间保持一致,不然应该会有重复任务执行情况。
    2022-01-13
收起评论
显示
设置
留言
14
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部