IRIS License 机制说明、 JOB 工具优化方案、常见问题说明
1. 背景说明:License 并发限制带来的风险
在 IRIS 系统中,数据库 License 通常存在最大并发限制(例如最大为 300)。每当一个客户端与服务器建立连接时,都会占用一个 License。当 License 使用量超过最大上限时,系统将无法再分配新的 License,导致后续请求无法正常建立连接,常见表现包括:
- 前端页面报错(连接失败、服务不可用等)
- 页面加载极慢或请求长时间无响应
- 部分接口调用失败,业务中断风险显著提升
与此同时,在 IRIS 中执行 JOB 命令也会额外占用 License。也就是说,每启动一个后台 Job 进程,就会消耗一个独立的 License。如果在业务高峰期的核心流程中频繁调用 JOB,会快速推高 License 使用量,极易造成 License 被撑满,从而影响正常在线业务请求,严重时甚至引发系统不可用。
2. 优化方案:使用 JOB 工具统一调度
基于上述风险,需要将业务程序中直接调用 JOB 命令的逻辑,统一调整为通过 JOB 工具进行调度执行,以避免业务高峰期 License 被瞬间打满。
该工具的核心机制如下:
- 实时监控当前 License 使用情况
- 当 License 使用量超过最大值的 80% 时,自动停止创建新的 Job 任务
- 避免因瞬时高并发任务导致 License 爆满,从而保障在线业务稳定运行
该策略的本质是对后台任务进行“削峰限流”,确保核心在线业务优先获得 License 资源。
JOB工具使用说明
示例接口方法:
ClassMethod Add(x, y)
{
h 30
q x + y
}
通常使用JOB命令调用的接口方式如下:
j ##class(Util.JobUtils).Add($random(10), $random(10))
需要将如上JOB命令调用的接口方式改为使用JOB工具调用,示例如下:
s ret = ##class(Util.JobUtils).RunJobMethod("Util.JobDemo", "Add", $random(10), $random(10))
方法签名如下:
ClassMethod RunJobMethod(className, methodName, arg...) As %Boolean
- className – 类名。
- methodName – 方法名称。
- arg – 可变参数。
3. 任务记录与失败补偿机制
通过 JOB 工具提交的每次任务调用,都会记录到表:
BS_BSP.ExternalJob
该表用于保存所有任务调用记录,包括任务参数、执行状态、错误信息、执行结果等信息,便于后续追踪与补偿处理。
当系统检测到 License 使用率超过 80% 时:
- 当前任务不会启动 Job 执行
iserror字段会置为1(标记为失败/暂挂任务)errmsg字段会记录失败原因,例如:超过当前license最大数量80%
需要说明的是:该失败属于正常保护机制,并非业务逻辑错误。
3.1 任务补偿执行逻辑
当 License 压力下降后,系统会对失败任务进行补偿重试,并按照失败任务的创建时间顺序进入队列执行,确保任务最终完成。
补偿执行过程中字段状态变化如下:
- 开始执行时:
istask = 1 - 执行完成时:
istaskfinish = 1 - 若接口存在返回值:结果会写入
taskResult字段
通过该机制,能够保证任务在高峰期不会挤占 License,而在低峰期会自动补偿执行,实现“削峰填谷”的效果。
4. 常见问题与根因分析
4.1 常见根因:接口超时导致 License 长时间不释放
目前绝大部分 License 阻塞问题,并不是 JOB 工具本身导致,而是由调用的接口执行超时引起。
典型现象为:
- 业务高峰期间产生大量 JOB 请求
- 每个 JOB 会占用一个 License
- 由于接口超时(如调用第三方接口未设置超时、数据库查询慢等),JOB 长时间不结束,License 长时间无法释放
- License 在短时间内快速攀升至 80% 以上
- 后续任务触发 JOB 工具保护机制,在
BS_BSP.ExternalJob表中表现为失败任务(iserror = 1)
此时在 errmsg 字段通常可以看到提示:
超过80%最大许可
4.2 排查方式:检查 InternalJob 执行耗时
此类问题应当重点查询表:
BS_BSP.InternalJob
重点关注 runtime 字段,筛选 runtime > 3s 的任务(实际上接口执行超过 1s 就已经属于偏慢,需要重点关注)。
如果发现大量 30s、60s、120s,甚至 360s 以上的数据,则说明 JOB 执行耗时严重异常,会直接导致 License 被占用时间过长。
排查结果通常如下:
classname+methodname指向具体接口实现- 根据对应接口定位到产品组/开发负责人
- 要求优化接口逻辑或外部依赖调用超时机制
注意:减少超时时间不是指从 30 秒调整到 10 秒,而是应当从根本上将接口执行耗时控制在 3 秒以内。
否则只是“五十步笑百步”,无法真正解决 License 阻塞问题。

