3. MSH段精讲与消息控制
MSH(Message Header)是 HL7 v2 消息的第一个段,也是整条消息的“控制中枢”。它决定了这条消息是谁发的、发给谁、什么时候发的、属于什么业务事件、用哪套编码规则解析、以及如何与应答消息配对。对接口开发者而言,MSH 解析错误往往不是“某个字段读不到”这么简单,而是整条消息的路由、字符集、时间格式和 ACK 关联全部失效。因此,理解 MSH 不能停留在字段清单,而要理解每个字段在消息生命周期中的作用。
一、MSH 的字段结构与位置约定
HL7 v2 使用竖线 | 作为字段分隔符,MSH 段本身比较特殊:MSH 之后紧跟的就是字段分隔符,因此 MSH-1 在物理位置上“看不见”,它由 MSH 段第二个字符决定。例如:
MSH|^~\&|HIS|HOSP_A|LIS|LAB_B|20240518103000||ADT^A01|MSG000123|P|2.5.1|||AL|NE|CHN|UNICODE UTF-8
这条消息中,| 是字段分隔符,^ 是组件分隔符,~\& 分别是重复、转义和子组件分隔符。MSH-1 即 |,MSH-2 为 ^~\&。很多解析器在读取 MSH-2 之前必须先确定 MSH-1,否则无法正确切分字段,这是实现 MSH 解析的第一个关键点。
二、编码字符:MSH-2 决定整条消息的解析规则
MSH-2 编码字符字段通常包含四个字符:组件分隔符、重复分隔符、转义符、子组件分隔符。它们不是“可选项”,而是解析器切分 MSH 之后所有字段的依据。若发送方使用 ^~\&,接收方却按默认规则解析,就可能把 PID-3 中的多个患者标识错误合并。实际工程中,建议在接口契约中固定编码字符,并在接收端做校验:如果 MSH-2 与约定不一致,应记录告警或拒绝消息,而不是继续解析。
此外,MSH-18 字符集字段用于声明消息使用的字符编码,例如 UNICODE UTF-8、ASCII、8859/1。当消息包含中文姓名、地址时,MSH-18 必须与传输层编码一致,否则会出现乱码。注意:MSH-18 是 HL7 层面的字符集声明,不等同于 MLLP 传输层的字节编码,两者需要同时正确。
三、消息类型与触发事件:MSH-9 的业务语义
MSH-9 是消息类型字段,通常由“消息类型^触发事件^消息结构”三部分组成。例如 ADT^A01^ADT_A01 表示患者入院消息,ORM^O01^ORM_O01 表示通用订单消息,ORU^R01^ORU_R01 表示检验结果消息。消息类型决定业务大类,触发事件决定具体动作,消息结构决定段序和可选段。接口路由通常先看 MSH-9.1 和 MSH-9.2,再决定调用哪个处理器。
需要特别注意的是,触发事件并不总是“动作名称”本身。例如 A01 是入院,A02 是转科,A03 是出院,A04 是注册,A08 是信息更新。同一个 ADT 消息类型下,不同触发事件对后续段的要求不同。开发时不能只判断 MSH-9.1 为 ADT 就统一处理,否则会把入院和出院混为一谈。
四、版本与消息控制 ID:MSH-12 与 MSH-10
MSH-12 是版本号,例如 2.3.1、2.4、2.5.1。版本号影响字段定义、数据类型和段结构。比如 2.3 与 2.5.1 在部分字段长度、可选性和组件划分上存在差异。接收端应根据 MSH-12 选择对应的解析模型,而不是用一套固定结构硬解所有版本。
MSH-10 是消息控制 ID,由发送方生成,用于唯一标识一条消息。它最重要的用途是 ACK 关联:接收方在 ACK 的 MSA-2 中回填该 ID,发送方据此判断哪条消息被确认。若 MSH-10 重复或为空,发送方就无法可靠地做重发、去重和状态跟踪。工程上建议使用 UUID 或“系统标识+时间戳+序列号”的方式生成,并保证在同一发送系统内唯一。
五、MSH-3 至 MSH-6:发送与接收应用/设施
MSH-3 和 MSH-4 分别表示发送应用和发送设施,MSH-5 和 MSH-6 表示接收应用和接收设施。它们共同构成消息的路由地址。例如 HIS|HOSP_A|LIS|LAB_B 表示 HIS 系统从 HOSP_A 发往 LAB_B 的 LIS 系统。接口引擎通常根据 MSH-5 和 MSH-6 判断消息是否属于本系统,再根据 MSH-3 和 MSH-4 决定回执目标。若这些字段为空或填写错误,消息可能被丢弃或回执发错地址。
六、MSH-7 与 MSH-11:时间与处理 ID
MSH-7 是消息日期时间,格式通常为 YYYYMMDDHHMMSS,例如 20240518103000。它用于业务时间排序、超时判断和审计。MSH-11 是处理 ID,常见取值 P(生产)、T(测试)、D(调试)。生产环境应过滤掉 T 和 D 消息,避免测试数据进入正式库。
七、MSH-15 与 MSH-16:接收确认条件
MSH-15 表示接收确认条件,MSH-16 表示应用确认条件。常见取值包括 AL(总是)、NE(从不)、ER(仅错误时)、SU(成功时)。它们决定接收方是否需要返回 ACK,以及何时返回。例如 AL|NE 表示接收层总是确认,应用层从不确认。开发时必须按这两个字段决定 ACK 生成策略,否则会出现“发送方等待 ACK 超时”或“接收方多发 ACK”的问题。
八、MSH 解析的工程检查清单
- 先读取 MSH-1,再按 MSH-2 建立分隔符表,禁止硬编码
|^~\&。 - 校验 MSH-12 版本号是否在支持列表内,不在则记录并拒绝或降级处理。
- 按 MSH-18 解码字符集,并与 MLLP 传输层编码核对。
- 用 MSH-9.1 和 MSH-9.2 做路由,不要只看消息类型。
- 保存 MSH-10 作为消息唯一键,用于 ACK 关联、重发去重和日志追踪。
- 根据 MSH-15 和 MSH-16 决定 ACK 生成策略。
- 生产环境过滤 MSH-11 为
T或D的消息。
掌握 MSH 的关键,是把每个字段放回消息生命周期中理解:MSH-1/2 解决“怎么切”,MSH-3~6 解决“从哪来、到哪去”,MSH-7/11 解决“什么时候、什么环境”,MSH-9 解决“是什么业务”,MSH-10 解决“如何配对”,MSH-12/18 解决“按什么规则解析”,MSH-15/16 解决“要不要回”。这些字段共同构成消息控制面,是后续所有段解析和业务处理的前提。