前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >celery执行的任务老是错误,让人头疼?这时候就要上错误重试!

celery执行的任务老是错误,让人头疼?这时候就要上错误重试!

作者头像
Devops海洋的渔夫
发布2022-01-17 11:15:56
2.1K0
发布2022-01-17 11:15:56
举报
文章被收录于专栏:Devops专栏

前言

前一篇内容我介绍了执行耗时任务的神器celery,但是感觉还是缺点料,本篇章再来继续深入讲诉以及介绍一下celery执行任务的错误重试机制。

存在的现象

我在最近开发平台的时候需要使用celery多次频繁并发使用paramiko库进行ssh远程命令执行调用。

在执行的过程中,主控服务器在百度云,远程调用阿里云的服务器是很OK的,暂时没有发现什么错误,一路任务顺畅执行,一点错误都没。

但是当我远程调用腾讯云服务器的时候,总会偶尔出现一些报错的情况,这就让我很纠结郁闷了。

因为这是最底层的调用方式,而我解决这种报错情况的方式是改用ansible进行执行,并且将多个执行shell命令写成脚本进行一次性调用。

将多次并发的远程调用尽量合并一次性执行,将shell执行的错误返回进行处理。

尽管做了那么多的改动以及优化,任务依然会出现ssh访问被偶尔阻止的情况,这时候就只能上这个错误重试了。

本次说明,我采用的是发送邮件错误的情况作为示例,如下:

在异步调用任务中经常需要调用第三方的api请求,如果一次执行失败,则应该进行重试执行。否则,如果在执行一些连续性的chain链条任务,前面执行失败,那么后续的也就不用执行了。

下面来看看一个发送邮件失败,然后重试执行的示例。

Celery任务的文档结构

错误重试示例

故意将邮件服务的地址配置错误

为了做到错误的演示,我首先将发送邮件的smtp地址写错,如下:

那么稍后执行发送邮件的时候,就一定会报找不到smtp的错误。

编写错误重试的task任务

代码语言:javascript
复制
# 定义任务函数
@celery_app.task(bind=True)
def send_register_active_email(self,to_email, username, token):
    '''发送激活邮件'''
    # 组织邮件信息
    subject = '欢迎信息'
    message = ''
    sender = settings.EMAIL_FROM
    receiver = [to_email]
    html_message = '<h1>%s, 欢迎您成为xxx注册会员</h1>请点击下面链接激活您的账户<br/><a href="http://127.0.0.1:8000/user/active/%s">http://127.0.0.1:8000/user/active/%s</a>' % (username, token, token)

    print("=========== 执行发送邮件 ===============")

    try:
        send_mail(subject, message, sender, receiver, html_message=html_message)
    except Exception as e:
        """
                邮件发送失败,使用retry进行重试

                retry的参数可以有:
                    exc:指定抛出的异常
                    throw:重试时是否通知worker是重试任务
                    eta:指定重试的时间/日期
                    countdown:在多久之后重试(每多少秒重试一次)
                    max_retries:最大重试次数
                """
        raise self.retry(exc=e, countdown=3, max_retries=5)

该示例任务将会进行调用发送邮件,当发生错误后,间隔3秒则重试执行一次,总共5次。可以通过print的打印信息来确认重试的次数。

启动celery任务

windows启动命令:

代码语言:javascript
复制
celery -A celery_tasks worker -l info -P eventlet

linux启动命令:

代码语言:javascript
复制
celery -A celery_tasks worker -l info

执行celery任务

启动完毕celery之后,那么下面进行交互模式进行测试,执行如下:

代码语言:javascript
复制
In [1]: from celery_tasks.tasks import send_register_active_email

In [2]: to_email = 'lijw@******.cn'

In [3]: token = '123456'

In [4]: username = 'lijw'

In [5]: send_register_active_email.delay(to_email,username,token)
Out[5]: <AsyncResult: 02deebc0-5d64-43f9-9ad5-5ccfe260ec70>

执行完毕任务后,查看celery的执行日志,如下:

代码语言:javascript
复制
[2019-10-21 14:01:09,508: INFO/MainProcess] celery@junwei1 ready.
[2019-10-21 14:01:09,509: INFO/MainProcess] pidbox: Connected to redis://127.0.0.1:6379/8.
[2019-10-21 14:01:14,353: INFO/MainProcess] Received task: celery_tasks.tasks.send_register_active_email[7b921776-f6a6-4da0-9c71-b04aac0d139a]

