勞雪松
安徽警官職業(yè)學院信息管理系,安徽合肥,230031
“互聯(lián)網(wǎng)+”的時代背景下,校園數(shù)字化、信息化已具相當規(guī)模,校園信息系統(tǒng)及基礎(chǔ)設(shè)施的類型與數(shù)量不斷增加。然而,業(yè)務系統(tǒng)建設(shè)時期各不相同,技術(shù)架構(gòu)、數(shù)據(jù)及通信標準不統(tǒng)一,系統(tǒng)功能的整合、數(shù)據(jù)共享與業(yè)務聯(lián)動等問題成為整個系統(tǒng)的瓶頸。應用云計算技術(shù)的IaaS模式雖可有效提升硬件利用率,但業(yè)務功能快速迭代、運維管理、系統(tǒng)性能等諸多方面仍面臨困難。本文探討如何基于微服務開源框架工具集——Spring Cloud[1],在云計算環(huán)境下開發(fā)與部署校園資源計劃Campus Resource Planning系統(tǒng)[2-3](以下簡稱CRP系統(tǒng))來解決上述問題。
傳統(tǒng)B/S架構(gòu)雖明確分出前后端,但軟件總體架構(gòu)仍是單體架構(gòu),這種架構(gòu)會隨著數(shù)據(jù)量和業(yè)務功能的增加導致其臃腫而引發(fā)效率低下,即使應用諸如負載均衡服務器集群、讀寫緩存服務器集群,IaaS模式等技術(shù)手段,也很難解決其內(nèi)生問題。SOA架構(gòu)中,模塊劃分粒度粗,依賴重型的ESB總線通信與集成,不夠敏捷,在大型系統(tǒng)的實際應用中效果不佳,這些傳統(tǒng)架構(gòu)均不能很好地融入云原生環(huán)境[4]。
私有云技術(shù)可通過IaaS模式解決硬件資源利用率不足的問題,隨著信息系統(tǒng)的不斷擴張,繼續(xù)增加私有云的規(guī)模會導致硬件與管理成本迅速上升。即使采用公有云或混合云部署系統(tǒng),若開發(fā)架構(gòu)本身不具有良好的云原生特性,會導致嚴重的兼容性與低性能,TCO(總擁有成本)本會更高。因此,應選擇具有云原生特性的開發(fā)架構(gòu)構(gòu)建新系統(tǒng),迭代舊系統(tǒng)。
CRP系統(tǒng)總體設(shè)計應遵循以下原則:
(1)CRP系統(tǒng)中的所有業(yè)務模塊都可進行有效的統(tǒng)一管理,根據(jù)需要進行更細粒度的業(yè)務劃分以降低業(yè)務單元自身的復雜性,提高硬件利用率;
(2)開發(fā)架構(gòu)應符合敏捷性要求,功能模塊之間應高內(nèi)聚,低耦合以解決單體架構(gòu)動態(tài)擴展與快速迭代能力不足的問題;
(3)開發(fā)技術(shù)??梢訨AVA體系為主,同時兼容其它技術(shù)棧以利團隊的技術(shù)整合[5];
(4)功能模塊之間應使用簡單、通用的輕量化通信協(xié)議,方便有效利用網(wǎng)絡帶寬,跨平臺,跨語言進行數(shù)據(jù)傳遞;
(5)功能模塊應可在虛擬容器中獨立運行,易于拆裝、快速迭代與橫向擴展,并便于狀態(tài)監(jiān)控和運維管理。
微服務架構(gòu)(Miroservices Architecture)最早由Fred George于2012年3月Agile India大會的演講中提出。后由Martin Fowler于2014年通過網(wǎng)文“Miroservices”[6]得以知名。作為云原生技術(shù)基礎(chǔ),這一先進的分布式開發(fā)框架理論得到廣泛的重視并成為一種趨勢。Spring Cloud是目前微服務開發(fā)架構(gòu)中的事實標準,來源于Spring Resources社區(qū),由Pivotal和Netflix提供主要技術(shù)迭代。除自身一套完整的架構(gòu)以外,其開放性還可兼容眾多工具集和多種開發(fā)語言,云原生特性使其適合部署在PaaS[7]及CaaS等云環(huán)境中。阿里云等國內(nèi)云服務提供商已在大力推廣其云原生生態(tài)[8],使這一開發(fā)技術(shù)在未來有更好的發(fā)展。微服務可獨立運行,架構(gòu)特性使其具有極低耦合性,可快速迭代與橫向擴展,非常適合CRP系統(tǒng)的開發(fā)。
CRP微服務整體架構(gòu)[9]如圖1所示,平臺基礎(chǔ)服務架構(gòu)由微服務注冊中心、配置中心、網(wǎng)關(guān)集群、微服務監(jiān)控中心、消息隊列中間件等組成。微服務框架的一大特點是其組件自身也是微服務,整個基礎(chǔ)框架可使用虛擬化容器技術(shù)[10]在云環(huán)境中分布式自動化部署[11]。平臺通過微服務注冊與配置中心對各微服進行統(tǒng)一管理。業(yè)務模塊只需符合微服務的設(shè)計規(guī)范即可快速整合到CRP平臺中。一個微服務的迭代、開發(fā)、部署、運維等活動不影響整個系統(tǒng)的使用,可方便進行功能擴展與性能縮放。
圖1 CRP微服務核心架構(gòu)
傳統(tǒng)校園信息系統(tǒng)的主要問題在于單體業(yè)務的不易拆分,業(yè)務模塊間的數(shù)據(jù)共享與業(yè)務聯(lián)動困難,而微服務架構(gòu)下,更細粒度的服務劃分能力和基于REST架構(gòu)的服務間簡單通信方式是解決這類問題的有效手段。
4.1.1 REST架構(gòu)基礎(chǔ)實現(xiàn)
微服務架構(gòu)是一種實現(xiàn)RPC的最新技術(shù)方法,整個系統(tǒng)圍繞REST架構(gòu)展開。為保證Restful風格的實現(xiàn),需在CRP項目中創(chuàng)建公共API子項目[12],其主要作用是定義CRP中所有業(yè)務微服務之間的訪問接口標準與傳輸類,該類只定義接口標準,以方便微服務之間的互相調(diào)用與數(shù)據(jù)傳遞。該項目需要根據(jù)所使用的微服務,建立相應的TO類和對應的業(yè)務接口,以下是為CRP中迎新業(yè)務模塊微服務所定義接口的部分關(guān)鍵代碼:
package edu.ahjg.crp.srv;
import java.util.List;
import ahjg.crp.to.YxTO;
public interface IYxSrv {
public boolean add(YxTO to) ;//增加迎新工作
public YxTO get(long Yxno) ;//根據(jù)迎新編號獲取迎新信息
public List
//其他接口略
}
公共API項目建立后,即可直接在各微服務的提供者與微服務消費者之間引入該模塊以方便互訪。
4.1.2 后端微服務的建立
迎新微服務實現(xiàn)的主要步驟如下:在CRP父項目中建立迎新模塊子項目,且在CRP父項目中增加ORM框架依賴配置,根據(jù)需要為微服務配置獨立使用的數(shù)據(jù)庫、數(shù)據(jù)連接池等;在迎新微服務子項目的pom.xml中加入以上公共API依賴、ORM框架依賴等;在Application.yml配置文件中定義數(shù)據(jù)源的相關(guān)屬性,重點在于配置該微服務的訪問端口號,之后便可建立持久化對象與該項目的數(shù)據(jù)訪問對象接口;定義業(yè)務層接口子類以實現(xiàn)具體的業(yè)務功能;定義核心功能的REST控制類;在定義該項目的程序啟動類后即完成該微服務的構(gòu)建。其他業(yè)務微服務依此構(gòu)建。以下是迎新微服務REST控制類的部分關(guān)鍵代碼:
package edu.ahjgxy.crp.restful;
//部分Spring框架標準包導入略
import edu.ahjgxy.crp.dto.YxDTO;
import edu.ahjgxy.crp.service.IYxtSrv;
@RestController
public class YxRest {
@Autowired
private IYxSrv yxSrv ;// 注入迎新業(yè)務
@PostMapping("/yx/add")
public Object get(@RequestBody YxDTO yx) {
return this.yxSrv.add(yx);// 增加迎新信息}
@GetMapping("/yx/get/{yxno}")
public Object get(@PathVariable("yxno") long yxno) {
return this.yxSrv.get(yxno);// 查詢迎新信息}
@GetMapping("/yx/list")
public Object list() {
return this.yxSrv.list() ;}}
4.1.3 前端微服務的建立
前端微服務項目設(shè)計時除引入SpringBoot相關(guān)依賴之外,還需引入crp-api公共接口包,可使用DTO類進行數(shù)據(jù)傳遞。通過定義一個配置類控制器RestTemplate對象來實現(xiàn)WEB端對服務端的RESTFUL調(diào)用。部分關(guān)鍵代碼如下:
package edu.ahjgxy.crp.csm.controller;
import java.util.List;
//部分Spring框架標準包導入略
import org.springframework.web.client.RestTemplate;
import edu.ahjgxy.crp.dto.YxDTO;
@RestController
//定義迎新微服務控制器類
public class YxController {
public static final String YX_ADD_URL =
"http://yx-8801.com:8801/yx/add";
public static final String YX_GET_URL =
"http://yx-8801.com:8801/yx/get";
public static final String YX_LIST_URL =
"http://yx-8801.com:8801/yx/list";
…
@Resource
//注入RestTemplate對象
private RestTemplate;
@GetMapping("/csm/yx/list")
public Object listYxRest() {
return this.restTemplate.getForObject(
YX_LIST_URL,List.class);}
@GetMapping("/csm/yx/get")
public Object getYxRest(long yxno) {
YxDTO yx = this.restTemplate.getForObject(
YX_GET_URL + "/" + yxno,YxDTO.class);
return yx;}
@GetMapping("/csm/yx/add")
//傳輸YxDTO對象
public Object addYxRest(YxDTO yx) {
YxDTO result= his.restTemplate.postForObject(
YX_ADD_URL,yx,YxDTO.class);
return result;}}
以上代碼使用拼接式路徑訪問遠程接口,實際開發(fā)中使用基于Ribbon的Feign[13]技術(shù)可將遠程Restful服務映射為遠程接口,消費端可以通過接口形式實現(xiàn)遠程訪問,從而進一步使代碼結(jié)構(gòu)清晰簡約,并可充分利用Ribbon的負載均衡功能。
4.2.1 微服務的統(tǒng)一管理
CRP系統(tǒng)是一個業(yè)務功能高度集成的信息系統(tǒng),包含眾多微服務,其核心要求就是功能模塊能高度整合,實現(xiàn)統(tǒng)一管理和相互通訊。為方便大量微服務互相調(diào)用,提高整合效率,需在項目中通過Spring Cloud的Eureka服務組件構(gòu)建注冊中心微服務,為CRP系統(tǒng)中的所有微服務統(tǒng)一提供注冊、發(fā)現(xiàn)等管理服務。微服務啟動時會將自己的網(wǎng)絡地址等信息注冊到注冊中心。服務的消費者可以從中心查詢服務的相關(guān)信息,并調(diào)用服務提供者的接口。這一服務是整個系統(tǒng)架構(gòu)的核心關(guān)鍵所在。在各個微服務的application.yml中使用eureka.instance.metadata-map配置項完善相關(guān)注冊信息,方便各個微服務通過注冊中心得到完整的服務信息,從而實現(xiàn)互相調(diào)用;在服務中啟用發(fā)現(xiàn)管理功能可實現(xiàn)對服務狀態(tài)進行監(jiān)聽,對無用的微服務進行清除等操作,同時引入SpringSecurity安全配置功能以保證注冊中心的安全。
4.2.2 微服務配置的統(tǒng)一管理
對于單體或者簡單微服務應用,配置application.yml文件中相應內(nèi)容,通過Profile項切換環(huán)境,即可有效更新服務配置。但對于CRP這類多微服務應用,則需依據(jù)環(huán)境配置進行不同的配置,使其具有運行時動態(tài)調(diào)整能力,并根據(jù)負載情況動態(tài)調(diào)整數(shù)據(jù)源連接池大小及熔斷閾值以提高系統(tǒng)性能并防止雪崩現(xiàn)象。實現(xiàn)動態(tài)更新功能需要使用配置管理組件Spring Cloud config構(gòu)造微服務來為其它微服務提供統(tǒng)一配置管理服務??蓪⑵湓谧灾行淖?并修改配置客戶端微服務的bootstrap.yml。通過將多個配置微服務注冊到EurekaServer中即可實現(xiàn)其高可用性。
負載均衡[14]能力是分布式微服務系統(tǒng)的另一重要核心功能,CRP這種大型分布式系統(tǒng)的業(yè)務量會隨時間、場景的變化而發(fā)生較大變化。如在學期始末,相關(guān)業(yè)務系統(tǒng)負載會短時間內(nèi)劇增,為提高整個系統(tǒng)的高性能與高可用性,負載均衡應從基礎(chǔ)架構(gòu)層面出發(fā),在軟件設(shè)計階段給予充分考慮。微服務架構(gòu)支持主流的負載均衡算法,如輪詢算法、最小連接數(shù)算法等。不同于傳統(tǒng)方式,微服務架構(gòu)通過注冊中心維護微服務清單并配合應用Spring Cloud Ribbon來實現(xiàn)基于客戶端的負載均衡能力。
4.3.1 注冊中心的負載均衡與高可用性
注冊中心是整個CRP分布式微服務系統(tǒng)的樞紐,可通過引入ERUKA-HA機制應保證實現(xiàn)其負載均衡能力。注冊中心負責全部微服務的發(fā)現(xiàn)與管理,在生產(chǎn)環(huán)境中應保證其部署環(huán)境中,Eureka Server分布在兩臺以上的可靠物理主機而非同一物理主機的虛擬運算單元上來保證Eureka-HA機制實現(xiàn)的有效性。Eureka Server其本身也是微服務,要實現(xiàn)HA機制需要修改Eureka項目的pom.xml追加打包相關(guān)插件,通過Maven生成jar包,部署不同的profile配置來運行不同的Eureka服務副本,副本之間互相注冊以實現(xiàn)高可用性與負載均衡。為此,需要對Eureka項目的appplication.yml配置文件中設(shè)置多個profile配置項來支持HA機制。后端微服務在云計算環(huán)境的支持下通過相對簡單的編程,動態(tài)生成更多副本,由此提供可橫向擴展的負載均衡能力。
4.3.2 客戶端負載均衡
客戶端負載均衡是微服務架構(gòu)的重要特性和優(yōu)勢,新生入學時,CRP平臺中的迎新微服務模塊會處于高并發(fā)狀態(tài),可在客戶端微服務添加Spring Cloud的Ribbon組件依賴,在Restfulconfig配置類中追加@LoadBalance注解來整合Ribbon的負載均衡功能以滿足性能需求。在Eureka配合下,Ribbon可自動從注冊中心微服務取得服務提供者地址列表,通過微服務名稱,結(jié)合其內(nèi)置的負載均衡規(guī)則或通過自定義方式委派一個服務提供者實例供客戶端使用,這些服務端微服務可通過多個微服務副本提高并發(fā)性能??蛻舳素撦d均衡由客戶微服務發(fā)起,相較于服務器端負載均衡模式具有更好的擴展性與性能。
CRP系統(tǒng)是校園信息系統(tǒng)的高度整合,在云計算環(huán)境下,這種功能模塊相對獨立又需要高度集成的應用場景[15]非常適合使用具有云原生特性的微服務架構(gòu)構(gòu)建。通過對當前高校信息化系統(tǒng)集成中的難點進行分析,指出校園信息系統(tǒng)中存在的問題,提出以微服務架構(gòu)構(gòu)建校園CRP系統(tǒng)的一般性原則以及部分核心架構(gòu)的設(shè)計與實現(xiàn)方法。其中,以迎新微服務為例,重點論述微服務的建立過程,并對微服務的統(tǒng)一管理、微服務系統(tǒng)負載均衡等的設(shè)計實現(xiàn)與部署進行了論述。