文/王楊帥
單體架構(gòu)的MES在通用性上的不足,很難適應(yīng)市場(chǎng)需求;各個(gè)模塊緊密耦合對(duì)系統(tǒng)的升級(jí)和維護(hù)帶來了巨大挑戰(zhàn)?;谖⒎軜?gòu)的MES根據(jù)企業(yè)的需求按照業(yè)務(wù)進(jìn)行服務(wù)劃分,形成積木式拼接系統(tǒng),如何做到MES中各個(gè)微服務(wù)之間有效調(diào)用成為了關(guān)鍵。本文提出基于WebClient的聲明式服務(wù)調(diào)用框架,簡(jiǎn)化了服務(wù)間的調(diào)用邏輯;調(diào)用方只需定義一個(gè)HTTP客戶端接口就可以實(shí)現(xiàn)代理類去實(shí)現(xiàn)遠(yuǎn)程資源調(diào)用。
根據(jù)制造企業(yè)業(yè)務(wù)進(jìn)行建模,一個(gè)MES按照業(yè)務(wù)可以分為訂單管理、工藝管理、生產(chǎn)排產(chǎn)、過程管控、質(zhì)量管理等制造服務(wù)。微服務(wù)架構(gòu)的MES靈活地根據(jù)業(yè)務(wù)選擇某些制造服務(wù)來快速定制一個(gè)系統(tǒng),在實(shí)際生產(chǎn)環(huán)境中根據(jù)客戶需求對(duì)服務(wù)進(jìn)行增減操作來實(shí)現(xiàn)MES的個(gè)性化定制,微服務(wù)的MES可以縮短開發(fā)周期、降低企業(yè)維護(hù)成本。
微服務(wù)架構(gòu)的MES中的各個(gè)微服務(wù)之間可以通過接口調(diào)用的方式來對(duì)外提供服務(wù)的,所以必須服務(wù)間的正常通信。Rest方式的服務(wù)調(diào)用方式對(duì)消費(fèi)者而言僅需通過一個(gè)HTTP客戶端就可以遠(yuǎn)程訪問服務(wù)資源,對(duì)于提供者而言只需在控制層開啟Rest功能即可。例如:提供方暴露的接口為/car/{carId}時(shí),消費(fèi)端只需利用HTTP客戶端請(qǐng)求http://IP:port/car/007 就可以獲取到服務(wù)提供方提供的服務(wù)資源。
基于Restful風(fēng)格的同步HTTP客戶端實(shí)現(xiàn)方式主要有HttpClient、RestTemplate。
HttpClient提供了基于HTTP協(xié)議的客戶端工具包,實(shí)現(xiàn)了HTTP全部類型的請(qǐng)求方法,同時(shí)也支持HTTPS協(xié)議。請(qǐng)求遠(yuǎn)程服務(wù)資源時(shí)繁瑣的步驟,需要根據(jù)不同的HTTP請(qǐng)求類型創(chuàng)建請(qǐng)求實(shí)例,在通過HttpClient對(duì)象去執(zhí)行請(qǐng)求實(shí)例,對(duì)獲取到的數(shù)據(jù)還必須進(jìn)行解析與封裝,在獲取到遠(yuǎn)程服務(wù)服務(wù)資源后還必須關(guān)閉相關(guān)的鏈接。
RestTemplate是在客戶端訪問遠(yuǎn)程服務(wù)的一個(gè)核心類,通過提供回調(diào)方法和允許配置信息轉(zhuǎn)換器來實(shí)現(xiàn)個(gè)性化定制功能,可以封裝請(qǐng)求對(duì)象,也可以對(duì)響應(yīng)對(duì)象進(jìn)行解析。使用其調(diào)用遠(yuǎn)程服務(wù)資源時(shí),只需要在業(yè)務(wù)類中依賴注入RestTemplate實(shí)例并調(diào)用不同類型的請(qǐng)求方法即可。
WebClient 是一個(gè)非阻塞、響應(yīng)式的HTTP客戶核心類,它以響應(yīng)式被壓流的方式執(zhí)行HTTP請(qǐng)求;非阻塞和響應(yīng)式特性使其可以用少量的線程數(shù)處理高并發(fā)的HTTP請(qǐng)求。
利用同步HTTP客戶端請(qǐng)求服務(wù)資源時(shí)都必須手動(dòng)封裝客戶端,很容易造成很多重復(fù)的編碼。本文主要簡(jiǎn)述基于WebClient實(shí)現(xiàn)一個(gè)聲明式的REST客戶端來解決MES中各個(gè)微服務(wù)之間的異步通信問題,簡(jiǎn)化MES遠(yuǎn)程服務(wù)資源調(diào)用的同時(shí)讓整個(gè)MES實(shí)現(xiàn)異步調(diào)用遠(yuǎn)程服務(wù)資源。
只需要定義服務(wù)接口進(jìn)行資源調(diào)用,具體的實(shí)現(xiàn)方式由動(dòng)態(tài)代理實(shí)現(xiàn)。該框架利用反射機(jī)制去獲取服務(wù)接口信息,再利用動(dòng)態(tài)代理創(chuàng)建客戶端實(shí)例,最后將實(shí)例動(dòng)態(tài)注冊(cè)到IOC容器中實(shí)現(xiàn)。在消費(fèi)方只需要依賴注入服務(wù)接口實(shí)例,并調(diào)用具體方法就可以實(shí)現(xiàn)遠(yuǎn)程服務(wù)調(diào)用。整體架構(gòu)圖如圖1所示。
創(chuàng)建@ Rest 注解,該注解的主要功能是用來聲明服務(wù)接口用的,它是遠(yuǎn)程服務(wù)客戶端接口的唯一標(biāo)識(shí)。遠(yuǎn)程服務(wù)的IP和端口都由它的value屬性指定。
利用自定義的Rest注解以及Spring提供的控制層注解來定義客戶端接口,該接口中的每一個(gè)方法都對(duì)應(yīng)一個(gè)遠(yuǎn)程資源,每個(gè)方法的具體實(shí)現(xiàn)由動(dòng)態(tài)代理實(shí)現(xiàn)。控制層注解的value屬性用于指定資源相對(duì)路徑,同時(shí)在方法簽名中可以定義請(qǐng)求信息。
利用反射機(jī)制獲取客戶端接口類類型,并利用反射機(jī)制獲取遠(yuǎn)程資源的服務(wù)信息和方法信息。服務(wù)信息中包含IP地址和端口信息,方法信息中包含請(qǐng)求信息和響應(yīng)信息。利用Mono對(duì)請(qǐng)求信息進(jìn)行封裝來實(shí)現(xiàn)框架支持響應(yīng)式的調(diào)用,響應(yīng)信息也將用Flux進(jìn)行封裝。WebClient會(huì)利用反射獲取到的服務(wù)信息和方法信息動(dòng)態(tài)創(chuàng)建客戶端實(shí)例進(jìn)行遠(yuǎn)程資源調(diào)用。
圖1
利用動(dòng)態(tài)代理獲取服務(wù)接口代理類信息之后,需要利用實(shí)例工廠處理器動(dòng)態(tài)注冊(cè)實(shí)例來實(shí)現(xiàn)服務(wù)接口代理類的注冊(cè)功能。為了能夠在實(shí)例工廠中動(dòng)態(tài)注冊(cè)Bean就必須創(chuàng)建一個(gè)實(shí)現(xiàn)了實(shí)例工廠接口的實(shí)現(xiàn)類,并在重寫方法實(shí)例工廠中動(dòng)態(tài)注冊(cè)的Bean就可以保證動(dòng)態(tài)注冊(cè)的bean能被實(shí)例工廠處理,并且可以保證其的實(shí)例化和初始化總是先于依賴它的bean。
IOC容器啟動(dòng)時(shí)會(huì)自動(dòng)掃描項(xiàng)目中標(biāo)注有@Rest注解的接口并為其創(chuàng)建代理類,還會(huì)將生成的代理注冊(cè)到IOC容器當(dāng)中;因此,在需要進(jìn)行遠(yuǎn)程調(diào)用服務(wù)資源的地方只需要利用@AutoWired按照類型依賴注入客戶端接口類型的實(shí)例并調(diào)用實(shí)例的方法即可。
基于WebClient的聲明式服務(wù)調(diào)用框架極大地簡(jiǎn)化了MES中遠(yuǎn)程服務(wù)資源的調(diào)用,使得車間計(jì)劃、車間操作、產(chǎn)品報(bào)工、產(chǎn)品質(zhì)檢、車間物流、設(shè)備維護(hù)、設(shè)備維修、看板信息、監(jiān)控等一系列制造執(zhí)行微服務(wù)可以協(xié)同工作。在基于HTTP協(xié)議的服務(wù)通信方面,支持響應(yīng)式、非阻塞的聲明式服務(wù)調(diào)用框架可以以少量而固定的線程數(shù)處理共并發(fā)的Http請(qǐng)求,使得整個(gè)MES可以在原有硬件資源的情況下承載更高的并發(fā)量,進(jìn)一步提供了MES的性能。