Simpy是否支持多节点优化动态资源分配?双节点动态调度如何实现
要实现两节点间的动态资源分配,核心要解决两个问题:一是支持Simpy资源容量的动态调整,二是增加调度逻辑根据实时负载调整资源分配。具体实现步骤和代码如下:
核心实现思路
- 可以根据业务需求选择普通
Resource或PreemptiveResource作为节点资源载体,前者调整容量时需等待现有任务处理完成再迁移资源,后者支持抢占式资源迁移 - 新增独立的调度进程,定期采集两个节点的排队长度、资源利用率指标,按照预设的调度策略调整两个节点的资源容量,保证总资源数始终为12
- 新增统计模块,记录每个物料的全链路处理时长,方便验证优化效果
完整可运行代码
import numpy as np import simpy # 全局配置参数 TOTAL_RESOURCES = 12 SCHEDULE_INTERVAL = 10 # 调度间隔,单位和仿真时间一致 ENABLE_PREEMPT = False # 是否允许资源迁移时抢占正在处理的任务 # 统计用变量 total_process_time = [] def interarrival(): return np.random.exponential(20) def servicetime(): return np.random.exponential(60) # 调度进程:动态调整两个节点的资源分配 def resource_scheduler(env, servers_array): while True: # 获取两个节点当前的排队长度(等待的请求数) queue0_len = len(servers_array[0].queue) queue1_len = len(servers_array[1].queue) # 当前两个节点的资源容量 cap0 = servers_array[0].capacity cap1 = servers_array[1].capacity # 调度策略示例:根据队列长度差调整,可替换为更优策略 # 节点0排队比节点1长很多,且节点1有富余资源,就迁1个资源到节点0 if queue0_len - queue1_len > 2 and cap1 > 1: servers_array[0].capacity += 1 servers_array[1].capacity -= 1 print(f"[{env.now:.2f}] 调整资源:节点0{cap0}→{cap0+1},节点1{cap1}→{cap1-1}") # 节点1排队比节点0长很多,且节点0有富余资源,就迁1个资源到节点1 elif queue1_len - queue0_len > 2 and cap0 > 1: servers_array[0].capacity -= 1 servers_array[1].capacity += 1 print(f"[{env.now:.2f}] 调整资源:节点0{cap0}→{cap0-1},节点1{cap1}→{cap1+1}") # 等待下一个调度周期 yield env.timeout(SCHEDULE_INTERVAL) def servicing(env, servers_array): i = 0 while True: i += 1 yield env.timeout(interarrival()) arrival_time = env.now print(f"[{env.now:.2f}] 物料{i}到达系统") env.process(items(env, i, servers_array, 0, arrival_time)) def items(env, item_id, servers_array, state, system_arrival_time): with servers_array[state].request() as request: yield request t_arrival = env.now print(f"[{t_arrival:.2f}] 物料{item_id}进入节点{state}处理") yield env.timeout(servicetime()) t_depart = env.now print(f"[{t_depart:.2f}] 物料{item_id}离开节点{state}") if state == 1: # 计算全链路处理时长 process_time = t_depart - system_arrival_time total_process_time.append(process_time) print(f"[{t_depart:.2f}] 物料{item_id}完成全流程,总耗时{process_time:.2f}") else: env.process(items(env, item_id, servers_array, 1, system_arrival_time)) # 仿真初始化 env = simpy.Environment() # 初始分配和原方案一致:节点05个,节点17个 if ENABLE_PREEMPT: servers_array = [ simpy.PreemptiveResource(env, capacity=5), simpy.PreemptiveResource(env, capacity=7) ] else: servers_array = [ simpy.Resource(env, capacity=5), simpy.Resource(env, capacity=7) ] # 启动所有进程 env.process(servicing(env, servers_array)) env.process(resource_scheduler(env, servers_array)) env.run(until=2880) # 仿真结束输出统计结果 avg_time = np.mean(total_process_time) if total_process_time else 0 print(f"\n仿真结束,总处理物料数:{len(total_process_time)},平均总处理时长:{avg_time:.2f}")
关键说明
- 上述代码中的调度策略是示例逻辑,你可以根据实际业务场景替换成更优的策略,比如结合两个节点的等待时间、资源利用率、未来流量预测等指标做决策,进一步降低平均处理时长
- 你也可以调整
SCHEDULE_INTERVAL参数,控制调度的频率,频率越高调整越及时,但仿真运行开销也会更大
内容的提问来源于stack exchange,提问作者Coding Practice
相关产品推荐
相关产品推荐

