Celery 的学习笔记--tornado异步开发的好朋友<二>

本文详细介绍了如何在Tornado中使用Celery,包括基础使用、进阶特性如回调、特殊变量、序列化以及配置。特别强调了如何实现任务间的链接、重试策略和不同序列化方式的使用,以及Celery的基本配置,帮助开发者掌握高效任务调度与管理技巧。

1.在tornado 中 使用 Celery

2.Celery的进阶


2.1回调

官方文档中把回调称为linking tasks。和回调差不多一个意思。这个回调怎么用呢,请看下面例子。

这个link就相当于tornado中的callback了

add.apply_async((2,2),link = add.s(16))

这个函数返回的值为20,这个20怎么来呢?

其实就是先执行第一个任务add(2,2) ,第一个任返回的结果传递给回调函数,然后add(4,16).最后就的好20了。这个例子很简单,

不过这个例子有个疑问—add.s(16),这个s是怎么回事?突然出现这个s,而且以前没有见过啊。

官网canvas guide里有说明的,这个咱们简单的学习一下。

>>>add.subtask((2, 2), countdown=10)
tasks.add(2, 2)

>>>add.s(2, 2)
tasks.add(2, 2)

add.s()就相当于subtask()方法,等于它的简写。


特殊变量

EAT(estimated time of arrival) 预计到达时间

result = add.apply_async((2, 2), countdown=3)
#我们通过countdown变量设置它
result.get()   
4

那么这个变量的作用是什么呢?我们可以给这个参数设定一个特殊的日期(date)或者时间(time),那么在这个时间内这个函数是不会返回结果的。上面那个例子代表我们至少需要等待3秒才能得到返回结果。


Message Sending Retry

celey将会在事件连接的失败时候自动重新连接,通过设置retry变量可以控制是否重新连接。比如retry=False表示连接失败后不重连。

不过还有更高级的配置

add.apply_async((2, 2), retry=True, retry_policy={
    'max_retries': 5,
    'interval_start': 0,
    'interval_step': 0.2,
    'interval_max': 0.8,
})
  • max_retries :最大重连次数,设为None表示无限次数的重连。
  • interval_start:第一次两次重连的等待时间,单位秒,默认为0
  • interval_max:重连登台时间 的最大值默认0.2
  • nterval_step:重连时间增量的步长,默认0.2

    刚才的例子里重连的间隔从0开始,每次增长0.2s,当间隔到带0.8的时候就不增长了。
    Serializers
    worker 返回来内容的格式。默认为pickle python有专门的包。
    不过我们可是设置 json,pickle,ymal,msgpack。

 add.apply_async((10, 10), serializer='json')

不过每调用一次都要设置它不是很麻烦么,我们可以定义celery设在它。这样就不必每次都设置了。
通过CELERY_TASK_PUBLISH_RETRY 就可以了。
所有的设这内容都在这里了


3.celery的配置(Configuration)


不过一般情况下我们不必对Celery进行配置哈,如果你有啥特殊的要求的话就需要了解这一方面了。

怎么配置


配置的格式(等号连接)

## Broker settings.
BROKER_URL = 'amqp://guest:guest@localhost:5672//'

# List of modules to import when celery starts.
CELERY_IMPORTS = ('myapp.tasks', )

## Using the database to store task state and results.
CELERY_RESULT_BACKEND = 'db+sqlite:///results.db'

CELERY_ANNOTATIONS = {'tasks.add': {'rate_limit': '10/s'}}

配置单个条目

app.conf.CELERY_TASK_SERIALIZER = 'json'

要配置多个

app.conf.update(
    CELERY_TASK_SERIALIZER='json',
    CELERY_ACCEPT_CONTENT=['json'],  # Ignore other content
    CELERY_RESULT_SERIALIZER='json',
    CELERY_TIMEZONE='Europe/Oslo',
    CELERY_ENABLE_UTC=True,
)

常用的配置选项


CELERY_RESULT_BACKEND
这里写图片描述

