Files
djangoadmin-wiki/DjangoAdmin_Django_EleVue/zh/volume4/business/job.md
T
2026-09-12 23:12:15 +08:00

179 lines
6.8 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.
:::tip 定时任务
定时任务模块基于 APScheduler 实现,支持 Cron 表达式调度、任务执行日志、动态启停等功能。包含 job(任务定义)、job_log(执行日志)两个子模块。
:::
## 模块结构
```
application/job/
├── models.py # 任务模型
├── forms.py # 表单验证
├── services.py # 业务逻辑层
├── views.py # 视图层
└── urls.py # 路由配置
application/job_log/
├── models.py # 执行日志模型
├── services.py # 日志业务逻辑
└── urls.py # 路由配置
```
## 任务模型
```python
# application/job/models.py
from application.models import BaseModel
class Job(BaseModel):
"""定时任务模型类"""
class Meta:
db_table = 'django_job'
job_name = models.CharField(max_length=255, verbose_name='任务名称')
job_alias = models.CharField(max_length=255, null=True, blank=True, verbose_name='任务别名')
job_group = models.CharField(max_length=255, null=True, blank=True, verbose_name='任务分组')
job_trigger = models.CharField(max_length=255, null=True, blank=True, verbose_name='任务触发器')
status = models.IntegerField(default=0, verbose_name='任务状态:0-未发布 1-运行中 2-暂停 3-删除')
cron_expression = models.CharField(max_length=255, null=True, blank=True, verbose_name='Cron表达式')
execute_policy = models.IntegerField(default=1, verbose_name='执行策略:1-立即执行 2-执行一次 3-放弃执行')
is_sync = models.IntegerField(default=0, verbose_name='是否同步任务:0-否 1-是')
url = models.CharField(max_length=255, null=True, blank=True, verbose_name='任务URL')
params = models.TextField(null=True, blank=True, verbose_name='任务参数')
note = models.CharField(max_length=255, null=True, blank=True, verbose_name='任务备注')
```
### 字段说明
| 字段 | 类型 | 说明 |
|------|------|------|
| `job_name` | str | 任务名称(唯一标识) |
| `job_alias` | str | 任务别名(显示用) |
| `job_group` | str | 任务分组(如"系统任务"、"业务任务") |
| `job_trigger` | str | 触发器类型(cron/interval/date) |
| `status` | int | 状态:0-未发布 1-运行中 2-暂停 3-删除 |
| `cron_expression` | str | Cron 表达式 |
| `execute_policy` | int | 执行策略:1-立即执行 2-执行一次 3-放弃执行 |
| `is_sync` | int | 是否同步:0-异步 1-同步 |
| `url` | str | 任务执行的 URL |
| `params` | str | 任务参数(JSON 格式) |
## 执行日志模型
```python
# application/job_log/models.py
from application.models import BaseModel
class JobLog(BaseModel):
"""定时任务日志模型类"""
class Meta:
db_table = 'django_job_log'
job_id = models.IntegerField(default=0, verbose_name='任务ID')
job_name = models.CharField(max_length=255, verbose_name='任务名称')
job_group = models.CharField(max_length=255, null=True, blank=True, verbose_name='任务分组')
job_trigger = models.CharField(max_length=255, null=True, blank=True, verbose_name='任务触发器')
job_message = models.CharField(max_length=500, null=True, blank=True, verbose_name='任务日志信息')
cron_expression = models.CharField(max_length=255, null=True, blank=True, verbose_name='Cron表达式')
status = models.IntegerField(default=0, verbose_name='执行状态:0-正常 1-失败')
start_time = models.DateTimeField(null=True, blank=True, verbose_name='执行开始时间')
end_time = models.DateTimeField(null=True, blank=True, verbose_name='执行结束时间')
consume_time = models.BigIntegerField(default=0, verbose_name='执行耗时(毫秒)')
exception_info = models.TextField(null=True, blank=True, verbose_name='异常信息')
```
## Cron 表达式
| 字段 | 允许值 | 允许的特殊字符 |
|------|--------|---------------|
| 秒 | 0-59 | , - * / |
| 分 | 0-59 | , - * / |
| 时 | 0-23 | , - * / |
| 日 | 1-31 | , - * / |
| 月 | 1-12 | , - * / |
| 周 | 0-7 | , - * / |
### 常用示例
```
0 0/5 * * * ? 每5分钟执行
0 0 2 * * ? 每天凌晨2点执行
0 0 0 1 * ? 每月1号零点执行
0 0 * * * ? 每小时执行
0 0 9 * * 1-5 工作日上午9点执行
0 0/30 8-18 * * ? 工作时间每30分钟执行
```
### 特殊字符说明
| 字符 | 说明 | 示例 |
|------|------|------|
| `*` | 所有值 | `* * * * *` 每分钟 |
| `?` | 不指定值(日和周) | `0 0 12 * * ?` |
| `-` | 范围 | `1-5` 表示 1 到 5 |
| `,` | 列表 | `1,3,5` 表示 1、3、5 |
| `/` | 步长 | `0/5` 从 0 开始每 5 |
## 任务状态
```
未发布(0) → 运行中(1) → 暂停(2) → 运行中(1) → 删除(3)
↓
删除(3)
```
| 状态 | 说明 | 可执行操作 |
|------|------|-----------|
| 0-未发布 | 任务已创建但未启动 | 启动、编辑、删除 |
| 1-运行中 | 任务正在调度执行 | 暂停、立即执行、编辑 |
| 2-暂停 | 任务已暂停 | 恢复、编辑、删除 |
| 3-删除 | 任务已删除(逻辑删除) | 无 |
## 执行策略
| 策略 | 说明 | 场景 |
|------|------|------|
| 1-立即执行 | 错过执行时间后立即补执行 | 关键任务(如数据备份) |
| 2-执行一次 | 错过执行时间后只执行一次 | 普通任务 |
| 3-放弃执行 | 错过执行时间后放弃本次执行 | 非关键任务 |
## API 接口
| 接口 | 方法 | 权限节点 | 说明 |
|------|------|---------|------|
| `/job/page` | GET | `sys:job:page` | 任务分页列表 |
| `/job/detail/<int:id>` | GET | `sys:job:detail` | 任务详情 |
| `/job/add` | POST | `sys:job:add` | 新增任务 |
| `/job/update` | PUT | `sys:job:update` | 编辑任务 |
| `/job/delete/<int:id>` | DELETE | `sys:job:delete` | 删除任务 |
| `/job/status` | PUT | `sys:job:status` | 启停任务 |
| `/job/run` | POST | `sys:job:run` | 立即执行 |
| `/job/log/page` | GET | `sys:jobLog:page` | 执行日志 |
## 分布式锁
多实例部署时,定时任务可能重复执行。项目通过 Redis 分布式锁解决:
```
1. 任务触发时,先尝试获取 Redis 锁
2. 获取成功 → 执行任务 → 释放锁
3. 获取失败 → 跳过本次执行(其他实例正在执行)
```
:::tip 锁的 Key
分布式锁的 Key 格式为 `job:lock:{job_id}`,TTL 与任务执行超时时间一致。
:::
## 总结
定时任务模块具备以下特点:
```
1. APScheduler:基于成熟的调度框架,支持 Cron 表达式
2. 动态管理:通过接口动态添加、修改、启停任务
3. 执行日志:自动记录每次执行的开始时间、耗时、状态、异常
4. 并发控制:可配置是否允许并发执行
5. 错过策略:配置错过执行时的处理策略
6. 分布式锁:多实例部署时避免任务重复执行
7. 立即执行:支持手动触发任务立即执行
```