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