5. FAQ 常见问题说明
Q1:HIS 调用平台接口返回 “License 超过 80%”,但实际监控发现 License 只有 70%,为什么?
A:常见原因如下:
- License 峰值具有瞬时性
高峰期短时间内大量并发 JOB 可能导致 License 瞬间超过 80%,但监控查询时峰值已经回落,因此监控值不能代表当时真实情况。 -
失败任务会自动补偿重发
JOB 工具触发保护机制后,任务会先失败入表,随后在 License 下降后自动补偿执行。 -
可通过 ExternalJob 表确认任务是否已补发完成
检查
BS_BSP.ExternalJob是否存在该条记录,并查看字段:
istask = 1表示已进入补偿执行队列istaskfinish = 1表示已补偿执行完成
Q2:发现存在较多消息未正常插入接口表,排查发现 ExternalJob 表中存在大量失败提示 “超过当前license最大数量80%”(高峰每天约 1-2w),DBA 优化负载后仍未解决?
A:需要明确以下几点:
iserror = 1属于正常限流保护行为
该机制的目的是防止 License 爆满导致核心在线业务不可用,因此失败数量大并不代表系统异常。-
失败任务会自动补偿执行
可检查
BS_BSP.ExternalJob
iserror = 1- 同时确认
istask、istaskfinish是否置位为 1
若istaskfinish = 1,则说明该任务已经补发完成,不会造成数据丢失。
- 如果失败任务未补偿完成,需要重点排查接口耗时问题
查询BS_BSP.InternalJob表,筛选runtime > 3s的记录。
若存在大量超时数据,需联系对应接口产品组处理,通常原因是接口内部调用第三方服务未设置 timeout,导致线程阻塞。
Q3:部分门诊患者缴费后未调用平台接口给 PACS 推送申请单信息,导致科室无法检查。项目组认为高峰期 JOB 占用 License 超过 80% 导致堵塞,需要协助排查。
A:排查思路如下:
- 查询
BS_BSP.ExternalJob是否存在对应推送任务记录
- 是否
iserror = 1 - 是否
errmsg提示超过 80%
- 查看该任务是否已补偿执行
istask = 1istaskfinish = 1taskResult是否记录执行结果
- 若存在大量失败且长期未补偿完成,进一步排查 InternalJob
- 查询
BS_BSP.InternalJob中runtime > 3s的接口 - 定位
classname、methodname,推动接口优化或第三方调用设置超时
该问题本质上仍属于“接口执行慢 / 超时 → License 占用过久 → 触发保护机制”链路,处理方式参考上述常见根因分析。
6. 总结
JOB 工具的作用并不是减少任务,而是在高峰期通过限流保护机制确保系统稳定:
- 防止 License 被瞬时打满导致在线业务不可用
- 失败任务会自动进入队列补偿执行,确保最终一致性
- 真正需要重点治理的是 InternalJob 中 runtime 偏高的接口,尤其是涉及第三方调用未设置 timeout 的场景
通过优化慢接口、控制 runtime 在 3 秒以内,可以显著改善 License 占用阻塞问题,减少 ExternalJob 高峰失败数量,并提升整体系统稳定性。