? ? 雖然我沒有實踐過集成平臺,但是技術的原理都是一樣的,什么是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市場會越來越理性,不像過去那樣,把搞定領導做為突破口,越來越不靠譜。