celery-redbeat方案(动态定时任务、异步任务)

2024-06-11 17:12

本文主要是介绍celery-redbeat方案(动态定时任务、异步任务),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

    • 为什么选择 RedBeat?
    • 方案
    • 坑事项记录

记一次工作上的问题

问题:项目上当前定时任务框架和服务端耦合,容易出现加载定时任务时间很长,影响后端服务启动,容易改动引发定时任务的问题。且能方便的动态的增加或删除定时任务而无需重启服务。
需求:将定时任务框架解耦,可以独立部署启动,不影响原来服务的功能,不会出现重复执行的定时任务和丢失定时任务
RedBeat是一个 Celery Beat 调度程序 ,它将计划任务和运行时元数据存储在Redis中。

为什么选择 RedBeat?

官方文档:https://redbeat.readthedocs.io/en/latest/intro.html
git仓库:https://github.com/sibson/redbeat

  1. 动态实时任务创建和修改,无需长时间停机
  2. 使用 Redis 绑定从任何语言外部管理任务
  3. 共享数据存储;Beat 不依赖于单个驱动器或机器
  4. 即使任务数量很多也能快速启动
  5. 防止意外运行多个 Beat 服务器
    用Celery-redbeat重构当前定时任务逻辑: Celery-redbeat是基于redis作为celery的中间件(broker)时的一个任务调度器(scheduler),有效提高调度器(scheduler)健壮性。

它最大的变化就是,它将调度器从原来Celery进程中的定时任务调度器(默认作为守护进程),改存在了Redis上。
因此,当任务创建或者发生变化的时候,调度器不再需要暂停和重载。利用Redis数据库的特性,我们只需要更新Redis中的键名,调度器就会随之发生改变。

方案

  1. 另起一个celery服务,不再跟随主服务启动
  2. 有一张数据库表用来针对动态定时任务做持久化存储以及做增删改查状态管理等。celery beat启动时会自动读取这张表的数据,将定时任务加载到redis中(每次会先清空再加载)
  3. 初始化完成后的redis数据, celery beat会根据redis里的scedule数据,如果满足执行条件,会将其推送到broker中,等待worker来消费
  4. 定时任务执行原理和之前可以保持一致,但不需要再往celery队列里插任务了,相当于直接执行celery队列中已有的任务,之前的锁逻辑还可以直接沿用
  5. 当用户对定时任务有任何更删改操作时,可以通过封装好的方法,先更新数据库中的值,然后直接更新redis中的值,从而同步更新队列中的定时任务,无需重启服务(此处需要保障数据库和redis的数据一致性,最后能有兜底or事务机制,要么都成功要么都失败)

坑事项记录

背景:发现线上服务会偶尔出现定时任务全部失效的情况,或者定时任务多次执行的情况
环境:k8s多pod部署服务来增加服务健壮性
分析线上日志,就是在某一个时间点突然报错:
LockNotOwnedError异常,表示无法释放或延长一个已经不再拥有的锁
所以一开始我们怀疑是redbeat存在bug,分析源码:
1、redbeat在启动时会触发 @beat_init.connect 装饰的 acquire_distributed_beat_lock 函数。使用 redis_client.lock() 方法创建一个分布式锁对象,通过 lock.acquire() 方法获取锁,此处会进行阻塞,直到成功获取到锁为止。最后,将获取到的锁对象赋值给调度器的 lock 属性。代码中生成的 time_task_:lock 锁用于在 Beat 启动时获取分布式锁,以实现在多个 Beat 进程或服务器之间协调任务调度的目的。这个锁对于 Beat 工作的用途是确保在分布式环境下只有一个 Beat 进程或服务器在执行任务调度。当多个 Beat 进程或服务器同时运行时,通过获取这个锁,只有获取到锁的进程或服务器可以执行任务调度,其他进程或服务器会被阻塞等待锁的释放。同时如果这个锁存在会给锁续期。(为了避免主进程 Readbeat 在执行任务时出现故障或长时间没有释放锁(例如进程崩溃、网络中断等情况),所以可能会有多个beat进程,虽然正常情况下永远只会有一个在工作。我们平台目前就只有一个beat服务)
2、然后Beat 服务会进入一个无限循环的进程,它会以一定的时间间隔进行轮询,检查是否需要执行任务。并且对time_task_:lock 锁进行续期。只有在进程终止时会释放

然后我们怀疑是,在某次续期时,这个锁会莫名其妙突然的消失,所以导致了报错问题
根据官方文档分析。time_task_:lock 锁仅仅是使用分布式锁来防止多个实例同时运行。我们当前仅设置一个实例服务,可以直接设置redbeat_lock_key = None关闭该功能。

