朱義方
(國網上海市電力公司信息通信公司,上海 200072)
微服務構架可以看做是一種軟件架構風格,能夠以開發(fā)一組組小型服務來構建成一個大型應用系統(tǒng)。微服務之間彼此耦合度松散,每個服務都可獨立放置、自我管理,且服務間調用編排靈活。由此構建的ERP 系統(tǒng)內,各微服務模塊即可保持彼此獨立,亦可相互關聯(lián),也能對每個微服務進行單獨部署、測試、和運轉。在服務內部,服務模塊只關心其關聯(lián)業(yè)務的開展,負責ERP 系統(tǒng)中的一個或者多個業(yè)務。
典型的ERP 系統(tǒng)是一個由多個模塊例如銷售管理、庫存管理、物資采購、人資管控、財務管理等組成的企業(yè)信息資源管理系統(tǒng)[1]。初期以IBM 大型機為平臺,主要開發(fā)語言為ABAP,之后推出SAP Net Weaver 平臺,配合單獨的Oracle 數(shù)據(jù)庫,從而形成一個數(shù)據(jù)庫層、應用層、展示層的SAP 三層架構體系[2]。隨著時間的推移,ERP 系統(tǒng)業(yè)務在現(xiàn)代化技術的依托下發(fā)展越來越快,功能不斷完善,流程日益增多,伴隨著開發(fā)人員不斷交替,代碼質量參差不齊,單體式架構下的應用越來越復雜,系統(tǒng)的更新管理、擴展與維護性備受挑戰(zhàn),其弊端逐漸暴露出來。尤其是在進入新時期之后,ERP系統(tǒng)急需一個全新的軟件結構模式來支撐其龐大的架構體系和業(yè)務需求。而近年來逐漸成熟化的云計算和微服務等新興技術架構,恰好能靈活的滿足我們對系統(tǒng)的需求,而且具備更加獨立的運營維護效率[3]。
根據(jù)微服務的架構思想,簡單的將ERP 系統(tǒng)劃分為多個子系統(tǒng),在這些子系統(tǒng)當中,開發(fā)環(huán)節(jié)、部署環(huán)節(jié)、測試環(huán)節(jié)都可以通過不同的團隊來完成,甚至可以由不同的技術棧來完成。這些團隊有不同的技術支撐,子系統(tǒng)只需要完成相關業(yè)務服務,通過Web Service 或RFC 形式的接口輸出即可。同時,這些暴露的接口粒度開發(fā)人員可根據(jù)具體業(yè)務需求、系統(tǒng)擴展需求、靈活性需求來進行綜合性設計。微服務還有另外一個顯著特征,即與單一應用程序的服務方向不同,單一程序根據(jù)層級來定義不同的團隊,如用戶界面、服務器、數(shù)據(jù)團隊等,而微服務是為公司全業(yè)務而服務,不受任何類型局限,這種方式讓團隊具備了跨職的可能,因此,微服務的功能更全面,如用戶體驗、數(shù)據(jù)庫管理、項目管理等[4]。這些功能的出現(xiàn)讓微服務更快融入了生活,使我們進一步走進Dev Ops 時代。此外,在數(shù)據(jù)庫層面,獨立的子系統(tǒng)均具備單獨數(shù)據(jù)庫,數(shù)據(jù)庫的具體設計根據(jù)系統(tǒng)具體需求而定義,可以是關系型數(shù)據(jù)庫,也可以是其他類型的數(shù)據(jù)庫。
微服務架構的核心就是去中心化,集合大量不同的子系統(tǒng),圍繞企業(yè)的需求開展本身業(yè)務以外的其他業(yè)務實現(xiàn),這其中采取的手段不同,實現(xiàn)結果也不同,降低了系統(tǒng)的債務情況,讓系統(tǒng)功能的實現(xiàn)不再依賴某一個框架或者是語言。每個服務技術選型靈活,不受遺留系統(tǒng)的技術約束。即使是一個比較小型微服務系統(tǒng)的升級、重構,也不會對系統(tǒng)的運行產生影響,這給軟件的更新?lián)Q代降低了多種風險[5]。
微服務有自己的邏輯和數(shù)據(jù),能完全獨立部署和運行在一個進程內,通過REST API 架構或RPC 架構,將事件流程與報文代理結合起來,以達到相互協(xié)同的輕量級通信機制。在微服務體系結構中,各個服務是獨立的業(yè)務單位,對領域內可進行自我管理和修復,且不對其他服務功能造成影響。微服務體系中的應用系統(tǒng)包含了許多具有高度自主性的、獨立的商業(yè)實體,能夠在各自的系統(tǒng)中運行,并且能夠很方便地將各種服務配置到不同的主機上,從而達到高度自治和高度分離性。作為單個獨立的微服務,其職責也是單一的,即一個微服務解決一個業(yè)務需求。當某個子系統(tǒng)需要升級,或者是添加額外功能的情況下,只需要對單個子系統(tǒng)進行重構,不需要對整個應用進行編譯和部署了。這種松耦合、自治的系統(tǒng)架構讓應用系統(tǒng)的發(fā)布流程更為可靠、便捷,同時也能降低對系統(tǒng)產生的各類風險,進一步縮短應用的交付周期。
傳統(tǒng)單體架構下的應用系統(tǒng)擴展往往都是水平方向的,例如服務器的擴充,數(shù)據(jù)庫的復制,這確實能夠在一定程度上解決訪問速度緩慢、訪問失敗等故障,但是無法解決根源上存在的問題。在這個過程中會消耗大量資源,系統(tǒng)負荷量也會顯著增加,資源消耗量大幅提升。如果將ERP 系統(tǒng)拆分為一個個微型服務,通過業(yè)務流程對服務進行排列組合,就可以處理更多的工作,或者很容易地進行擴展。這些無狀態(tài)的自治節(jié)點靈活地分布在整體系統(tǒng)中,自由地拓展伸縮,為系統(tǒng)提供了穩(wěn)定且可靠的性能基礎和更加清晰的業(yè)務劃分。
從開發(fā)角度來看,我們還可以嘗試分散服務來擴大服務范圍,管理人員與開發(fā)人員通過業(yè)務需求來確定使用哪種程序語言,而其決定因素是圍繞微服務架構更適合哪一種語言。這也意味著開發(fā)與管理人員可能選擇彼此獨立的數(shù)據(jù)庫,但這也是微服務架構具備的最大優(yōu)勢,即無限拓展性。開發(fā)人員可在微服務部署結束之后根據(jù)自己需要的功能調整即可,而不是每次都要創(chuàng)建語言,節(jié)省了大量的時間和成本。
微服務構架設計的過程中首要任務就是對服務進行拆分,拆分原則多種多樣,但是基本均是圍繞業(yè)務開展的。服務拆分粒度目前并沒有可以借鑒的標準,實際上也沒有統(tǒng)一的標準。因此按照業(yè)務劃分的各個微服務,應該在這個環(huán)節(jié)做到向內聚集,從而減少分布式事務的存在。由于系統(tǒng)的服務力度標準不統(tǒng)一,當服務力度過于粗糙,就會產生耦合的現(xiàn)象,在具體的設計過程中,服務力度也不是以細為好,如果拆分過于細密,系統(tǒng)內部交錯復雜的關系就會增加使用的隱患,而問題發(fā)生后也很難找到根源,增加了系統(tǒng)的不穩(wěn)定性。因此在服務的拆分粒度方面應盡可能保證服務本身的獨立與完整,避免錯綜復雜的交錯現(xiàn)象存在,減少系統(tǒng)之間的依賴性,盡可能避免多層依賴、鏈式調用現(xiàn)象的存在[5]。
由前文可知,服務之間要盡量做到高內聚、低耦合,但無論怎樣,一定不能避免系統(tǒng)中各服務之間的互相調用。所以當服務完成拆分后,就需要處理服務間互相通信的問題。如何使服務間進行最有效便捷的相互調用,是目前微服務架構下眾說紛紜的熱點[6]。當前,已有一些成熟開源的RPC 框架調用使用較為廣泛,如Dubbo、Spring Cloud、gRPC 等,都能夠支持多種調用協(xié)議。這些框架能夠幫助封裝底層數(shù)據(jù)間的通信細節(jié),讓不同微服務之間的通信就像是本地通信一樣簡單快捷。另外,我們也能根據(jù)自身特性開發(fā)適合ERP 系統(tǒng)的調用框架,或與其他技術框架結合使用,才是解決眾多服務間調用交互的根本方法。
基于微服務的靈活性,每個服務都可以有自己的數(shù)據(jù)庫。這對于開發(fā)人員來說大大提高了他們的發(fā)布效率,但如何實施跨服務的事務和查詢以及保持整個系統(tǒng)的數(shù)據(jù)一致性卻不是一件輕松的事,可以說是一把“雙刃劍”。
假設將ERP 系統(tǒng)中某大型業(yè)務分為多個子服務,那么在運行該業(yè)務時,服務與服務之間需彼此通信,遠程協(xié)作后才能輸出最終結果,即完成一整套分布式事務操作[7]。但是如果在服務調用過程中某一個服務突然不可用,或由于網絡問題遠程調用超時,那么服務之間就可能出現(xiàn)數(shù)據(jù)不一致甚至級聯(lián)反應導致整個業(yè)務運行失敗。例如,采購管理系統(tǒng)的業(yè)務實現(xiàn),在材料采購入庫時相應數(shù)據(jù)會寫入庫存管理系統(tǒng)內,系統(tǒng)當前的數(shù)據(jù)為庫存數(shù)據(jù),當材料完成入庫之后,庫存管理系統(tǒng)中的材料數(shù)量就應同步更新。如果在這一整套流程中發(fā)生了某一個節(jié)點的卡頓或夯死,就會造成數(shù)據(jù)鏈斷裂,一旦數(shù)據(jù)出現(xiàn)不一致,就會導致整個業(yè)務邏輯執(zhí)行任務失敗。為保證業(yè)務流程順利進行,我們需要提供更多的服務,如文檔管理、服務治理、服務模擬的工具和框架;實現(xiàn)統(tǒng)一認證、統(tǒng)一配置、統(tǒng)一日志框架、分布式匯總分析;采用全局事務方案、異步模擬同步或搭建持續(xù)集成平臺、統(tǒng)一監(jiān)控平臺等。
ERP 系統(tǒng)的一個主要功能就是使企業(yè)的業(yè)務過程自動化。例如,在客戶發(fā)出訂單后,銷售部會根據(jù)企業(yè)的存貨和生產能力,對客戶的訂單進行審核,如果存貨和生產能力都能滿足,那么就對客戶的定單進行確認,然后按照定單上的產品,向倉庫部提出出貨要求,如果存貨達到了要求,則直接出庫。如果存貨不夠,則由生產部根據(jù)訂單確定生產任務,待產品生產出來后再提交倉庫。
基于微服務的ERP 系統(tǒng)架構可以分為四層,從底層到頂層分別是基礎設施層、微服務層、服務網關層、應用交互層。其中基礎設施層的主要作用是數(shù)據(jù)存儲,由Redis 數(shù)據(jù)庫來提供緩存服務和關系型數(shù)據(jù)庫資源;微服務層的主要作用是為ERP 系統(tǒng)的應用提供聚合微服務和基礎業(yè)務服務,包括銷售管理、生產管理、庫存管理、采購管理、財務管理、訂單服務、支付服務等;服務網關層則主要為ERP 系統(tǒng)的正常運行提供Gateway服務網關和Nginx 反向代理;應用交互層可為用戶和管理人員提供信息數(shù)據(jù)交互使用的功能,如Web View、Web APP、第三方OA 或者是CRM 系統(tǒng)。
設計協(xié)作接口的本質是定義各個銜接上下文的應用服務接口,保證企業(yè)對ERP 系統(tǒng)使用的需求。在微服務框架下,ERP 系統(tǒng)協(xié)作接口可采用事件機制,協(xié)作接口可按照之前確定的上下文映射來獲得。由于每個協(xié)作關系都有一個接口,不同的上下文映射模式可能會影響到接口的設計效果。比如:生產訂單上下文映射時,需要將訂單和系統(tǒng)集成之間的協(xié)作改為事件機制,并詳細記錄和訂單上下文相關的協(xié)作接口。
有時一個服務會對應多個接口,而每個接口所擔任的職責功能可能會有關聯(lián),所以開發(fā)一套簡單又便捷的協(xié)作服務接口是很重要的。我們在設計時應盡可能地減少依賴性,以降低故障發(fā)生的可能,提高服務可靠性。還可以嘗試將一個功能下的接口根據(jù)主次拆分到不同的服務中去,優(yōu)先級高的放在一個服務中,優(yōu)先級低的放在另一個服務中,以減少一個服務不可用導致其所有接口均不可用的情況。
網關是ERP 系統(tǒng)的上層服務,它隔絕了微服務與客戶端的直接通信,所有的外部請求都會先經過網關這一層。傳統(tǒng)單體式架構的ERP 系統(tǒng)通常只開放一個服務給客戶端調用,而微服務架構中服務都是獨立拆分的。當客戶端訪問某個服務時,需要先在本地記錄該微服務的調用地址,如需訪問多個服務,則需要記錄每個微服務的接口地址,這無疑增加了系統(tǒng)的負擔。這時就需要由網關來統(tǒng)一系統(tǒng)入口,即將微服務進行封裝,所有請求經網關合理分配至各微服務,使客戶端只需與網關通信,不必再一一調用其他服務。另外,網關系統(tǒng)還能收集相關監(jiān)控數(shù)據(jù),對訪問請求進行統(tǒng)一認證,控制并發(fā)流量等,為系統(tǒng)的安全加上一把“鎖”。目前市場上使用較多的網關有Zuul、Spring Cloud Gateway、Kong 等,其性能較好,可維護性強,可實現(xiàn)身份認證、內部負載均衡、限流等主要功能。
綜上,微服務架構的優(yōu)勢固然可見,與之而來的困難與挑戰(zhàn)也是關卡重重。所以無論是傳統(tǒng)單體式還是新型微服務架構,我們在使用它之前都需要對其有全面深入的認知,在結合系統(tǒng)本身特性的基礎上認清系統(tǒng)面臨的變革與挑戰(zhàn),而不是為了追求技術而去微服務化。