forked from erp-dev/erp
109 lines
4.2 KiB
Markdown
109 lines
4.2 KiB
Markdown
# 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. 本地验证真实 worker(RabbitMQ + Celery)
|
||
|
||
### 2.1 启动依赖服务
|
||
|
||
```bash
|
||
# 启动基础设施(Postgres/Redis/Rabbit/Celery worker/web)
|
||
docker compose up -d postgres redis rabbitmq
|
||
|
||
# 启动 web(Django)
|
||
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`,在任务内进行必要的日志记录,便于问题排查。***
|
||
|