C#批处理作业架构指南:800医疗站点每日定时并行任务实现咨询
适配该医疗站点批处理场景的最优架构设计方案
核心负载前置测算
先把刚性约束算明白,避免拍脑袋加复杂度:
- 单站点执行耗时按上限4分钟计算,要保证17:00完成,预留3小时调度窗口(14:00正式启动任务),容错空间覆盖失败重跑、节点异常的场景
- 按任务执行稳态计算:总并发只要达到25,就能实现每分钟稳定完成6个以上站点任务,3小时可支撑1100+站点的处理量,完全覆盖800站点的规模需求,还留30%的冗余
- 5台单节点服务器平均分配5并发即可达到总并发25的阈值,远低于单服务器的常规负载上限
分层架构落地(完全复用现有资产,不新增冗余组件)
不引入额外的分布式调度框架、消息队列等依赖,基于已有的C#控制台程序、5台服务器、现有数据库搭建,所有逻辑可落地、排错成本极低:
- 集中触发层:仅在1台服务器上配置Task Scheduler,每天14:00触发1次调度控制台程序,程序只负责从站点配置表拉取800个有效站点的清单,批量插入轻量任务队列表,设置任务截止时间为当日17:00,状态为待执行。不需要5台服务器各自配置调度任务,避免重复触发、任务覆盖的问题。
- 分布式执行层:5台服务器上的C#控制台作业,都配置为每5分钟通过Task Scheduler触发1次,核心逻辑做两个调整:
- 程序启动后通过数据库原子锁抢占任务,每次抢占对应数量的待执行任务,从机制上避免多节点重复执行同一个站点的任务,示例SQL如下:
UPDATE TOP (5) TaskQueue SET Status = 'Running', NodeId = @CurrentNodeId, UpdateTime = GETUTCDATE() OUTPUT inserted.SiteId, inserted.SiteConnectionString FROM TaskQueue WITH (ROWLOCK, UPDLOCK, READPAST) WHERE Status = 'Pending' AND Deadline >= GETUTCDATE() - 抢占到任务后,在单节点内部用指定并发度(和抢占数量对齐,比如5并发)并行执行每个站点的存储proc调用,执行完成后根据结果把任务状态更新为
Success/Failed,记录错误信息和执行耗时
- 程序启动后通过数据库原子锁抢占任务,每次抢占对应数量的待执行任务,从机制上避免多节点重复执行同一个站点的任务,示例SQL如下:
- 容错兜底层:
- 每次抢占任务前,自动扫描僵死任务:把状态为
Running、但最后更新时间超过10分钟的任务,自动重置回Pending,避免节点崩溃导致的任务永久丢失 - 每15分钟扫描一次队列表,把当日状态为
Failed的任务重置回Pending,最多重跑3次,仍失败的自动触发邮件告警 - 16:30节点自动调整单节点的抢占阈值,把并发提升50%,集中资源完成剩余未执行的任务,确保不卡17:00的截止时间
- 每次抢占任务前,自动扫描僵死任务:把状态为
关键设计细节避坑
- 并发度一定要做数据库压测:因为所有任务都是调用存储proc,要提前在测试环境验证库能承受的最大并发连接数、proc的锁粒度,避免并发过高造成数据库行锁、表锁,反而拖慢整体执行速度,比超时问题的影响更大
- 和现有Web架构解耦:之前站点管理员手动触发操作的场景,不需要再走Web API长连接,只要直接往任务队列表插入一条对应站点的待执行记录即可,执行节点抢占后就会自动处理,Web页面直接查询队列表的状态展示给管理员,从根本上解决Web请求超时的问题
- 所有任务状态可追溯:队列表保留近30天的执行记录,哪个站点什么时候执行、在哪个节点跑、成功还是失败、耗时多久,直接查表就能定位问题,不需要去5台服务器挨个翻日志
这种架构的核心优势是没有额外运维成本,所有逻辑都基于已有的技术栈实现,没有引入新的中间件,医疗场景下的故障点最少,稳定性最高,完全匹配当前的资源规模和时效要求。
内容的提问来源于stack exchange,提问作者user2631832
相关产品推荐
相关产品推荐