### 回答问题 你遇到的错误是: ``` Error response code! error message: Gateway Time-out, details: "<html>...<h1>504 Gateway Time-out</h1>...</html>" ``` --- ### ✅ 错误类型:HTTP 504 Gateway Timeout(网关超时) 这是一个 **服务器端代理层返回的错误**,表示: > **作为网关或代理的服务器(这里是 Nginx)在等待上游应用服务器响应时,超过了允许的时间,于是主动中断并返回了 504。** --- ### 🔍 详细解释 #### 📌 报错关键信息: - `504 Gateway Time-out`:不是后端程序抛出的异常,而是 **Nginx 层面** 检测到后端没及时响应。 - `<center>nginx</center>`:明确说明这是由 Nginx 返回的页面。 - 响应体中的“padding”是为了防止 Chrome/IE 显示友好错误页而故意加长内容。 --- ### ❓ 可能原因分析 | 原因 | 说明 | |------|------| | 1. 后端服务处理时间过长 | 请求的接口逻辑复杂、数据库查询慢、外部调用阻塞等导致响应超过 Nginx 超时限制。 | | 2. 应用服务器无响应或崩溃 | Python 服务(如 Flask/FastAPI + Gunicorn/Uvicorn)卡死、进程满载、死循环、内存溢出等。 | | 3. 并发太高,工作进程/线程耗尽 | Gunicorn worker 数不够,请求排队太久,无法及时响应。 | | 4. 网络问题或跨服务调用延迟 | 如你的服务调用了 Jira API、GitLab、MySQL 等外部系统,这些依赖响应缓慢。 | | 5. Nginx 配置超时太短 | 默认 `proxy_read_timeout` 可能只有 30~60 秒,长任务直接被切断。 | --- ### ✅ 解决方法 #### ✅ 1. 检查后端日志(Python 服务日志) 查看你的应用是否真的收到了请求?有没有打印开始/结束日志? ```bash # 示例:检查 gunicorn 或 uvicorn 日志 tail -f logs/gunicorn.log ``` 如果根本没有日志输出 → 请求未到达应用层(可能是负载均衡、防火墙等问题) 如果有日志但长时间无返回 → 是你的代码执行太慢! #### ✅ 2. 优化慢接口逻辑 比如你在 `/v1/system/config-ta-jql/update` 中做了以下事情: - 大量数据校验 - 循环调用外部 API - 执行复杂 SQL 查询(如多表 JOIN 统计) - 没有异步处理却要等几分钟 👉 应考虑: - 异步任务(Celery + Redis/RabbitMQ) - 分批处理 - 加缓存 - 使用更高效算法或索引 #### ✅ 3. 调整 Nginx 超时配置(临时缓解) 编辑 Nginx 配置文件(通常为 `/etc/nginx/nginx.conf` 或站点配置): ```nginx location /tap-system-api/ { proxy_pass http://your-backend-server; proxy_http_version 1.1; # 增加超时时间(单位秒) proxy_connect_timeout 300; proxy_send_timeout 300; proxy_read_timeout 300; send_timeout 300; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } ``` 然后重启 Nginx: ```bash sudo nginx -s reload ``` ⚠️ 注意:这只是掩盖问题,根本解决还是要优化后端性能。 #### ✅ 4. 提升后端并发能力(Gunicorn/Uvicorn 示例) 如果你用的是 Gunicorn + Uvicorn Worker: ```bash gunicorn -w 4 -k uvicorn.workers.UvicornWorker --timeout 300 app:app ``` - `-w 4`:启动 4 个工作进程 - `--timeout 300`:允许每个请求最长运行 300 秒 也可以使用异步框架(FastAPI)+ Uvicorn 的异步模式提升吞吐量。 #### ✅ 5. 使用异步任务队列(推荐长期方案) 对于耗时操作,不要同步执行,改为提交到后台任务: ```python # 示例:使用 Celery from celery_app import update_ta_jql_task @app.post("/config-ta-jql/update") def update_config(request): task = update_ta_jql_task.delay(data=request.json) return {"task_id": task.id, "status": "accepted"} ``` 前端轮询任务状态即可。 --- ### ✅ 如何预防 504? | 措施 | 建议 | |------|------| | 设置合理的接口超时监控 | Prometheus + Grafana 监控响应时间 | | 添加请求日志埋点 | 记录每个接口的 `start_time`, `end_time` | | 使用健康检查 | `/healthz` 接口确保服务存活 | | 上限流和熔断机制 | 防止雪崩 | --- ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值