本以为解决了问题,结果过了几天问题又再次出现,最后在偶然的灵机一动下发现
我们使用的k8s多pod服务,每个pod服务中的项目代码都是同一套一样的(不管是server还是celery还是beat),发现如果某个pod重启了,会将前面方案中的第二点中的预加载init函数(为了重置所有定时任务,防止异常数据残留)执行一次,就是会清空redis关于redbeat的数据然后重新加载数据,这就导致了所有数据和锁消失了~~

这篇关于celery-redbeat方案(动态定时任务、异步任务)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1051786

相关文章

防止Linux rm命令误操作的多场景防护方案与实践

《防止Linuxrm命令误操作的多场景防护方案与实践》在Linux系统中,rm命令是删除文件和目录的高效工具,但一旦误操作,如执行rm-rf/或rm-rf/*,极易导致系统数据灾难,本文针对不同场景... 目录引言理解 rm 命令及误操作风险rm 命令基础常见误操作案例防护方案使用 rm编程 别名及安全删除

Linux下MySQL数据库定时备份脚本与Crontab配置教学

《Linux下MySQL数据库定时备份脚本与Crontab配置教学》在生产环境中,数据库是核心资产之一,定期备份数据库可以有效防止意外数据丢失,本文将分享一份MySQL定时备份脚本,并讲解如何通过cr... 目录备份脚本详解脚本功能说明授权与可执行权限使用 Crontab 定时执行编辑 Crontab添加定

Java使用Javassist动态生成HelloWorld类

《Java使用Javassist动态生成HelloWorld类》Javassist是一个非常强大的字节码操作和定义库,它允许开发者在运行时创建新的类或者修改现有的类,本文将简单介绍如何使用Javass... 目录1. Javassist简介2. 环境准备3. 动态生成HelloWorld类3.1 创建CtC

Python实现批量CSV转Excel的高性能处理方案

《Python实现批量CSV转Excel的高性能处理方案》在日常办公中,我们经常需要将CSV格式的数据转换为Excel文件,本文将介绍一个基于Python的高性能解决方案,感兴趣的小伙伴可以跟随小编一... 目录一、场景需求二、技术方案三、核心代码四、批量处理方案五、性能优化六、使用示例完整代码七、小结一、

C#使用Spire.Doc for .NET实现HTML转Word的高效方案

《C#使用Spire.Docfor.NET实现HTML转Word的高效方案》在Web开发中,HTML内容的生成与处理是高频需求,然而,当用户需要将HTML页面或动态生成的HTML字符串转换为Wor... 目录引言一、html转Word的典型场景与挑战二、用 Spire.Doc 实现 HTML 转 Word1

使用Python实现Word文档的自动化对比方案

《使用Python实现Word文档的自动化对比方案》我们经常需要比较两个Word文档的版本差异,无论是合同修订、论文修改还是代码文档更新,人工比对不仅效率低下,还容易遗漏关键改动,下面通过一个实际案例... 目录引言一、使用python-docx库解析文档结构二、使用difflib进行差异比对三、高级对比方

SpringBoot集成XXL-JOB实现任务管理全流程

《SpringBoot集成XXL-JOB实现任务管理全流程》XXL-JOB是一款轻量级分布式任务调度平台,功能丰富、界面简洁、易于扩展,本文介绍如何通过SpringBoot项目,使用RestTempl... 目录一、前言二、项目结构简述三、Maven 依赖四、Controller 代码详解五、Service

Python异步编程之await与asyncio基本用法详解

《Python异步编程之await与asyncio基本用法详解》在Python中,await和asyncio是异步编程的核心工具,用于高效处理I/O密集型任务(如网络请求、文件读写、数据库操作等),接... 目录一、核心概念二、使用场景三、基本用法1. 定义协程2. 运行协程3. 并发执行多个任务四、关键

Linux系统管理与进程任务管理方式

《Linux系统管理与进程任务管理方式》本文系统讲解Linux管理核心技能,涵盖引导流程、服务控制(Systemd与GRUB2)、进程管理(前台/后台运行、工具使用)、计划任务(at/cron)及常用... 目录引言一、linux系统引导过程与服务控制1.1 系统引导的五个关键阶段1.2 GRUB2的进化优

Python多线程应用中的卡死问题优化方案指南

《Python多线程应用中的卡死问题优化方案指南》在利用Python语言开发某查询软件时,遇到了点击搜索按钮后软件卡死的问题,本文将简单分析一下出现的原因以及对应的优化方案,希望对大家有所帮助... 目录问题描述优化方案1. 网络请求优化2. 多线程架构优化3. 全局异常处理4. 配置管理优化优化效果1.