基于规则的自动调度是生产管理系统的核心功能之一,其核心思想是通过预定义的业务规则(如优先级、资源匹配、时间窗口等)自动分配任务。以下是结合 FastAPI + 定时任务的具体实现方案:
一、架构设计
graph TD
A[定时触发器] --> B(规则引擎)
B --> C{规则1: 优先级匹配?}
C -->|是| D[分配高优先级资源]
C -->|否| E{规则2: 时间窗口匹配?}
E -->|是| F[分配空闲设备]
E -->|否| G[进入等待队列]
二、关键技术实现
1. 规则定义(数据库模型)
使用SQLAlchemy或Tortoise ORM定义规则表:
# models.py
class SchedulingRule(BaseModel):
id = fields.IntField(pk=True)
name = fields.CharField(max_length=50)
priority = fields.IntField() # 规则优先级
condition = fields.JSONField() # 规则条件
action = fields.JSONField() # 执行动作
is_active = fields.BooleanField(default=True)
# 示例规则存储格式:
condition = {
"type": "AND",
"rules": [
{"field": "order.priority", "operator": ">=", "value": 3},
{"field": "resource.status", "operator": "==", "value": "idle"}
]
}
action = {
"type": "assign_resource",
"params": {"resource_type": "machine"}
}
2. 规则引擎实现
# services/rule_engine.py
class RuleEngine:
def evaluate(self, context: dict, rule: SchedulingRule) -> bool:
# 使用递归解析JSON条件
return self._eval_condition(rule.condition, context)
def _eval_condition(self, condition: dict, context: dict) -> bool:
if condition["type"] == "AND":
return all(self._eval_condition(sub, context) for sub in condition["rules"])
elif condition["type"] == "OR":
return any(self._eval_condition(sub, context) for sub in condition["rules"])
else:
# 原子条件判断
field_value = self._get_nested_field(context, condition["field"])
return self._apply_operator(
field_value,
condition["operator"],
condition["value"]
)
def _apply_operator(self, a, op, b):
ops = {
"==": lambda x,y: x == y,
">=": lambda x,y: x >= y,
"<=": lambda x,y: x <= y,
"contains": lambda x,y: y in x
}
return ops[op](a, b)
3. 调度任务与FastAPI集成
使用 APScheduler 或 Celery Beat 实现定时触发:
# main.py (FastAPI入口)
from apscheduler.schedulers.asyncio import AsyncIOScheduler
app = FastAPI()
scheduler = AsyncIOScheduler()
@app.on_event("startup")
async def init_scheduler():
# 每5分钟运行一次自动调度
scheduler.add_job(auto_schedule, 'interval', minutes=5)
scheduler.start()
async def auto_schedule():
# 1. 获取待处理工单
pending_orders = await Order.filter(status="pending").all()
# 2. 加载活跃规则(按优先级排序)
rules = await SchedulingRule.filter(is_active=True).order_by("-priority")
# 3. 遍历工单应用规则
for order in pending_orders:
context = await build_context(order) # 获取工单上下文数据
for rule in rules:
if RuleEngine().evaluate(context, rule):
await execute_action(rule.action, order)
break # 匹配到即终止
三、典型规则案例
规则1:紧急订单优先分配
{
"name": "紧急订单处理",
"priority": 1,
"condition": {
"type": "AND",
"rules": [
{"field": "order.priority", "operator": ">=", "value": 4},
{"field": "resource.type", "operator": "==", "value": "high_performance"}
]
},
"action": {
"type": "assign_resource",
"params": {"resource_id": "high_perf_pool"}
}
}
规则2:时间窗口匹配
{
"name": "夜班自动化生产",
"priority": 2,
"condition": {
"type": "AND",
"rules": [
{"field": "order.required_time", "operator": "contains", "value": "night"},
{"field": "resource.shift", "operator": "==", "value": "night_shift"}
]
},
"action": {
"type": "assign_with_checklist",
"params": {
"checklist": ["safety_switch", "lighting_check"]
}
}
}
四、性能优化技巧
-
上下文缓存:
from fastapi_cache.decorator import cache @cache(expire=300) async def build_context(order_id: int) -> dict: # 聚合订单、资源、库存等数据 ... -
批量处理优化:
# 使用异步批量查询 async def auto_schedule(): order_ids = await Order.filter(...).values_list("id", flat=True) # 一次加载所有相关资源 resources = await Resource.all().prefetch_related("capabilities") # 并行处理工单 await asyncio.gather(*[process_order(o) for o in order_ids]) -
规则预编译:
# 启动时编译规则为可执行函数 class CompiledRule: def __init__(self, rule_data): self.condition = self._compile(rule_data["condition"]) self.action = self._compile_action(rule_data["action"]) def _compile(self, condition): # 生成Lamba表达式或AST树 ...
五、调试与监控
-
API端点测试:
@app.post("/dev/force-schedule") async def manual_trigger(): await auto_schedule() return {"status": "triggered"} -
可视化日志:
# 在规则执行时记录决策过程 logger.info( f"Rule {rule.name} applied to Order {order.id}", extra={ "condition": rule.condition, "context_snapshot": context } ) -
Prometheus监控指标:
from prometheus_client import Counter RULES_TRIGGERED = Counter( 'scheduler_rules_triggered_total', 'Total triggered rules', ['rule_name'] ) # 在execute_action中增加 RULES_TRIGGERED.labels(rule.name).inc()
六、扩展性设计
-
规则热加载:
@app.post("/rules/reload") async def reload_rules(): global cached_rules cached_rules = await SchedulingRule.filter(...) return {"count": len(cached_rules)} -
与Agently的兼容接口:
async def execute_action(action: dict, order: Order): if action["type"].startswith("ai_"): # 调用Agently服务 await agently_client.execute( endpoint=action["type"][3:], params=action["params"] ) else: # 原生操作 ...
通过这种设计,可以实现:
-
规则与业务逻辑解耦:通过JSON配置动态修改规则
-
弹性调度频率:从每分钟到每小时自由调整
-
平滑升级到AI阶段:只需在
execute_action中增加AI分支处理
8815

被折叠的 条评论
为什么被折叠?