# 任务第一次执行,然后执行失败
[2019-10-21 14:01:14,354: WARNING/MainProcess] =========== 执行发送邮件 ===============
[2019-10-21 14:01:15,311: INFO/MainProcess] Received task: celery_tasks.tasks.send_register_active_email[7b921776-f6a6-4da0-9c71-b04aac0d139a]  ETA:[2019-10-21 06:01:18.21
8857+00:00]
[2019-10-21 14:01:15,345: INFO/MainProcess] Task celery_tasks.tasks.send_register_active_email[7b921776-f6a6-4da0-9c71-b04aac0d139a] retry: Retry in 3s: gaierror(11001, 'N
o address found')

# 当执行错误之后,下面则会重试执行5次任务,直到成功,或者失败
[2019-10-21 14:01:18,224: WARNING/MainProcess] =========== 执行发送邮件 ===============
[2019-10-21 14:01:18,253: INFO/MainProcess] Received task: celery_tasks.tasks.send_register_active_email[7b921776-f6a6-4da0-9c71-b04aac0d139a]  ETA:[2019-10-21 06:01:21.22
5853+00:00]
[2019-10-21 14:01:18,265: INFO/MainProcess] Task celery_tasks.tasks.send_register_active_email[7b921776-f6a6-4da0-9c71-b04aac0d139a] retry: Retry in 3s: gaierror(11001, 'N
o address found')
[2019-10-21 14:01:21,227: WARNING/MainProcess] =========== 执行发送邮件 ===============
[2019-10-21 14:01:21,255: INFO/MainProcess] Received task: celery_tasks.tasks.send_register_active_email[7b921776-f6a6-4da0-9c71-b04aac0d139a]  ETA:[2019-10-21 06:01:24.22
8790+00:00]
[2019-10-21 14:01:21,264: INFO/MainProcess] Task celery_tasks.tasks.send_register_active_email[7b921776-f6a6-4da0-9c71-b04aac0d139a] retry: Retry in 3s: gaierror(11001, 'N
o address found')
[2019-10-21 14:01:24,243: WARNING/MainProcess] =========== 执行发送邮件 ===============
[2019-10-21 14:01:24,280: INFO/MainProcess] Received task: celery_tasks.tasks.send_register_active_email[7b921776-f6a6-4da0-9c71-b04aac0d139a]  ETA:[2019-10-21 06:01:27.24
4729+00:00]
[2019-10-21 14:01:24,291: INFO/MainProcess] Task celery_tasks.tasks.send_register_active_email[7b921776-f6a6-4da0-9c71-b04aac0d139a] retry: Retry in 3s: gaierror(11001, 'N
o address found')
[2019-10-21 14:01:27,245: WARNING/MainProcess] =========== 执行发送邮件 ===============
[2019-10-21 14:01:27,271: INFO/MainProcess] Received task: celery_tasks.tasks.send_register_active_email[7b921776-f6a6-4da0-9c71-b04aac0d139a]  ETA:[2019-10-21 06:01:30.24
6720+00:00]
[2019-10-21 14:01:27,281: INFO/MainProcess] Task celery_tasks.tasks.send_register_active_email[7b921776-f6a6-4da0-9c71-b04aac0d139a] retry: Retry in 3s: gaierror(11001, 'N
o address found')
[2019-10-21 14:01:30,261: WARNING/MainProcess] =========== 执行发送邮件 ===============
[2019-10-21 14:01:30,279: ERROR/MainProcess] Task celery_tasks.tasks.send_register_active_email[7b921776-f6a6-4da0-9c71-b04aac0d139a] raised unexpected: gaierror(11001, 'N
o address found')
Traceback (most recent call last):
  ....
    raise socket.gaierror(socket.EAI_NONAME, 'No address found')
socket.gaierror: [Errno 11001] No address found

可以看到,上面的日志中的打印信息。第一次执行任务,则发送了一次报错。随后一直重试执行了5次都报错,说明重试的5次是从第一次执行失败后计算的。

好了,大概celery错误重试的机制大概就是如此。后续,我会继续尽量将工作中碰到的问题,以及解决的方法抛出来进行分享,谢谢。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-07-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 海洋的渔夫 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 存在的现象
  • Celery任务的文档结构
  • 错误重试示例
    • 故意将邮件服务的地址配置错误
      • 编写错误重试的task任务
        • 启动celery任务
          • 执行celery任务
          相关产品与服务
          云服务器
          云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档