Electron/Nginx/NodeJS/MongoDB开发HIS之架构概述

前言

今年已经2021相信不少人都已经听说过electron了
小弟技术不才,希望可以给台湾医疗资讯带来不一样的选择
在此想提出一个架构可能性,望各位大佬海涵
而小弟的发想其实国外也已有类似的专案:https://hospitalrun.io/
但小弟绝非抄袭
小弟的专案如下https://github.com/teddy1565/HospitalInformationSystem
尚未完成,将来还打算重构,欢迎各位大大指教,小弟虚心接受

为何会想要设计一套新的架构,原因来自於,小弟原先在一家医疗资讯公司服务,工作一阵子後
实在是觉得,原公司的产品错误太多,故此想设计一套解决方案,供大家参考研究。
此专案不营利也欢迎各医院资讯室研究参考。

使用的技术

  • Electron
  • Nodejs
  • Bootstrap
  • Cornerstone/OHIF
  • MongoDB
  • Nginx

架构优点

  • Electron对於设计师技术要求较低
  • 相较於直接操作作业系统API,在Electron框架下操作HTML会更稳定
  • 充足弹性及灵活度,能够因应不同环境
  • 对系统依赖性较低,避免不可预知的错误

过往的缺点

就本人观察,台湾大多数医疗资讯系统皆采用C#开发,尚不论C#及Electron优劣,但C#对设计师的要求较高
需要足够理解作业系统,才能够写出流畅的程序,若仅仅会拖拉写逻辑,这样的设计师开发的程序很容易造成意外,运行上也十分不稳定,时常会发生错误
以我曾从事的公司系统而言

  • OOM
  • DeadLock
  • 各式设计错误
  • IP传输错误
  • 使用者环境导致错误
  • 同步设计导致系统容易出现大型崩溃

架构分析

我先将整体架构拆分成三个部分

  • 使用者
  • 传输过程
  • 後端

设计重点及设计理念

基本上一个软件,在开头设计的时候,这一点深深影响往後的发展
建议任何作戏同行至少看过一次作业系统设计及原理
最重要的几个核心思考是

  • 所有事情都是平行的:
    诚心建议除了特殊的操作外,都采用非同步设计。
    这一点我目前做的不够好所以还会重构
  • 如果还没用到就先不要叫:
    桌面应用不同於服务器,所以每一分效能能省则省
    Electron官方文件有写到,可以利用延後引用的方式,避免在开启的一瞬间载入过多非当下会使用的资讯
    这样的好处是,只有在使用的当下才会去用到相对应要消耗的资源
  • 预处理:
    有已知条件下,可以在背景偷偷先做的就做了。好比医师报告系统,打开时需要载入影像及病人资讯
    这个过程是由Client向DB捞取资料,但如果在一开始打开程序,也确定某些报告要这个医生执行
    那何不预先帮他下载,准备执行。这样当医师要撰写报告时,可以降低很多时间。
    这个功能便需要在意DB的吞吐量,因此我根据作业系统设计的方式设想两种解决方案
    • interrupt handler:当A连线时间太长,或是运用时间超出规定,则先处理其他请求,随後再回来处理原先A的请求
      这样可以增加系统的稳定性,避免单一使用者大量的请求导致瘫痪
    • 预先处理: 设置一些区域的节点,当系统使用量较低时,先传送档案至区域节点,当使用者需要请求资料时,只需要请求区域节点的资料
      这两种方法可以并行,也许有更好的做法,再请教各位大神了

使用者

在使用者操作的部分,使用Electron开发相应的软件,怎麽做其实就跟往常没有不一样,只是换了个框架
有个简单的参考:https://github.com/teddy1565/HospitalInformationSystem
就是让使用者操作的部分
但Electron的好处在於,可以让网页设计师去做一个桌面应用,特别是前端的部分
前端开发框架的强大,让使用者端的程序十分富足
另一个好处就是它的弹性,上面的参考中,所有的按钮功能绝大多数都是透过JSON储存
当要打该这个页面的时候才实时载入,虽然这样的设计,在开发当下会很麻烦,但後续维护会十分容易

