1
0
forked from erp-dev/erp
Files
erpnew/docs/celery_testing.md

109 lines
4.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Celery 任务测试指南
## 1. 自动化测试(单元测试/CI
项目新增了三个演示型任务(`api_v1/tasks.py`
| 任务 | 功能 |
|------|------|
| `ping_task(message='ping')` | 打印并返回时间戳,用于快速验证 worker 是否可接收/返回结果 |
| `merchant_product_count(merchant_id)` | 统计某商户下产品数量,示范如何在任务中访问数据库 |
| `backup_database(output_dir=None, filename_prefix='db-backup')` | 将当前数据库导出为 `.sql` 文件(数据备份),默认保存到 `BASE_DIR/data-bak/` |
对应的单元测试位于 `api_v1/tests.py`(类 `CeleryTasksTestCase`),通过
`@override_settings(CELERY_TASK_ALWAYS_EAGER=True)` 让任务在测试进程内同步执行。
运行方式:
```bash
uv run manage.py test api_v1.tests.CeleryTasksTestCase
```
若要在其他测试中调用任务,只需在测试类上使用同样的 `override_settings`
即可保证 Celery 在没有 worker 的情况下仍能同步执行。
---
## 2. 本地验证真实 workerRabbitMQ + Celery
### 2.1 启动依赖服务
```bash
# 启动基础设施Postgres/Redis/Rabbit/Celery worker/web
docker compose up -d postgres redis rabbitmq
# 启动 webDjango
docker compose up -d web
# 启动 Celery worker如已运行可跳过
docker compose up -d celery_worker
# 或者手动uv run celery -A flower worker -l info
```
> 若 worker 容器异常,可通过 `docker compose restart celery_worker` 重启。
### 2.2 发送测试任务
在另一个终端进入容器或宿主项目目录执行:
```bash
uv run python manage.py shell
```
```python
from api_v1.tasks import ping_task, merchant_product_count, backup_database
from basic_info.models import Merchant
# 发送心跳任务
async_result = ping_task.delay('hello celery')
print(async_result.get(timeout=10))
# 发送统计任务(示例:使用 ID=1 的商户)
merchant = Merchant.objects.first()
result = merchant_product_count.delay(merchant.id)
print(result.get(timeout=10))
# 触发数据库备份(输出到默认 data-bak
backup = backup_database.delay(filename_prefix='manual-backup')
print(backup.get(timeout=30)) # payload 中包含 backup_path文件为 .sql
```
### 2.3 观察执行结果
1. **Worker 日志**`docker compose logs -f celery_worker` \
可查看任务被消费、日志输出等信息。
2. **RabbitMQ 控制台**:访问 `http://localhost:15672`(默认账号 guest/guest
观察队列长度是否回落到 0。
3. **Task Result**:上面的 `result.get()` 会在任务完成时返回 payload
若超时或无法连接则会抛出异常,帮助定位问题。
---
## 3. 失败排查 Checklist
1. **环境变量**`CELERY_BROKER_URL``CELERY_RESULT_BACKEND` 是否指向
正在运行的 RabbitMQ/Redis
2. **Worker 进程**`docker compose ps` 确认 `celery_worker` 状态为 Up。
3. **队列阻塞**RabbitMQ 控制台查看是否有大量消息处于 `Unacked`
4. **日志级别**:测试中需要捕获日志时,可使用
`with self.assertLogs('api_v1.tasks', level='INFO')`.
5. **自动化测试**:若任务在测试里需要真实队列,请去掉
`CELERY_TASK_ALWAYS_EAGER` 覆盖;否则保持默认值即可同步执行。
6. **数据库备份依赖**`backup_database` 在 PostgreSQL 场景下需要系统可执行 `pg_dump`
请确保容器/宿主机已安装 PostgreSQL 客户端工具SQLite 则会使用内置 `iterdump` 生成 `.sql`
---
## 4. 常用命令速查
| 操作 | 命令 |
|------|------|
| 启动 worker | `docker compose up -d celery_worker` |
| 查看 worker 日志 | `docker compose logs -f celery_worker` |
| 重启 worker | `docker compose restart celery_worker` |
| 清空 RabbitMQ 队列 | `docker compose exec rabbitmq rabbitmqctl purge_queue flower`(示例) |
| 运行单个任务测试 | `uv run python manage.py shell` -> `ping_task.delay()` |
通过以上步骤,即可确认 Celery + RabbitMQ 在本地能够成功执行任务,并在自动化测试里保持覆盖。若需要新增业务任务,可参考 `api_v1/tasks.py` 的写法:使用 `@shared_task`,在任务内进行必要的日志记录,便于问题排查。***