医疗行业多层级复杂网络环境下的消息传输(远程会诊)架构与实现
近期接手一个针对医疗系统远程会诊平台的技术改造工作,这项工作中的一些技术问题颇具代表性,我会在此记录这一工作的过程和技术细节,如果条件允许,会在 GitHub 上开源部分业务无关的纯技术实现,敬请关注。(https://github.com/iccb1013)。
远程会诊平台的应用场景指的是乡镇或县卫生所,在接诊过程中,对疑难问题上报上级医疗机构,由上级医疗机构进行网络诊断并回复诊疗意见,但是这一过程,并不是简单的点对点的关系。
主要特点:
1) 包含多级机构:乡镇、县、区、市、省。由任意一级向上级机构提出远程会诊请求,可以提供远程会诊服务的上级机构可能存在多个。
2) 部署环境复杂,此系统并非统一部署于服务器的云服务,而是在各级别,都可能会部署区域性的服务器(也可以不部署),如县一级部署服务器,服务于县和乡镇,区、市都分别部署各自的服务器。客户端不能跨级别与服务器进行连接。
3) 网络环境复杂,对于医疗机构,其部署服务器和客户端的网络环境可能十分复杂,多层防火墙、专用网络等,同时对于乡镇或县等机构来说,网络质量亦存在十分不稳定的情况。
从我目前收集的问题来,排除BUG和业务逻辑上问题,基础结构上存在的主要问题是:
1)连接不稳定,对网络环境有较大依赖。
2)响应速度慢,容易卡死。
3)主服务重启后下面连接的所有服务都必须跟着重启。
简单分析:
1)既有的远程会诊平台使用的是基于 TCP 长连接的 WebService,现场环境较复杂时,跨过乡镇、区县、市等地的机构时,还需要穿过各内部网络,网络环境较为敏感,依赖性较大。
2)现有的实现方式并没有对多级层的网络消息传输机制进行独立的拆分实现,而是基于 WebService 连接直接实现各业务接口并集成在客户端中进行使用,也就是硬编码。
鉴于以下问题,新的技术架构有以下几点目标:
1)所有连接支持 HTTP 无状态或 TCP 长连接两种方式,由服务端决定采用哪种方式连接。
2)使用 HTTP 方式连接时,消息的向上传输使用 WEB API 接口的方式进行调用,接收回复消息则使用 HTTP 轮循进行。使用 HTTP 方式可最大程度减小整体架构对网络环境的敏感和依赖,同时极为方便系统规模进行横向扩展。
3)使用 TCP 方式连接则可以获得更高的性能,但是对网络环境的要求更为严格,可以在网络环境较好的节点服务器到 Client 端使用。
4)整体结构分为 主服务器、节点服务器、客户端 三层,支持异构的方式连接,如:客户端到节点服务器使用 TCP 方式,节点服务器到主服务器使用 HTTP 方式,或反之,或均采用同样的连接方式都可以,可在现场配置。
5)文件的存储使用独立的文件服务器,可自建或使用公有云服务。独立的文件服务器可避免文件传输对主服务网络带宽的占用,剥离文件存储相关的具体实现,同时独立的 OSS 服务有较低的带宽成本和存储成本优势。
6)对于消息的传输,使用命令封包的方式进行,技术架构不处理任何业务逻辑。命令封包中包括目标节点、目标 Client、要执行的命令和参数等信息,由客户端发出后,经过节点服务器到主服务器,由主服务器分发给指定的目标。支持任意 Client 到任意 Client 的消息传输。在命令的传输中,当发起 Client 和目标 Client 在同一个节点服务器时,支持经过主服务器和不经过主服务器两种方式,可配置需要配置。经过主服务器可实现全局的记录存储审计等功能。
7)所有的消息传输,都使用异步方式,不支持挂起等待的同步方式。当发起端的一条命令发出之后,发起端通过自己的命令接收器处理命令的回复,两者分别运行于不同的线程。
8)与现有服务端实现和客户端的集成,使用提供 SDK 开发包的方式进行,不进行任何代码层面的混合编写,以维持本架构的独立性,便于后期升级维护,以及实有服务和客户端本身在未来重构之后,能够继续无缝兼容本架构。
原文:http://blog.shengxunwei.com/Home/Post/db2c6373-2639-4717-8601-8361d54afbaa