iT邦幫忙

1

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
看了真的很火很無奈,倒也不是自認多強,只是覺得連基本素質都不具備的工程師寫出來的東西
然後被廠商拿去各種唬爛包裝,賺一堆錢,然後後續的服務品質有夠爛,有夠羞愧
當國外的技術不斷進步,國內的廠商永遠停留十幾二十年前,覺得有賺錢就好。
一副我們就是要拿爛東西賺錢的嘴臉,好東西研發太花錢花時機沒必要去做。
也可能是本人年不足二十,眼界太小,但真的覺得難怪產業永遠不會進步
從小看醫生看到大,醫療系統還是那個樣
企盼我簡單的說明這個設計發想可以給一些有能力的人一些啟發或是方向

歡迎各位大老指教


尚未有邦友留言

立即登入留言