同时采用Electron最大的原因还有另一个,在医疗资讯系统中,有三种需求不可或缺

  • DICOM操作浏览,以下提供两种比较後最稳定的几个模组
    事实上DICOM的解析及操作十分复杂,在此无法多作赘述,但以下模组有一定的即战力
    • Cornerstone
    • OHIF
  • 医疗过程的影像撷取
    • 本人认为有两种做法
      • 利用撷取卡厂商提供的SDK写C/C++的程序,NodeJS可以兼容
        这一种做法,以效能来说为最高,但在环境的适应上比较差,会被撷取卡绑定
      • 利用撷取卡厂商提供的SDK写一个能够读取Config并依照设定显示画面的软件
        而这一种做法,能够适应不同的环境,以开发来说只需要开发一个撷取特定画面的视窗
        SDK的部分只需要开发能够读取CONFIG并显示相应画面的程序
        但效能来说较低
  • 图片/PDF/DICOM之间的转挡
    • PDF之转挡可以使用PDFJS
    • DICOM转挡尚未研究

传输过程

过往,院内设备都是一个IP对一个设备,万一停电或是意外,导致IP跑掉。那就没办法正常运作了
所以在参考作业系统设计後,认为在各个设备之间,可以透过一个表去映射实际IP
好比:
A(10.5.xxx.xx) -> B(10.5.xxx.xx)
在过往传输资料时,都是在软件内写上实际IP地址,若IP不对则无法传输资料
但如果透过一个映射表的方式
A如果要传递资讯给B 只需要填入AETitle,向记载IP的节点取得实际IP
这样就可以省去人工管理IP的麻烦

後端

在资料方面打算采用Mongo的原因是,在实务上,其实医疗资讯系统有水平延展性的需求
也正好NOSQL是这方面的专家,这样一来可以解决扩充栏位的麻烦
以实际的例子来说:
某一天突然一个医生要求我们多一个XX时间的栏位,结果弄得鸡飞狗跳,要重新编义程序,重新发布上线
资料库也要全部改掉
或是交换资料:
由於不同系统商之间的格式不同,很多时候需要另外再写一个table就只为了转换资料格式,如果使用NOSQL就可以解决这个问题
事实上这样的情况可以透过NOSQL解决
而DICOM影像则会建议继续采用RDBMS

总结

以上提供了另一种医疗资讯系统的解决方案
不再仅限於C#+MSDB
虽然暂时没有实作教学,但基本方向都有了。
真正实行的技术,以後有机会再补上实行作法,毕竟要弄新工作了XD
有其他不同的选择提供给医院参考
这是国外的实行专案:
https://hospitalrun.io/
https://cornerstonejs.org/
https://ohif.org/

事实上在工作的前段日子,对於台湾医疗资讯系统的落後感到无奈,也可能是自己待的厂商太小
资讯系统商提供的服务品质低下,不够稳定,另一个工程师写的两条Thread都可以打在一起,找了好久自己找不到BUG
看了真的很火很无奈,倒也不是自认多强,只是觉得连基本素质都不具备的工程师写出来的东西
然後被厂商拿去各种唬烂包装,赚一堆钱,然後後续的服务品质有够烂,有够羞愧
当国外的技术不断进步,国内的厂商永远停留十几二十年前,觉得有赚钱就好。
一副我们就是要拿烂东西赚钱的嘴脸,好东西研发太花钱花时机没必要去做。
也可能是本人年不足二十,眼界太小,但真的觉得难怪产业永远不会进步
从小看医生看到大,医疗系统还是那个样
企盼我简单的说明这个设计发想可以给一些有能力的人一些启发或是方向

欢迎各位大老指教


<<:  【如何快速学习新技能 ?】软技能 : 十步学习法

>>:  R语言个人小笔记

TOGAF架构框架

TOGAF由国际标准权威组织The Open Group制定。The Open Group於1993...

从零开始学3D游戏设计:触发式按钮

这是 Roblox 从零开始系列,使用者介面章节的第四个单元,你将学会如何去制作当触发某些条件时才会...

学习笔记:一起进入 PixiJS 的世界 (五)

目前已接触的DisplayObject包含了PIXI.Graphics()的图像绘制、PIXI.Te...

Oracle DB-Link ORA-01017 错误排除

Oracle DB link 出现 ORA-01017:invalid username/passw...

Day 14 在VSCode中使用Azure

前言 由於接下来要开始写到attention和Capsule的实作,主要是会研究一些github或是...