虽然我没有实践过集成平台,但是技术的原理都是一样的,什么是SOA、ESB、消息队列等等知识都是从网上获取到。我们都知道,学习一门技术,只要把原理搞懂了,就“一通百通”。我之前写过《如何成为写SQL高手》文章,里面提到的帮小伙伴分析的sql问题,我也不知道他们用的是什么his系统,都是从原理岀发来解决。
一、信息系统问题的大小
我们经常听到有人说,有很多问题,大问题、小问题、难问题、简单问题。首先从计算机专业人士,如何定义一个信息系统问题大小。从很宏观的角度,我个人建议用“数据量”来衡量一个问题的大小。我举个例子,对数据进行排序这个问题,当数据量很小的时候,基本调用一下编程语言提供的sort函数就可以了;当数据量有几十个GB,甚至几个TB,你还能调用一下sort处理吗?显然不行,数据量越大,处理的难度越大。
数据量大小如果没有超过“内存”称为“内存级”问题;数据大小超过“内存”,但是没有超过硬盘称为“硬盘级”问题;数据量大小超过“硬盘”称为“大数据级”数据,也就就是分布式要解决的问题。看似同一个问题,从“内存级”到“硬盘级”再到“大数据级”,难度只会越来越越大。
举个例子,实时统计医院消耗前10的药品,大部分医院解决方案就是一条sql语句就能搞定,没必要搞的太复杂,否则“杀鸡用牛刀”,得不偿失。某大型电商,实时统计前10销售的商品,通常是“大数据级”的问题,就没这么简单了。
我再举个曾经开过我“脑洞”的例子,英文句子倒置,比如把“Welcome to HIT meeting”变成“meeting HIT to Welcome”,我用java编写的示例代码如下:
第一种方法 第二种方法特别说明 , 以上代码没有在实际环境中运行过,我最重要的是把套路说明白。第一种方法,98%的人都可以想到,学了几十年的英文,英文句子不就是由单个单词组成,先把拆分句子得到单词,再组装起来。第二种方法,打破惯性认识,在计算机里面“Welcome to HIT meeting”就不要当成英文句子来看待,而是一个String,先将这个String反转过来变成“gniteem TIH ot emocleW”,再进行相应处理。
或许你会问,2种代码用哪种都无所谓,如果你在“内存级”层面,当然无所谓;如果你在“大数据级”层面,第二种明显优于第一种,少了一个数组开销,意外着每次在内存中可以多加载一些“数据”,提高效率。据说这是某大厂的面试题,当时知道这种处理方式,真是开“脑洞”,很多时候我们处理问题的确是受这种惯性思维的影响。
集成平台主要用作数据实时交换,大部分医院除去影像图片,当日HIS数据量不会超过几个GB,大部分医院集成平台问题属于“内存级”的。
二、同步与异步
不理解同步与异步,就很难理解在集成平台下开发HIT“难”在哪里。据小伙伴反应,大量厂商接入集平台使用同步调用,这可能造成集成平台崩溃的“元凶”,我个人没有实践过,所以没有发言权。同步与异步是一个非常重要的概念,值得好好普及一下。从专业视角来看待这个问题,一般称之为,同步阻塞,异步非阻塞。它们之间有什么区别,我用挂号伪代码,举例说明,如下图所示。
同步与异步以上面代码为例 ,同步,“写数据库”就不能同时“发送消息”,这样形成阻塞。异步,“写数据库”与“发送消息”同时执行,就是非阻塞。同步调用,简单粗暴,我不做过多讨论。重点来讨论异步,异步的好处高并发,缺点也十分明显,对系统失去控制,而且异步要比同步实现起来要复杂许多,优先使用同步调用是最保险的方案。
在异步模式,为什么会失去控制?假设“写数据库”失败了,“发送消息”成功了,或者是数据库”成功了,“发送消息”失败了,这就是失控;又比如“写数据库”与“发送消息”同时执行,究竟是什么时候执行完成的,这也是失控。第一个问题,业务逻辑中尽可能规避了“写失败”的风险,万一写失败了,要有日志记录,并通知管理员,或者是业务重试。第二个问题,一般会注册一个回调函数来反馈给主程序。
集成平台,最核心的功能服务通过“消息队列”来订阅/发布(Subscribe/Publish),对应软件设计模式是观察者模式,典型异步调用,在下面中详细分析如何解决“失控性”问题。
三、基于“集成平台"开发基本问题模型
假设某医院,存在以下的最基本的业务模型,患者挂号成功以后,将"挂号消息"推送至”微信“和”医生就诊“。
基本业务模型挂号业务成功以后,向消息队列发一个消息,这个消息我们采用一个专用的术语叫”主题(Topic)“。假设”医生就诊服务“,成功获取到”挂号“并处理成功,或者明确失败,返回给调用方,这2个问题都好处理。
但是有一个问题比较难处理,”医生就诊服务“超时,不知道是成功,还是失败?难点就在这里,一旦发生超时,一般会选择重发”消息“,解决这种问题,有一个专业的术语叫”幂等“。 什么是幂等(Idempotency)?简单来说,一个操作如果多次任意执行所产生的影响,均与一次执行的影响相同,我们就称其为幂等。举例说明,查询账户余额,查询一次和多次区别都一样,这就是一个”幂等“操作。假设往账户上面增加100元,操作一次和多次,区别就很大,这个就不是幂等操作了,怎么实现幂等,可以从业务逻辑代码入手,先查询账户余额,再判断要不要加100元。如果发生超时了,先判断前后两次账户余额是否一致,如果不一致,说明之前操作没成功,一致说明之前的操作是成功的。
怎样保证幂等,一般来说有3种方法,第一种方法,可以数据库表增加键约束;第二种方法,业务代码实现幂等,有时非常难;第三种方法,实现一个通用幂等框架,赋予每个业务操作一个全局唯一的”幂等号“,根据幂等号判断是否执行成功,非常难。
如果发生业务超时,不是每个服务自动做”幂等“处理,有时候会直接抛给用户决定是否重试。
最后小结,传统这种C/S架构,这种业务并发通常由”数据库“来保证的,开发相对比较容易。而基于”集成平台“环境的HIT软件,经过我前面的描述,其实是有难度的,难点如何实现“幂等”。但是”集成平台“问题也没有大到阿里的“双11”、京东“618”可能同时在线用户超过1个亿,基本属于“内存级”的。如果面对有难度的开发,his还是保持“粗、糙、猛、快”习惯,把开发生产当流水线,最后结果是用户不满意,工程师骂街,领导发飚,最后只能选择”分手“。HIT市场会越来越理性,不像过去那样,把搞定领导做为突破口,越来越不靠谱。
网友评论