回头看一下,才发现前面的几篇“集成的故事”有点跑题了,从最初的技术随笔沦落成一些肤浅而且不着边际的商业评论。
记得在温昱老师(《软件架构设计》一书的作者)的课上,曾经听到一个很特别的观点:SOA不是软件架构,而是企业架构。当时刚听到的时候还有些许疑惑,现在开始觉得比较能接受了。
因此,让我们回归到技术的重心上吧,至少把早先在“集成的故事-导言”里面计划好的剩下的几篇给写完。
---
信息系统中的错误通常有两种原因,一种是技术性的,比如断电、断网或者文件系统错误等导致数据不完整;还有一种是人为的,比如输入了错误的病人年龄、性别、过敏史等重要的信息。在医疗环境下,有些错误可能是人命关天的。
技术性的错误比较容易被发现和处理,但人为错误发现和处理起来往往比较困难。在一个分布式的信息系统中,有时你无法预测一个错误已经被扩散到了多少个节点。多年前,一位医工领域的老前辈告诉我:发现错误的时候,你就从产生这个错误的源头开始改起,然后让先前的数据流重新执行一遍,只要数据流上的每个节点都支持Update,这个错误最终将会被消灭,并且保证整个系统都是干净的。
比如在放射科,病人来拍片才发现登记的时候把病人性别输错了,他推荐的做法就是先在RIS登记台上修改,然后让RIS更新任务清单,让设备重新拿一次任务清单,这样就能保证的图像中病人信息是正确的了。他极力反对的一种做法就是在设备上直接修改了事,因为大多数成像设备都允许在拍摄前修改病人信息,一旦修改之后医生在诊断工作站上打开图像的时候就发现RIS和PACS的信息对不上了。
如果某些信息错误是拍片之后才发现的,当然不可能让病人重拍一次,而是让QA工作站把最新的任务清单中的正确信息更新到图像中,重新发到PACS,覆盖先前错误的图像。这就要求QA工作站要在本地保存一段时间内的图像,如果本地没有的话还可以让设备重发,如果设备也找不到的话,那就得想其他的办法了。比如IHE SWF里面的,让RIS发一个HL7消息给PACS更新病人信息,尽管HL7在国内不太现实,但是有些厂家的RIS和PACS之间也会有一些私有的协议。
除了这些技术方案以外,他还在他的放射科推行一种奖惩制度,督促登记员尽量不要输入错误的信息,并且在他指导设计的软件中增加相关的功能来支持这种制度的执行(比如每次修改需要输入工号和密码并且记录在案以便绩效挂钩,而不像老外习惯的思维方式:在界面可用性上做文章以减少误操作)。过去,我们曾一度怀疑QA工作站在国内的应用会困难重重,比如增加了医院的工作量,却没有直接带来利润(象DR印钞机那样)。事实上,还是会有很多例子让我们看到了医院对医疗质量和病人生命的真正重视,至少从一些诸如“三查三对”之类的制度开始。这些制度远远早于信息化的应用,并值得信息化工作者去深入的理解和思考。
这里,我们只讨论如何在集成方案中处理信息错误,而不会从象TQM这种很高的层次来讨论医疗质量。虽然在现实世界中,技术方案的可靠性本身也取决于高层对质量的要求,而每一个要求都可能造成很大的成本支出:当问题的复杂度增加一点的时候,解决方案的复杂度往往就要增加很多了。
注意这里的可靠性可能更倾向于指医疗信息本身的完整和准确,不是那种可以用几个9来描述的系统持续可用性。
---
通常我们会在下面两种场景下考虑在集成方案的错误处理能力。
- 错误处理是一种功能需求,即要求我们实现某种信息修改的集成语义。比如当HIS中的病人姓名被修改的时候,把新的病人姓名同步到RIS。当然,有时这种修改并非因为发现了错误,而是事先并不知道确切的病人姓名(比如急诊)。
- 错误处理是一种非功能需求,即集成方案本身的可靠性设计。比如,使用两阶段提交事务来保证系统之间数据交换的完整性;为了在系统之间实现可靠的异步消息传输,引入重试、补偿等附加的控制流。
对于第一种场景,比如修改病人信息和医嘱内容,HL7和IHE里面都有相关的规范,这里也就不重复了。从IHE规定业务流程里面,也不难看出“从源头改起”法则的影子。毕竟“从源头改起”,相比一步一步回溯的方式要节约很多代价。
第二种场景,在现实世界中应用得更加广泛,可靠性是大多数集成方案都必须具备的质量属性。另外一部分集成方案,比如那些简单的事件通知式的应用,偶尔丢掉一两条消息也许无关紧要。
在分布式系统中实现可靠性数据传输似乎是个复杂的问题,好像也没有什么通用的法则可以套用。悲观的策略通常就是使用传统的两阶段提交,通过每个节点的投票来决定提交或者回滚整个事务。就像瀑布模型在软件工程里面的地位一样,两阶段提交也经常被分布式系统的专家当作死马来鞭打。从整体上看,两阶段提交的确会极大地增加系统耦合,并降低效率,但有些时候,在一些局部,正如瀑布模型一样,两阶段提交依旧发挥着重要而又经典的作用。
分布式系统中的乐观派则主张事后再来处理错误,在著名的“星巴克不使用两阶段提交”一文中介绍了几种典型的错误处理策略,比如放弃、重试以及补偿。同样,我们也可以在DICOM中找到乐观派的设计,比如Storage Commitment。这些方法都可以总结到集成方案的设计模式里面,值得我们去领会和举一反三。
---
事实上,信息错误有时候并不是那么可怕:被控制在有限范围内的错误可能会带来一些意想不到的好处。
放射科在打印胶片的时候,都需要在胶片的几个角打上一些相关的病人和检查的信息,有时甚至希望在一行,比如在显示PID的那一行,同时显示其他的一些需要打印在胶片上的信息。然而,他们的打印机或者工作站(作为IHE的Print Composer)在这方面的支持比较弱,比如不能在一行里显示多个DICOM Tag的内容。就算能显示,成像设备上也没有合适的地方可以输入。
对于厂商来说,这种奇怪的需求通常不会予以搭理。于是某位技师找到成像设备上修改PID的地方,在PID后面加个空格,然后手动输入了他们要在胶片上显示的信息,让设备把这个信息带到图像里并发送到打印机。由于这个信息对于领导来说如此的重要,这位技师的做法得到了表扬,并在放射科内部推广。直到有一天,要上PACS了,发现所有这些设备的图像都无法发送到中心存储服务器,原来所有图像的PID都是非法的。
于是厂商大显身手的机会来了,可以用QA工作站或者接口引擎之类的工具,把收到的图像做一下转换再发到PACS,这样也不会改变之前的业务规则和流程。把集成做到这种程度,客户应该心服口服了。
---
前面不止一个地方提到了QA工作站,其实在软件原理上,放射领域的QA工作站和集成接口引擎是近亲:在QA工作站里面也可以找到《企业集成模式》里面介绍的扩展器、规范器等一些设计模式,以及一些跟接口引擎很类似的可配置的值处理。
这里花一点时间来回顾一下QA工作站,看看能给我们带来什么启发。
QA工作站的QA是一个被夸大的概念。比如我们提到工程领域的QA的时候,通常指是的全面的过程质量管理,而QA工作站的工作只相当于QC,也就是后验地发现并处理问题。对于放射科来说,质量保证工作应该包括图像质量、诊断质量、病人服务质量等很多方面,QA是一个流程而不仅仅是一个工作站。就算只是关心图像质量,也有Presentation State,GSDF和Hanging Protocol等一系列的一致性显示控制,也不在QA工作站的功能范围之内。
我最早是从radwork的工作站上看到QA这个概念的,当时只是一个QA模块,可以让用户修改图像信息(我不记得是否包含图像调整和处理)。然后,各个厂商都有了自己的QA工作站,用来在图像进入PACS之前进行一些信息校验,以及图像质量的检查和控制。
后来还看到了一些QA工作站的变种,比如某些老的成像设备不支持MWL/MPPS,或者是医院买新设备的时候没人懂DICOM所以也没买MWL/MPPS,后来有人懂的时候却发现这个功能价钱太高了。于是干脆叫人开发了一个检查工作站,放在设备旁边,为技师提供任务清单:虽然实现了无纸化,但还是需要在设备上重复录入少量信息(比如某些ID等,用于匹配)。收到并匹配设备产生的图像之后,就转换和转发到PACS,使得这些图像可以包含MWL中提供的Accession Number等丰富的登记信息。
QA工作站在国内应用的时候,最大的业务问题是到底让谁来做QA,技师,医生,还是专门的QA工作人员。在很多医院,技师本身就承担了很多传统的QA任务,比如定期对成像设备进行校准等,但技师调整出来的图像未必是医生想要的,很多医生还是希望得到原始图像,根据自己的诊断需要自己边调边看。医生通常不可能专职做QA,这对医院来说太昂贵。
还有一个业务问题是图像被修改之后可能面临的法律困境,比如保存到PACS里面的是修改后的图像还是原始图像,还是一起保存;或者是(如果只修改图像头信息的话)在修改后的图像里面用一些SQ类型的DICOM Tag来保存每次修改的记录;如果是一起保存是否会增加存储成本,是否需要压缩等等。厂商通常要跟医院商量,选择一个双方都能够接受的方案。
业务问题的复杂性直接导致了QA工作站设计的复杂性。假如有人要是在Biztalk上面开发一个QA工作站的话,那么他首先要做一些Adapter来接收从设备发过来的图像,要做至少一个Adapter把图像发出去给PACS,和至少一个Adapter查询RIS的任务清单,随后的流程编排里面,首先要支持自动的信息校验和修正,还要支持人工流程去处理那些无法进行自动校验的图像。对于某些设备发过来的图像还需要进行调整,因为它们发出来的默认的窗宽窗位或者曲线显示得并不好;对于某些设备发过来的图像序列中,Study/Series/Image的树型关系需要进行调整,比如要把CT定位图提取出来,否则诊断工作站无法显示定位线等等。。于是,从来没人想过会用Biztalk来做一个象QA工作站这种东西,尽管它可能还是可以做得出来,而且价格非常昂贵。
这让我想起在intersystem的白皮书里,有一页叫做What You Can Do With Ensemble,里面提到一个概念,叫做Composite Application Development。的确,在企业集成领域,人们在搞定数据集成(EII)以后,都会想去搞定业务流程的集成(EAI)。但是,到底哪种业务流程是集成引擎可以碰的,哪种是万万不能碰的呢?也许,SOA已经给出了答案,EAI只能是做一些粗粒度的(比如部门之间的,企业之间的)业务流程;部门内部的,就交给象QA工作站,图像网关这样的东西去处理吧。
ft,不小心又绕回到SOA来了。