陳家豪,劉宇杰,宋暉
(東華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)學(xué)院,上海 201620)
隨著社會(huì)的發(fā)展,政府機(jī)構(gòu)產(chǎn)業(yè)經(jīng)濟(jì)的管理部門需要對(duì)所屬區(qū)域內(nèi)的企業(yè)進(jìn)行管理并提供相應(yīng)的服務(wù)。但是面對(duì)轄區(qū)內(nèi)的所有企業(yè),政府難以及時(shí)了解產(chǎn)業(yè)細(xì)分領(lǐng)域的整體情況以及把握企業(yè)發(fā)展運(yùn)行的動(dòng)態(tài)情況和經(jīng)濟(jì)運(yùn)行情況。并且隨著經(jīng)濟(jì)的快速發(fā)展,也暴露了政府在產(chǎn)業(yè)政策扶持以及企業(yè)幫扶等方面的問題。文獻(xiàn)[1]也指出政府在融資、稅收等方面存在資源調(diào)配先國企后民企的現(xiàn)象,這樣就使得民企獲得的支持越發(fā)顯得薄弱。
隨著時(shí)代的發(fā)展與信息技術(shù)的進(jìn)步,云計(jì)算技術(shù)取得了突飛猛進(jìn)的發(fā)展,SaaS(software as a service:軟件即服務(wù))作為云計(jì)算中最為成熟、出名的模式,已得到了廣泛的應(yīng)用。與此同時(shí),SaaS 模式的發(fā)展使得傳統(tǒng)的單體架構(gòu)開發(fā)模式已經(jīng)逐漸無法滿足當(dāng)前互聯(lián)網(wǎng)時(shí)代的軟件開發(fā)需求,于是微服務(wù)架構(gòu)應(yīng)運(yùn)而生。在傳統(tǒng)單體架構(gòu)開發(fā)方式下,應(yīng)用的開發(fā)很簡(jiǎn)單,測(cè)試也相對(duì)簡(jiǎn)單直觀,但是單體架構(gòu)存在很大的局限性,隨著時(shí)間的推移,開發(fā)、測(cè)試、部署和擴(kuò)展都會(huì)變得更加困難。而微服務(wù)架構(gòu)在開發(fā)過程中不僅擁有更好的容錯(cuò)性,其最大的好處就是可以實(shí)現(xiàn)大型復(fù)雜應(yīng)用程序的持續(xù)交付和部署[2]。
本文針對(duì)政府管理部門為企業(yè)提供服務(wù)過程中存在的問題,基于SaaS 軟件服務(wù)模式以及微服務(wù)架構(gòu)設(shè)計(jì)并實(shí)現(xiàn)了產(chǎn)業(yè)經(jīng)濟(jì)信息的管理,助力政府借此平臺(tái)增強(qiáng)產(chǎn)業(yè)結(jié)構(gòu)調(diào)整的準(zhǔn)確性,促進(jìn)產(chǎn)業(yè)結(jié)構(gòu)的轉(zhuǎn)型升級(jí)[3]。該系統(tǒng)依靠SaaS 的多重租賃的特性[4],完成平臺(tái)由單一用戶到多租戶的轉(zhuǎn)變,并且結(jié)合微服務(wù)架構(gòu)服務(wù)獨(dú)立擴(kuò)展、獨(dú)立部署的優(yōu)點(diǎn),靈活的對(duì)功能服務(wù)進(jìn)行擴(kuò)展。
微服務(wù)架構(gòu)是一種面向服務(wù)的架構(gòu),可將應(yīng)用程序構(gòu)建為松耦合、可獨(dú)立部署的一組服務(wù),每個(gè)服務(wù)都是獨(dú)立的進(jìn)程,可以由不同團(tuán)隊(duì)開發(fā)維護(hù),實(shí)現(xiàn)團(tuán)隊(duì)的自治。通過對(duì)當(dāng)下主流的微服務(wù)架構(gòu)進(jìn)行對(duì)比分析,本文選用Spring Cloud[5]作為系統(tǒng)的微服務(wù)架構(gòu)。Spring Cloud 是若干框架的集合,通過提供一系列開發(fā)組件幫助開發(fā)者迅速搭建一個(gè)分布式的微服務(wù)系統(tǒng),其常用組件包括服務(wù)注冊(cè)和發(fā)現(xiàn)、配置中心、路由網(wǎng)關(guān)、控制總線、熔斷器等。
為實(shí)現(xiàn)系統(tǒng)在只有一個(gè)應(yīng)用實(shí)例的情況下能被多區(qū)域政府共同使用,本文采用多租戶技術(shù)對(duì)其進(jìn)行改進(jìn)。多租戶[6]是SaaS 領(lǐng)域的特有產(chǎn)物,是SaaS 服務(wù)模式與傳統(tǒng)軟件模式的重要差別。多租戶技術(shù)是用于實(shí)現(xiàn)在同一環(huán)境下多租戶可以共用相同的系統(tǒng)或者程序組件,并仍然可以保證租戶之間的數(shù)據(jù)隔離性。多租戶數(shù)據(jù)隔離的方式有以下三種:第一是獨(dú)立數(shù)據(jù)庫,第二是共享數(shù)據(jù)庫但隔離數(shù)據(jù)結(jié)構(gòu),第三是共享數(shù)據(jù)庫和數(shù)據(jù)結(jié)構(gòu)。本系統(tǒng)中采用的是第一種方式,在創(chuàng)建租戶時(shí)為其創(chuàng)建專屬的數(shù)據(jù)庫并完成數(shù)據(jù)庫的初始化,雖然該方式成本最高,但是數(shù)據(jù)的隔離級(jí)別和安全性也是最高的。采用多租戶技術(shù),可以將系統(tǒng)角色分為三種:平臺(tái)管理員、租戶系統(tǒng)管理員以及租戶普通管理員。多租戶業(yè)務(wù)流程如圖1所示。平臺(tái)管理員可通過初始化租戶組和權(quán)限信息完成租戶的創(chuàng)建,啟用租戶后由該租戶的租戶系統(tǒng)管理員對(duì)租用的系統(tǒng)進(jìn)行管理,租戶系統(tǒng)管理員也可以創(chuàng)建普通管理員用戶。
圖1 多租戶業(yè)務(wù)流程
本文通過動(dòng)態(tài)切換數(shù)據(jù)庫的方式來實(shí)現(xiàn)SaaS服務(wù)模式并保證多租戶之間數(shù)據(jù)的隔離性,讓每個(gè)用戶在使用本系統(tǒng)的時(shí)候,只能訪問其所屬租戶的數(shù)據(jù)庫。動(dòng)態(tài)切換數(shù)據(jù)庫,其本質(zhì)是通過切換數(shù)據(jù)源來實(shí)現(xiàn)連接不同數(shù)據(jù)庫,最常用的做法是在配置文件中配置多個(gè)數(shù)據(jù)源,在固定數(shù)目的數(shù)據(jù)源之間進(jìn)行切換連接,但本文所使用的方式可以實(shí)現(xiàn)在數(shù)目不限的數(shù)據(jù)源之間進(jìn)行切換,切換過程如圖2所示。具體實(shí)現(xiàn)可分為以下3步。
圖2 動(dòng)態(tài)切換數(shù)據(jù)庫流程
(1)修改配置文件。在配置文件application.yml中配置數(shù)據(jù)源時(shí),將JDBC URL 中數(shù)據(jù)庫的IP和名稱等信息使用“%s”占位符代替,用于在連接數(shù)據(jù)庫時(shí)進(jìn)行動(dòng)態(tài)填充。租戶所對(duì)應(yīng)的數(shù)據(jù)源信息在創(chuàng)建租戶時(shí)就已保存于Redis緩存中。
(2)攔截請(qǐng)求。使用Spring 的AOP 特性來攔截用戶請(qǐng)求,通過獲取用戶請(qǐng)求的域名來判斷對(duì)應(yīng)的租戶,并且對(duì)應(yīng)的租戶編碼保存至ThreadLo?cal線程變量中。
(3)創(chuàng)建并管理數(shù)據(jù)源。在項(xiàng)目中創(chuàng)建Data?SourceConfig 配置類,通過使用由DataSource 派生的子類DynamicDataSource 實(shí)現(xiàn)根據(jù)配置參數(shù)創(chuàng)建數(shù)據(jù)源,并完成數(shù)據(jù)庫的動(dòng)態(tài)連接。同時(shí)增加數(shù)據(jù)庫標(biāo)識(shí)類,從ThreadLocal 變量中獲取租戶編碼,根據(jù)此租戶編碼到Redis 數(shù)據(jù)庫中獲取對(duì)應(yīng)的數(shù)據(jù)源信息。對(duì)于配置文件中使用占位符替換掉的數(shù)據(jù),則使用該數(shù)據(jù)源信息進(jìn)行一一填充,形成完整的數(shù)據(jù)源,進(jìn)而連接數(shù)據(jù)庫。同時(shí)還可將已建立連接的數(shù)據(jù)源保存在Map 容器中,提供數(shù)據(jù)源的查詢和刪除功能。并且設(shè)置定時(shí)任務(wù)管理數(shù)據(jù)源,將當(dāng)前時(shí)間與最近使用時(shí)間進(jìn)行比較,若在一個(gè)空閑時(shí)間周期內(nèi)沒有訪問,則將對(duì)應(yīng)的數(shù)據(jù)庫連接關(guān)閉,并將數(shù)據(jù)源從Map容器中刪除。
將傳統(tǒng)的單體應(yīng)用轉(zhuǎn)變?yōu)槲⒎?wù)應(yīng)用,最重要的就是進(jìn)行服務(wù)的拆分。進(jìn)行服務(wù)拆分有兩種方法:第一種是使用領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)的方法,根據(jù)子域進(jìn)行服務(wù)拆分,第二種是根據(jù)業(yè)務(wù)能力進(jìn)行服務(wù)拆分。本文采用第二種方法,根據(jù)業(yè)務(wù)能力來定義服務(wù),同時(shí)根據(jù)服務(wù)屬性將其分為輔助型服務(wù)和業(yè)務(wù)型服務(wù),其中輔助型服務(wù)是指基于Spring Cloud框架所提供的用于構(gòu)建分布式微服務(wù)系統(tǒng)的常用組件所實(shí)現(xiàn)的服務(wù),業(yè)務(wù)型服務(wù)則是指根據(jù)系統(tǒng)功能所劃分的服務(wù)。具體服務(wù)劃分如下。
輔助型服務(wù)主要包含以下4 個(gè)服務(wù):①配置管理服務(wù),主要負(fù)責(zé)對(duì)分布式系統(tǒng)的各模塊的配置文件進(jìn)行統(tǒng)一管理。②監(jiān)控服務(wù),主要負(fù)責(zé)監(jiān)控所有服務(wù)的健康狀況,并可對(duì)服務(wù)中的請(qǐng)求進(jìn)行鏈路追蹤。③網(wǎng)關(guān)服務(wù),主要負(fù)責(zé)接收外界所有請(qǐng)求,并將其轉(zhuǎn)發(fā)至對(duì)應(yīng)的微服務(wù)。④服務(wù)注冊(cè)與發(fā)現(xiàn)服務(wù),主要負(fù)責(zé)提供服務(wù)的注冊(cè)與續(xù)約功能。
業(yè)務(wù)型服務(wù)包含以下7 個(gè)服務(wù):①產(chǎn)業(yè)數(shù)據(jù)匯集服務(wù),負(fù)責(zé)將政府提供的產(chǎn)業(yè)數(shù)據(jù)與外部采集的企業(yè)數(shù)據(jù)匯聚于一起,通過智能統(tǒng)計(jì)、數(shù)據(jù)分析等方式為政府制定管理措施、開展企業(yè)服務(wù)提供數(shù)據(jù)支撐。②企業(yè)管理服務(wù),主要負(fù)責(zé)提供如企業(yè)建議、企業(yè)活動(dòng)、企業(yè)支持等政府為企業(yè)服務(wù)提供的功能。③消息發(fā)布服務(wù),主要負(fù)責(zé)為提供政府發(fā)布新聞、政策、知識(shí)庫等功能,方便企業(yè)了解政府的政策法規(guī)。④授權(quán)與認(rèn)證服務(wù),負(fù)責(zé)獲取當(dāng)前登錄用戶信息并進(jìn)行用戶身份驗(yàn)證,同時(shí)還對(duì)系統(tǒng)資源進(jìn)行權(quán)限管理。⑤組織管理服務(wù),包括租戶管理與用戶管理,主要負(fù)責(zé)租戶的創(chuàng)建與權(quán)限初始化,以及對(duì)各租戶下使用該平臺(tái)的用戶進(jìn)行管理。⑥系統(tǒng)管理服務(wù),主要負(fù)責(zé)對(duì)系統(tǒng)用戶組、角色、部門以及權(quán)限等信息進(jìn)行管理。⑦日志服務(wù),負(fù)責(zé)通過RabbitMQ 接收其他服務(wù)所發(fā)送的日志信息并對(duì)其進(jìn)行處理。
本系統(tǒng)基于前后端分離開發(fā)模式,前端使用Vue 與Element UI 進(jìn)行開發(fā),后臺(tái)則采用Spring Boot 作為單個(gè)服務(wù)的開發(fā)框架,使用Spring Cloud架構(gòu)進(jìn)行服務(wù)治理。系統(tǒng)采用Eureka 作為服務(wù)注冊(cè)與發(fā)現(xiàn)中心,給客戶端提供一個(gè)可用的服務(wù)注冊(cè)列表,負(fù)責(zé)完成服務(wù)的注冊(cè)、續(xù)約功能;使用Ribbon 和Feign 實(shí)現(xiàn)服務(wù)的調(diào)用以及負(fù)載均衡的功能;使用Spring Cloud Zuul 作為系統(tǒng)的服務(wù)網(wǎng)關(guān);使用Spring Cloud Config 進(jìn)行分布式配置文件的統(tǒng)一管理。除此之外,還使用Spring Security OAuth2保護(hù)微服務(wù)系統(tǒng),并同時(shí)使用JWT的方式進(jìn)行身份認(rèn)證。系統(tǒng)總體架構(gòu)設(shè)計(jì)如圖3 所示,自上而下依次分為訪問層、網(wǎng)關(guān)層、服務(wù)層以及數(shù)據(jù)層。①訪問層作為系統(tǒng)的使用入口,負(fù)責(zé)用戶對(duì)系統(tǒng)的操作和系統(tǒng)前端界面顯示。②網(wǎng)關(guān)層選用Spring Cloud Zuul 組件,負(fù)責(zé)所有服務(wù)的API接口統(tǒng)一聚合,并統(tǒng)一對(duì)外暴露。來自客戶端的所有外部請(qǐng)求在進(jìn)入系統(tǒng)時(shí),都要通過網(wǎng)關(guān)層進(jìn)行處理,由網(wǎng)關(guān)將其轉(zhuǎn)發(fā)至對(duì)應(yīng)的服務(wù)。③服務(wù)層作為系統(tǒng)的核心業(yè)務(wù)層,負(fù)責(zé)完成系統(tǒng)的核心功能,各個(gè)服務(wù)之間通過使用基于同步請(qǐng)求/響應(yīng)的HTTP REST 機(jī)制進(jìn)行通信,并使用Eureka服務(wù)認(rèn)證與注冊(cè)中心對(duì)所有服務(wù)進(jìn)行統(tǒng)一管理。④數(shù)據(jù)層負(fù)責(zé)對(duì)底層數(shù)據(jù)進(jìn)行訪問以及持久化操作,所使用的數(shù)據(jù)庫包括MySQL、Redis 以及Mon?goDB。數(shù)據(jù)層同時(shí)還負(fù)責(zé)對(duì)數(shù)據(jù)源進(jìn)行動(dòng)態(tài)管理,通過動(dòng)態(tài)切換數(shù)據(jù)源的方式使得租戶只能使用自己的數(shù)據(jù)源連接自己的數(shù)據(jù)庫,保證數(shù)據(jù)之間的隔離性。
圖3 系統(tǒng)架構(gòu)
為使系統(tǒng)后期具有較高的維護(hù)和擴(kuò)展能力,本系統(tǒng)選擇使用容器技術(shù)在服務(wù)端進(jìn)行項(xiàng)目部署。容器是一種更現(xiàn)代、更輕量級(jí)的部署機(jī)制,與虛擬機(jī)技術(shù)相比所消耗的資源更少。本文選用容器中最有代表性的Docker[7]進(jìn)行項(xiàng)目部署。使用Docker 技術(shù),不僅可以實(shí)現(xiàn)系統(tǒng)的快速交付與部署,而且其兼容性與輕量級(jí)特性可以輕而易舉的實(shí)現(xiàn)應(yīng)用的動(dòng)態(tài)管理。
為完成系統(tǒng)上線,采用四臺(tái)操作系統(tǒng)為Cen?tOS 的Linux 服務(wù)器進(jìn)行項(xiàng)目部署,并在服務(wù)器中安裝好Docker。每臺(tái)服務(wù)器所肩負(fù)的職責(zé)各不相同,具體分工如表1所示。
表1 服務(wù)器職責(zé)分工
Spring Cloud 應(yīng)用是采用Spring Boot作為單個(gè)服務(wù)的開發(fā)框架,而由于Spring Boot 內(nèi)置了Tom?cat服務(wù)器,因此系統(tǒng)的各個(gè)服務(wù)模塊都可以將其以jar 包的方式獨(dú)立運(yùn)行。系統(tǒng)部署如圖4 所示。將每個(gè)服務(wù)打包成鏡像容器,再按照服務(wù)器職責(zé)分工將服務(wù)部署到對(duì)應(yīng)的服務(wù)器上。
圖4 系統(tǒng)部署
將服務(wù)部署為容器的操作如下:對(duì)于系統(tǒng)的每個(gè)服務(wù)模塊,在本地機(jī)器上使用Maven 將其打成jar 包,然后將jar 包上傳到服務(wù)器上,通過編寫包含構(gòu)建鏡像所需指令的Dockerfile文件,使用docker build 命令將其構(gòu)建為鏡像并保存在鏡像倉庫中,最終根據(jù)鏡像文件生成容器并運(yùn)行服務(wù)實(shí)例。
為實(shí)現(xiàn)政府對(duì)其區(qū)域內(nèi)的產(chǎn)業(yè)經(jīng)濟(jì)發(fā)展提供更好的保障,本文設(shè)計(jì)實(shí)現(xiàn)了產(chǎn)業(yè)經(jīng)濟(jì)數(shù)據(jù)管理系統(tǒng),助力政府更好的為企業(yè)提供服務(wù)。根據(jù)業(yè)務(wù)能力對(duì)系統(tǒng)進(jìn)行服務(wù)劃分,拆分出多個(gè)可執(zhí)行微服務(wù),并通過使用Spring Cloud作為系統(tǒng)的微服務(wù)框架,構(gòu)建了具有較高擴(kuò)展性的軟件系統(tǒng)。同時(shí)基于SaaS 服務(wù)模型完成系統(tǒng)的多租戶功能,實(shí)現(xiàn)對(duì)多地政府提供系統(tǒng)租用服務(wù)。在以后還可以推出企業(yè)畫像、資質(zhì)校驗(yàn)等服務(wù),進(jìn)一步幫助政府了解企業(yè),并利用微服務(wù)架構(gòu)以及Docker 的特性實(shí)現(xiàn)服務(wù)的快速上線。