教你設計一個最簡單的微服務
原題:《枚舉常量數據字典微服務設計》
作者:汪照輝 王作敬 中國銀河證券股份有限公司 信息技術部IT研發中心
枚舉常量數據字典微服務,是一個基礎的相對簡單的微服務,算是一個起手式。
數據標準化之後,基於這些標準化數據就可以方便地快速地構建服務、組件和應用系統。鑒於每個系統都少不了很多枚舉常量值,所以我們把枚舉枚舉值進行梳理,實現一個枚舉值數據字典微服務,它是一個基礎的相對簡單的微服務,算是一個起手式。
一、數據梳理
第一步就是要對這些枚舉常量進行梳理,一個單體系統梳理起來可能很簡單,但如果多個系統放在一起,同時支持多個系統的枚舉數據字典,就複雜很多。前面我們也提到過,簡單的性別欄位,其取值在不同的系統中就可能有多種,更別說其他複雜的欄位取值了。數據梳理可以採用主數據實施的方法,以一個核心系統數據為基礎,比如說CRM,逐步擴展支持其他系統。枚舉常量數據字典的設計相對簡單很多,把所有欄位的枚舉值都找出來,然後根據實體含義和業務場景進行分析梳理,先實體後元素再取值,主-枝-葉逐步梳理。欄位枚舉取值數據梳理中幾個常見問題需要考慮。
二、欄位名相同,含義不同
在不同系統中,你可能發現,一個相同的欄位名分別在兩個系統中代表不同的含義。比如客戶類型,在不同的系統中可能完全不是一回事。可能是個人客戶、機構客戶等,也可能是普通客戶、金卡客戶等,或者是境內客戶、境外客戶等。這是由於不同場景數據代表的含義不同,有一定的適用範圍。在做數據標準化規範化時,也不能簡單的合併了之。需要考慮其數據域,也就是使用範圍。比如客戶實體在每個域都會存在,但其元素可能會不同,所以即便是相同的元素名稱,其代表的含義可能不同,取值也不同。這樣的問題一般通過域前綴來區分,明確其數據含義。
三、欄位名不同,含義相同
還有就是不同的欄位名卻代表相同的含義,比如Currency和MoneyType都表示貨幣類型,含義和取值都是一樣的,但是卻是兩個不同的命名欄位。我們甚至在同一個系統提供的介面中發現有這樣的命名,給我們的系統服務集成帶來一些小麻煩。相同含義不同命名的欄位需要標準化,映射為統一的標準化名稱。我們做數據梳理、數據標準化不僅僅是為了標準化,更多的應該是一種意識、一種習慣。
四、取值範圍不同
數據域確定,梳理同一域內的數據,你也可能發現,元素相同、含義相同,取值可能不同,就像我們提到的性別,有取(男、女),也有(男、女、其他),或者(男、女、未知)等,這就需要把這些不同的取值基於實際業務實現標準化。但我們基於一個系統要兼容其他系統的標準化字典定義取值範圍可能面臨著幾個問題:
取值範圍小
基準系統的欄位取值範圍可能沒有其他系統的取值那麼多,這種情況下就需要根據實際各系統的取值擴展欄位標準取值範圍。比如基準系統性別是(男、女),另一個系統是(男、女、未知),這就需要將「未知」這個取值添加到「性別」欄位的取值範圍內。中文不同辭彙意思是不一樣的,有差別的,「未知」和「其他」所表示的意思是不一樣的。如果性別取值中還需要表示其他意思,也可以把「其他」添加到「性別」欄位的取值範圍內(不建議這麼做)。
取值範圍大
取值範圍大,這倒相對簡單些,不需要擴展,也就不涉及代碼、配置等的修改。以基準系統的欄位取值範圍作為標準取值範圍就可以了。
取值範圍交叉
取值範圍交叉,這種情況呢是上面兩種情況的結合,基準系統多的可以不管它,少的擴展以支持需要兼容的系統欄位的取值。
五、鍵值編號不一致
鍵值編號不一致倒是也很正常,畢竟不同系統是由不同的人員來開發的,枚舉值鍵值編號沒有統一的標準可以參考,基本上都是開發人員自己來定義,還有不少是硬編碼到代碼中的。我們既要兼容不同的系統,又要標準化,這處理起來稍微麻煩點。不同系統和標準的字典取值需要建立對應的映射關係,根據系統代碼來實現源系統和標準字典之間的轉換。一旦這些舊的歷史遺留系統都被替換,那麼就只有標準字典定義了。
六、編碼不同
還有就是不同系統編碼可能不同,這也是我們需要考慮的一個方面。當然更多是的需要在集成系統的Adapter中來實現轉換。但要實現標準化時,一個公司也需要考慮數據的標準編碼格式。
七、欄位可取多值
最麻煩的可能是枚舉類型在系統中可以同時取多個值,存儲時以分割符分割作為一個String存儲。可能這個欄位是多選的,可以同時取多一個或多個值,這種情況可能連取值範圍都比較難以確定。有時候系統需要先跑起來再說,文檔也不全,或者忘記了,整理起來就比較麻煩些。比如產品的銷售渠道,可以是網站、app、櫃檯等多個渠道。這在轉換時需要根據分割符進行處理。
八、定義數據模型
數據梳理過程中可以逐步定義數據模型,數據字典是全局公用的服務,相對來說也時比較簡單的基礎服務。我們可以定義枚舉值數據字典和字典詳情兩個實體和源系統枚舉值數據字典和字典詳情映射關係模型。
九、確認介面需求
標準化之後,所有新的業務需求都按照標準的字典定義來使用。舊的歷史遺留系統,還需要繼續它們的使命。跟這些系統的集成可以按照ESB的集成方式實現。對枚舉值數據字典服務的介面存在查詢和維護需求,以及源系統字典和標準字典之間查詢和映射轉換需求。因此我們:
1、至少需要提供枚舉值的查詢和標準字典值和源系統字典值之間的轉換服務。
2、提供維護更新操作,可以對數據字典進行添加更新刪除。通常可以提供一個UI來實現;如果存儲在文件中(比如XML文件),可以直接編輯文件。
3、考慮到頻繁操作資料庫或文件不是一種比較好的方式,我們把這些基礎數據在應用服務啟動時載入內存中,如果這些數據發生了變化,需要實現主動更新通知。在數據字典更新後,通知所有的應用服務,更新緩存在內存中的數據字典內容。這樣以client/server的方式實現,類似於配置中心的設計。
十、定義介面API
根據介面需求,我們定義了查詢所有枚舉值數據字典API 和按照sysCode查詢某一系統的枚舉值數據字典的API,按照ID查詢的API,示例如下:
標準字典值和源字典值之間的映射轉換在應用服務中集成數據字典Client模塊實現。
十一、載入內存
數據字典服務是基礎的服務,可以說每個微服務都會用到,這就面臨著頻繁的操作需求。不管使用HTTP restful或者其他方式通信,我們覺得都不是一種很好的方式。從性能方面考慮,為了支撐這樣高頻度的操作,減少不必要的服務調用,可以把數據在啟動時載入內存。實現方式和配置中心數據配置的實現類似。系統初始化時,把相應的系統數據字典信息按照業務應用的需求統一載入到內存,在內存中實現數據字典的查詢和轉換。
十二、自動更新管理
數據字典值發生改變,在不影響運行時服務的情況下,能夠自動更新數據字典枚舉值也可能是一個潛在的需求。其實我們採用配置中心的設計方式來實現枚舉值數據字典服務,也是為了滿足這樣的需求。這樣可以很方便的集成其他系統,或者在舊系統被替換之後方便的從枚舉值數據字典中把過期的信息移除。我們使用的文件來存儲枚舉值數據字典的影射關係,採用配置中心配置更新的設計,由一個任務來監控這個文件的變化,一旦文件改變了,觸發通知機制,通知所有的服務更新其內存中的數據內容。
自動載入內存和自動更新管理都在數據字典client模塊中實現,應用服務僅引用該模塊,使用其提供的數據轉換函數,專註於實現業務應用功能即可。
十三、建立OpenAPI文檔中心
服務實現之後,需要對外開放介面。不管是面向公司內部團隊之間的API,或者面向公司外部的OpenAPI, 都需要提供實現的API文檔說明,以幫助其他團隊成員快速的查找和理解我們公開的API介面用途用法。API描述自身結構的能力是OpenAPI魅力的所在。
互聯網的思維越來越普及,現在項目基本上也都採用互聯網項目的前後端合作的開發形式,後端開發好介面API供前端使用。API介面是標準化的,所以後端也不需要知道這個API介面被誰使用,什麼時候使用。當API介面發布出去,前端的應用基於API文檔描述和API測試來使用API。 前端和後端的聯繫也變成了標準化的API介面。API文檔變得越來越重要,它變成了前後端開發人員聯繫的紐帶。採用微服務,建立OpenAPI文檔中心,對外提供統一的API文檔服務,也是一個需要考慮的問題。
目前Swagger框架一個很強大的OpenAPI文檔管理工具,它是由一系列核心工具支持,用於設計、構建、歸檔RESTful APIs。包括Swagger Editor、SwaggerUI、Swagger CodeGen等工具。它只支持restful API介面。一些API的實現也不一定都是Restful的,其實也沒必要,就像我們前面提到的,枚舉值數據字典也可以在應用初始化是載入內存,這樣更合適。也可能會用到Java API介面或者JMS API介面。根據實際情況來決定就是了。當然要想使用Swagger,必須使用restful API。
到後面你會發現,很多API都已經Deprecated了,這也說明微服務體系已經成熟了。就像蝴蝶,總要經歷從蟲到繭到蝶蛻變,才能成為漂亮的蝴蝶。當然在這個過程並不是一帆風順的,需要做好各項管理和治理工作,最後才能蛻變為蝴蝶而不是成為笨重的蛾子。
十四、最後
我們討論的枚舉常量數據字典微服務只是個相對簡單獨立的一個基礎服務,也可以使用配置中心的思想來實現,不用單獨建立枚舉值數據字典微服務,但我們覺得這是一個理解微服務和嘗試微服務的比較好的切入點。我們ESB實施時實現了一個枚舉常量數據字典服務,但基於性能方面的考慮,數據字典映射轉換的實現是在內存中實現的,畢竟枚舉值數據字典和系統關聯比較大,使用的地方比較多,轉換頻繁,所以我們採用配置中心的設計,在應用初始化時載入內存中,並提供相應的方法來供服務來使用,避免頻繁的遠程調用。


TAG:talkwithtrend |