趙媛心,王 毅,紀(jì)祖赑,趙俊翔,劉 萍
(北京臨近空間飛行器系統(tǒng)工程研究所,北京 100076)
航天領(lǐng)域是國(guó)家安全基石的重要組成部分,是多學(xué)科綜合、多專(zhuān)業(yè)耦合、多領(lǐng)域覆蓋的系統(tǒng)工程,其中的型號(hào)軟件具有技術(shù)水平高、復(fù)雜度高、覆蓋范圍廣的特點(diǎn)。同時(shí),組織也在發(fā)揮型號(hào)軟件中積攢的技術(shù)和管理優(yōu)勢(shì),逐步擴(kuò)大產(chǎn)品化、市場(chǎng)化軟件的研制和推廣。隨著航天控制軟件規(guī)模越來(lái)越大,涉及的單位越來(lái)越多,分工也越來(lái)越細(xì)化。在這種場(chǎng)景下所有功能在一個(gè)軟件中編寫(xiě)實(shí)現(xiàn)已經(jīng)不現(xiàn)實(shí),多個(gè)系統(tǒng)、多個(gè)軟件配合使用已經(jīng)成為航天控制領(lǐng)域軟件的主要模式。隨之產(chǎn)生多系統(tǒng)、多軟件協(xié)同調(diào)用問(wèn)題越來(lái)越突出,歸納起來(lái)有以下兩點(diǎn):
1)調(diào)用方如何發(fā)現(xiàn)被調(diào)用方[7-8];
2)被調(diào)用方啟用或者關(guān)閉如何通知調(diào)用方[9-10]。
目前常用的解決方法有以下兩種:
1)靜態(tài)配置。在數(shù)據(jù)庫(kù)或者文件中手動(dòng)維護(hù)被調(diào)用方軟件地址列表。如果被調(diào)用方啟用或者關(guān)閉,則手動(dòng)更新數(shù)據(jù)庫(kù)或者文件列表。調(diào)用方每次調(diào)用服務(wù)之前,首先讀取數(shù)據(jù)庫(kù)或者文件,然后再調(diào)用服務(wù)。
2)引入互聯(lián)網(wǎng)領(lǐng)域的微服務(wù)框架。分布式微服務(wù)框架[1-2]優(yōu)點(diǎn)在于:
(1)一個(gè)服務(wù)對(duì)應(yīng)一項(xiàng)業(yè)務(wù)能力,做到單一職責(zé)[11-12];
(2)服務(wù)實(shí)現(xiàn)自動(dòng)注冊(cè)和發(fā)現(xiàn);
(3)服務(wù)之間相互獨(dú)立,可以實(shí)施不同的優(yōu)化方案[13]。
當(dāng)前互聯(lián)網(wǎng)領(lǐng)域比較流行的微服務(wù)框架[3]有Thrift-Eureka[1-2]和Dubbo[20],這些微服務(wù)框架的核心原理和組件基本一致,組件包括客戶端[4](調(diào)用方軟件)、服務(wù)端(被調(diào)用方軟件)和注冊(cè)中心[5-6],注冊(cè)中心的主要作用就是維護(hù)服務(wù)端列表,通過(guò)健康檢查[14-15]和消息通知[16]及時(shí)維護(hù)服務(wù)列表,目前比較常用的注冊(cè)中心是Zookeeper[17]。
但是這兩種方式在適配航天控制領(lǐng)域軟件都遇到了困難。靜態(tài)配置方式遇到的主要困難是每次軟件啟用、關(guān)閉都需要手動(dòng)更新數(shù)據(jù)庫(kù)或者文件,這就給運(yùn)維人員提出了很高的要求,尤其是調(diào)用關(guān)系復(fù)雜的情況下,如何及時(shí)正確地配置調(diào)用關(guān)系就成為了系統(tǒng)瓶頸。
互聯(lián)網(wǎng)領(lǐng)域軟件與航天控制領(lǐng)域軟件的一個(gè)重要區(qū)別是物理網(wǎng)絡(luò)隔離。Thrift-Eureka框架、Dubbo比較適用于互聯(lián)網(wǎng)領(lǐng)域,而不太適合航天控制領(lǐng)域,原因就在于這些框架依賴(lài)服務(wù)很多,部署復(fù)雜。通常航天控制軟件需要在多個(gè)區(qū)域部署試用,而且各個(gè)區(qū)域的網(wǎng)絡(luò)是物理隔離無(wú)法遠(yuǎn)程部署服務(wù)。如果需要匯報(bào)演示軟件,航天控制軟件自身部署需要1 h,但是微服務(wù)框架部署可能需要1 d。所以就需要結(jié)合互聯(lián)網(wǎng)領(lǐng)域微服務(wù)框架思想開(kāi)發(fā)一套適用于航天控制軟件領(lǐng)域的微服務(wù)框架,其需要具備以下特點(diǎn):1)易用性高;2)功能豐富;3)依賴(lài)項(xiàng)少,部署簡(jiǎn)單。
Facebook作為全球10大巨頭互聯(lián)網(wǎng)公司之一,其內(nèi)部包含多套軟件系統(tǒng)。并且各個(gè)軟件系統(tǒng)使用的開(kāi)發(fā)語(yǔ)言互不相同,部署環(huán)境互不相同。為了打通不同系統(tǒng)之間的信息壁壘,串聯(lián)各個(gè)信息孤島,構(gòu)建互聯(lián)互通的軟件系統(tǒng),其開(kāi)發(fā)了Thrift框架。在內(nèi)部穩(wěn)定運(yùn)行一段時(shí)間后,F(xiàn)acebook于2007年將Thrift框架作為一個(gè)開(kāi)源項(xiàng)目提交給了Apache基金會(huì)。由于創(chuàng)建Thrift框架的原由就是解決跨平臺(tái)通信問(wèn)題,所以Thrift天生支持多種語(yǔ)言通信。既支持流行了很多年的開(kāi)發(fā)語(yǔ)言C++、JAVA、C#等,也支持當(dāng)前正在流行的Erlang、Python、Ruby等。Thrift框架雖然在程序語(yǔ)言支持方面表現(xiàn)優(yōu)異,但是它的靜態(tài)編譯技術(shù)也常常被人詬病。Thrift框架需要先定義數(shù)據(jù)結(jié)構(gòu),然后使用Thrift工具將數(shù)據(jù)結(jié)構(gòu)轉(zhuǎn)換成IDL文件。這就意味著,如果某個(gè)數(shù)據(jù)結(jié)構(gòu)發(fā)生了變化,必須重新編譯生成IDL文件,但是這個(gè)弱項(xiàng)并沒(méi)有阻礙Thrift成為流行的微服務(wù)通信框架。
完整的Thrift框架包括一個(gè)客戶端和一個(gè)服務(wù)端,首先用戶需要自定義數(shù)據(jù)結(jié)構(gòu),然后使用Thrift工具自動(dòng)生成客戶端和服務(wù)端代碼,并且自動(dòng)生成的代碼中包含接口協(xié)議字段,以便客戶端與服務(wù)端進(jìn)行通信。在通信過(guò)程中Thrift會(huì)將數(shù)據(jù)信息轉(zhuǎn)換成高效的二進(jìn)制字節(jié)來(lái)提高傳輸效率。服務(wù)器端會(huì)利用底層多線程、阻塞或者非阻塞協(xié)議來(lái)接收數(shù)據(jù)。具體采用哪種協(xié)議基于操作系統(tǒng)不同而不同。
通過(guò)上面介紹可以發(fā)現(xiàn)Thrift框架是客戶端與服務(wù)端直接通信的,這就會(huì)導(dǎo)致以下問(wèn)題。
1)服務(wù)的端口或者IP發(fā)生變化,調(diào)用方需要手動(dòng)修改IP或端口;
2)新啟服務(wù)無(wú)法實(shí)現(xiàn)動(dòng)態(tài)發(fā)現(xiàn);
3)服務(wù)之間調(diào)用關(guān)系錯(cuò)綜復(fù)雜,難以維護(hù)。
針對(duì)以上缺點(diǎn)互聯(lián)網(wǎng)領(lǐng)域通常將Thrift與Eureka配合使用。Eureka是Netflix開(kāi)發(fā)的服務(wù)發(fā)現(xiàn)框架,本身是一個(gè)基于REST的服務(wù),以達(dá)到負(fù)載均衡和中間層服務(wù)故障轉(zhuǎn)移的目的。
Eureka是Netflix開(kāi)發(fā)的服務(wù)發(fā)現(xiàn)框架,其有兩部分構(gòu)成,即服務(wù)端和客戶端。服務(wù)端主要提供用戶服務(wù)注冊(cè)功能與更新功能,即用戶服務(wù)啟動(dòng)之后,會(huì)將自身服務(wù)信息注冊(cè)到Eureka的服務(wù)端中。每隔30 s用戶服務(wù)節(jié)點(diǎn)會(huì)發(fā)一次心跳到Eureka的服務(wù)端中,如果Eureka服務(wù)端連續(xù)多個(gè)心跳周期(一般為3個(gè)周期)都沒(méi)有收到某個(gè)服務(wù)節(jié)點(diǎn)的心跳,那么Eureka服務(wù)端就認(rèn)為該服務(wù)節(jié)點(diǎn)不可用,然后將其剔除。通過(guò)這樣的機(jī)制Eureka的服務(wù)端就可以總覽所有服務(wù)節(jié)點(diǎn)信息,并且快速識(shí)別可用的服務(wù)列表。Eureka客戶端主要提供服務(wù)訂閱功能和與服務(wù)端的連接封裝管理功能。即利用Eureka客戶端上層應(yīng)用可以使用服務(wù)名稱(chēng)與其他應(yīng)用進(jìn)行通信,而不用通過(guò)配置IP與其他應(yīng)用進(jìn)行通信。Eureka客戶端還內(nèi)置了輪詢算法來(lái)實(shí)現(xiàn)負(fù)載均衡功能。Thrift-Eureka微服務(wù)框架如圖1所示。
圖1 Thrift-Eureka微服務(wù)框架圖
由圖2所示,Thrift-Eureka框架的調(diào)用邏輯分為以下幾步:
圖2 Thrift-Eureka框架調(diào)用圖
1)在注冊(cè)中心中配置服務(wù)端名稱(chēng),在客戶端中配置其需要訂閱的服務(wù)名稱(chēng);
2)服務(wù)啟動(dòng)之后,服務(wù)端將本地IP和服務(wù)信息發(fā)送給注冊(cè)中心;
3)注冊(cè)中心將服務(wù)端IP和服務(wù)發(fā)送給客戶端;
4)客戶端基于注冊(cè)中心發(fā)來(lái)的消息,調(diào)用服務(wù)端的接口。
Dubbo 最早誕生于阿里巴巴,隨后加入 Apache 軟件基金會(huì),項(xiàng)目從設(shè)計(jì)之初就是為了解決企業(yè)的服務(wù)化問(wèn)題,因此充分考慮了大規(guī)模集群場(chǎng)景下的服務(wù)開(kāi)發(fā)與治理問(wèn)題,如易用性、性能、流量管理、集群可伸縮性等。在Dubbo開(kāi)源的將近10年時(shí)間內(nèi),Dubbo幾乎成為了國(guó)內(nèi)微服務(wù)框架的首選框架,尤其受到大規(guī)模互聯(lián)網(wǎng)、IT企業(yè)的認(rèn)可,可以說(shuō)作為開(kāi)源服務(wù)框架,Dubbo在支持微服務(wù)集群方面有著非常大的規(guī)模與非常久的實(shí)踐經(jīng)驗(yàn)積累,是最具有企業(yè)規(guī)模化微服務(wù)實(shí)踐話語(yǔ)權(quán)的框架之一。采用Dubbo的企業(yè)涵蓋互聯(lián)網(wǎng)、傳統(tǒng)IT、金融、生產(chǎn)制造業(yè)多個(gè)領(lǐng)域,一些典型用戶包括阿里巴巴、攜程、工商銀行、中國(guó)人壽、海爾、金蝶等。
Dubbo作為一款微服務(wù)開(kāi)發(fā)框架,它提供了遠(yuǎn)程服務(wù)調(diào)用與微服務(wù)治理兩大關(guān)鍵能力。利用Dubbo提供的豐富服務(wù)治理能力,可以實(shí)現(xiàn)諸如服務(wù)發(fā)現(xiàn)、負(fù)載均衡、流量調(diào)度等服務(wù)治理訴求。同時(shí)Dubbo是高度可擴(kuò)展的,用戶幾乎可以在任意功能點(diǎn)去定制自己的實(shí)現(xiàn),以改變框架的默認(rèn)行為來(lái)滿足自己的業(yè)務(wù)需求,Dubbo框架如圖3所示。
自開(kāi)源以來(lái),Dubbo 就被一眾大規(guī)模互聯(lián)網(wǎng)、IT公司選型,經(jīng)過(guò)多年企業(yè)實(shí)踐積累了大量經(jīng)驗(yàn)。因此,Dubbo 在解決業(yè)務(wù)落地與規(guī)?;瘜?shí)踐方面有著無(wú)可比擬的優(yōu)勢(shì):
1)易用性高,如 Java 版本的面向接口代理特性能實(shí)現(xiàn)本地透明調(diào)用;
2)功能豐富,基于原生庫(kù)或輕量擴(kuò)展即可實(shí)現(xiàn)絕大多數(shù)的微服務(wù)治理能力;
3)高性能的跨進(jìn)程通信協(xié)議;
4)地址發(fā)現(xiàn)、流量治理層面,輕松支持百萬(wàn)規(guī)模集群實(shí)例。
Dubbo 提供了從服務(wù)定義、服務(wù)發(fā)現(xiàn)、服務(wù)通信到流量管控等幾乎所有的服務(wù)治理能力,并且嘗試從使用上對(duì)用戶屏蔽底層細(xì)節(jié),以提供更好的易用性。定義服務(wù)在 Dubbo 中非常簡(jiǎn)單與直觀,可以選擇使用與某種語(yǔ)言綁定的方式(如Java中可直接定義Interface),也可以使用Protobuf IDL語(yǔ)言中立的方式。無(wú)論選擇哪種方式,站在服務(wù)消費(fèi)方的視角,都可以通過(guò) Dubbo 提供的透明代理直接編碼。
點(diǎn)對(duì)點(diǎn)的服務(wù)通信是Dubbo提供的一項(xiàng)基本能力,Dubbo以遠(yuǎn)程服務(wù)調(diào)用的方式將請(qǐng)求數(shù)據(jù)(Request)發(fā)送給后端服務(wù),并接收服務(wù)端返回的計(jì)算結(jié)果(Response)。遠(yuǎn)程服務(wù)調(diào)用對(duì)用戶來(lái)說(shuō)是完全透明的,使用者無(wú)需關(guān)心請(qǐng)求是如何發(fā)出去的、發(fā)到了哪里,每次調(diào)用只需要拿到正確的調(diào)用結(jié)果就行。同步的Request-Response是默認(rèn)的通信模型,它最簡(jiǎn)單但卻不能覆蓋所有的場(chǎng)景,因此,Dubbo 提供更豐富的通信模型:
1)客戶端異步請(qǐng)求(Client Side Asynchronous Request-Response);
2)服務(wù)端異步執(zhí)行(Server Side Asynchronous Request-Response);
3)客戶端請(qǐng)求流(Request Streaming);
4)服務(wù)端響應(yīng)流(Response Streaming);
5)雙向流式通信(Bidirectional Streaming)。
Dubbo的服務(wù)發(fā)現(xiàn)機(jī)制,讓微服務(wù)組件之間可以獨(dú)立演進(jìn)并任意部署,客戶端可以在無(wú)需感知對(duì)端部署位置與 IP 地址的情況下完成通信。Dubbo 提供的是 Client-Based 的服務(wù)發(fā)現(xiàn)機(jī)制,使用者可以使用Zookeeper作為服務(wù)發(fā)現(xiàn)組件。
Dubbo 提供了包括負(fù)載均衡、流量路由、請(qǐng)求超時(shí)、流量降級(jí)、重試等策略,基于這些基礎(chǔ)能力可以輕松的實(shí)現(xiàn)更多場(chǎng)景化的路由方案,包括金絲雀發(fā)布、A/B測(cè)試、權(quán)重路由、同區(qū)域優(yōu)先等。Dubbo 強(qiáng)大的服務(wù)治理能力不僅體現(xiàn)在核心框架上,還包括其優(yōu)秀的擴(kuò)展能力以及周邊配套設(shè)施的支持。
Thrift-Eureka需要使用API(接口定義語(yǔ)言)定義一個(gè)文件,然后通過(guò)Thrift來(lái)生成對(duì)應(yīng)的各種語(yǔ)言的代碼,服務(wù)的提供者和消費(fèi)者都需要把這個(gè)代碼引入進(jìn)去,服務(wù)端負(fù)責(zé)接口的實(shí)現(xiàn),消費(fèi)者使用API的存根去直接調(diào)用提供者。目前Thrift-Eureka支持的語(yǔ)言比較多,比如常見(jiàn)的C++、Java、Python、Ruby、C#、PHP等。Thrift屬于C/S模式,它通過(guò)代碼生成工具將接口定義的文件生成服務(wù)器端和客戶端的代碼,當(dāng)然,服務(wù)端和客戶端可以是不同語(yǔ)言的,從而實(shí)現(xiàn)了客戶端和服務(wù)端之間跨語(yǔ)言的支持。傳輸?shù)男蛄谢仓С趾芏喾N,比如:二進(jìn)制模式、壓縮模式、JSON模式以及Debug模式,可以在開(kāi)發(fā)的過(guò)程中使用Debug模式和JSON模式來(lái)方便的看到傳輸?shù)臄?shù)據(jù),在正式環(huán)境使用二進(jìn)制模式或壓縮模式來(lái)提升性能。在通訊模式上也支持很多種,它支持阻塞的I/O和NIO,還有專(zhuān)門(mén)用來(lái)傳輸文件的傳輸方式。在線程模型上,它也支持很多種,比如簡(jiǎn)單的單線程模式、線程池模式、多線程使用非阻塞I/O模式。這樣可以在不同的業(yè)務(wù)場(chǎng)景中使用更適合的技術(shù)來(lái)實(shí)現(xiàn)微服務(wù)調(diào)用。Thrift并沒(méi)有服務(wù)治理相關(guān)的功能,消費(fèi)者只能使用服務(wù)提供者IP和端口號(hào)來(lái)進(jìn)行訪問(wèn),而Eureka具有服務(wù)注冊(cè)與發(fā)現(xiàn)功能,需要將Thrift和Eureka配合使用,來(lái)作為一個(gè)完整的微服務(wù)框架。
Dubbo的消費(fèi)者和提供者以及注冊(cè)中心之間使用的是長(zhǎng)連接,服務(wù)的消費(fèi)者和提供者會(huì)在內(nèi)存中累計(jì)服務(wù)調(diào)用的次數(shù),并且定時(shí)將調(diào)用的信息發(fā)送到監(jiān)控中心;消費(fèi)者和提供者之間通信采用的是非阻塞I/O(即NIO);Dubbo的序列化使用的是阿里修改過(guò)的hession序列化方式,Dubbo是基于Java來(lái)進(jìn)行開(kāi)發(fā)的,所以也支持java的客戶端和服務(wù)端。Dubbo具備完善的服務(wù)注冊(cè)、服務(wù)訂閱、通知以及監(jiān)控功能。
總體而言,Dubbo作為一個(gè)完善的微服務(wù)框架,具備豐富的工具。但是它的缺點(diǎn)在于只支持Java語(yǔ)言。Thrift-Eureka搭配使用也能作為一個(gè)完善的微服務(wù)框架,其具備的工具集合滿足航天型號(hào)軟件使用需求,而且其支持的語(yǔ)言非常豐富。綜合比較下來(lái),系統(tǒng)選擇改造Thrift-Eureka微服務(wù)框架來(lái)適配航天型號(hào)軟件。
結(jié)合引言中介紹的航天型號(hào)軟件使用場(chǎng)景,即經(jīng)常需要在不同場(chǎng)地進(jìn)行試用,并且各個(gè)場(chǎng)地之間網(wǎng)絡(luò)不通。如果型號(hào)軟件部署需要1小時(shí),但是微服務(wù)框架部署需要1天,那就是本末倒置了。針對(duì)這種情況,微服務(wù)框架改造的重點(diǎn)在于不增加使用難度的情況下,縮短部署時(shí)間。
結(jié)合上文中提到的改造目標(biāo),如果能夠?qū)⒆?cè)中心和監(jiān)控中心的功能進(jìn)行轉(zhuǎn)移,并且將客戶端軟件和服務(wù)端軟件做成依賴(lài)包的形式嵌入型號(hào)軟件中,那么就達(dá)到了在不增加使用難度的情況下,減少部署時(shí)間的目標(biāo)。目前Thrift-Eureka的客戶端軟件和服務(wù)端軟件可以作為依賴(lài)包嵌入型號(hào)軟件。再分析一下注冊(cè)中心和監(jiān)控中心的功能,注冊(cè)中心的功能主要是服務(wù)注冊(cè)、服務(wù)更新通知和服務(wù)發(fā)現(xiàn),監(jiān)控中心的主要功能是客戶端指標(biāo)收集和服務(wù)端指標(biāo)收集。
1)服務(wù)注冊(cè):服務(wù)提供方將自身服務(wù)地址寫(xiě)入注冊(cè)中心;
2)服務(wù)更新通知:當(dāng)服務(wù)提供方IP或者端口發(fā)生變化后,及時(shí)通知客戶端更新服務(wù)列表;
3)服務(wù)發(fā)現(xiàn):客戶端讀取注冊(cè)中心中的服務(wù)列表;
4)客戶端指標(biāo)收集:客戶端將調(diào)用成功次數(shù)、失敗次數(shù)及耗時(shí)情況寫(xiě)入監(jiān)控中心;
5)服務(wù)端指標(biāo)收集:服務(wù)端將調(diào)用成功次數(shù)、失敗次數(shù)及耗時(shí)情況寫(xiě)入監(jiān)控中心。
在原有數(shù)據(jù)庫(kù)的基礎(chǔ)上增加兩張數(shù)據(jù)庫(kù)表,就可以來(lái)承載注冊(cè)中心和監(jiān)控中心的職責(zé),如圖4所示。
圖4 包含數(shù)據(jù)庫(kù)型號(hào)軟件微服務(wù)框架
根據(jù)圖4可知,包含數(shù)據(jù)庫(kù)的型號(hào)軟件微服務(wù)架構(gòu)原理概述如下:
首先在原有數(shù)據(jù)庫(kù)的基礎(chǔ)上增加兩張表,分別為服務(wù)注冊(cè)表和服務(wù)健康統(tǒng)計(jì)表。服務(wù)注冊(cè)表主要包括服務(wù)提供方IP、端口、最近更新時(shí)間。服務(wù)健康統(tǒng)計(jì)表主要包括機(jī)器IP、端口、服務(wù)名稱(chēng)、調(diào)用次數(shù)、失敗次數(shù)、類(lèi)型(服務(wù)端、客戶端)等。
然后修改服務(wù)端的服務(wù)注冊(cè)邏輯,每隔30 s更新一次服務(wù)注冊(cè)表中的服務(wù)信息。
再次在原有客戶端的基礎(chǔ)上,基于guava的Localcache構(gòu)建一套本地緩存,每隔30 s從數(shù)據(jù)庫(kù)中獲取一次服務(wù)提供方列表,并且將更新時(shí)間超過(guò)90 s的服務(wù)剔除。并且基于客戶端緩存的服務(wù)列表來(lái)實(shí)現(xiàn)負(fù)載均衡、流量路由、重試等策略等功能。
最后客戶端和服務(wù)端都將服務(wù)統(tǒng)計(jì)數(shù)據(jù)上傳到服務(wù)健康統(tǒng)計(jì)表中。
對(duì)照Thrift-Eureka的注冊(cè)中心和監(jiān)控中心,重新梳理了以下功能:
1)服務(wù)注冊(cè):服務(wù)提供方每隔30 s將自身服務(wù)地址和服務(wù)器時(shí)間更新到服務(wù)注冊(cè)表;
2)服務(wù)更新通知:客戶端通過(guò)本地緩存每隔30 s拉取一次服務(wù)注冊(cè)表信息,來(lái)達(dá)到服務(wù)更新通知的目標(biāo);
3)服務(wù)發(fā)現(xiàn):客戶端讀取本地緩存的服務(wù)列表;
4)客戶端指標(biāo)收集:客戶端將調(diào)用成功次數(shù)、失敗次數(shù)及耗時(shí)情況寫(xiě)入服務(wù)健康統(tǒng)計(jì)表;
5)服務(wù)端指標(biāo)收集:服務(wù)端將調(diào)用成功次數(shù)、失敗次數(shù)及耗時(shí)情況寫(xiě)入服務(wù)健康統(tǒng)計(jì)表。
上一章節(jié)介紹了如何基于數(shù)據(jù)庫(kù)改造Thrift-Eureka,下面介紹不利用數(shù)據(jù)庫(kù)改造微服務(wù)框架的方法。即可以通過(guò)服務(wù)端發(fā)送廣播本地服務(wù)消息的方式來(lái)實(shí)現(xiàn)注冊(cè)中心的功能,客戶端發(fā)送廣播獲取服務(wù)消息的方式來(lái)實(shí)現(xiàn)服務(wù)發(fā)現(xiàn)的功能,如圖5所示。
圖5 不包含數(shù)據(jù)庫(kù)型號(hào)軟件微服務(wù)框架
根據(jù)圖5所示,不包含數(shù)據(jù)庫(kù)的微服務(wù)架構(gòu)原理概述如下:首先服務(wù)端啟動(dòng)之后,在局域網(wǎng)內(nèi)廣播本地服務(wù)地址和服務(wù)信息,其他服務(wù)器收到消息之后,判斷該消息包含的服務(wù)信息是否是自己訂閱的。如果是自己訂閱的,則更新本地服務(wù)列表。如果不是自己訂閱的,則忽略這條廣播消息。然后服務(wù)端每隔3 min廣播一次本地服務(wù)地址和服務(wù)消息,其他服務(wù)器收到消息后處理邏輯與第一次收到消息處理邏輯一致。
然后客戶端啟動(dòng),在局域網(wǎng)內(nèi)廣播自己需要的服務(wù)地址,其他服務(wù)器收到消息之后,判斷該消息包含的服務(wù)信息是否是自己提供的。如果是自己提供的,則將本地服務(wù)地址和服務(wù)信息發(fā)送給客戶端。如果不是自己提供的,則忽略這條廣播消息。
再次在原有客戶端的基礎(chǔ)上,基于guava的Localcache構(gòu)建一套本地緩存,主要存儲(chǔ)服務(wù)地址和服務(wù)更新時(shí)間,并且將更新時(shí)間超過(guò)3 min的服務(wù)剔除。并且基于客戶端緩存的服務(wù)列表來(lái)實(shí)現(xiàn)負(fù)載均衡、流量路由、重試等策略等功能。
最后客戶端和服務(wù)端都將服務(wù)統(tǒng)計(jì)數(shù)據(jù)存儲(chǔ)到本地日志中,方便后續(xù)定位分析問(wèn)題。
對(duì)照Thrift-Eureka的注冊(cè)中心,重新梳理了以下功能:
1)服務(wù)注冊(cè):服務(wù)提供方啟動(dòng)之后將自身服務(wù)地址和服務(wù)器時(shí)間廣播給局域網(wǎng)內(nèi)其他機(jī)器;
2)服務(wù)更新通知:服務(wù)提供方每隔3 min將自身服務(wù)地址和服務(wù)器時(shí)間廣播給局域網(wǎng)內(nèi)其他機(jī)器;
3)服務(wù)發(fā)現(xiàn):客戶端讀取本地緩存的服務(wù)列表。如果本地緩存列表為空,則廣播發(fā)送獲取服務(wù)消息。
基于上述章節(jié),航天型號(hào)系統(tǒng)微服務(wù)框架內(nèi)置了兩套使用模式。模式一針對(duì)包含數(shù)據(jù)庫(kù)的型號(hào)系統(tǒng),它具有可靠性高、問(wèn)題排查方便的特點(diǎn)。模式二針對(duì)不包含數(shù)據(jù)庫(kù)的型號(hào)系統(tǒng),它具有依賴(lài)少,使用范圍廣泛的特點(diǎn)。系統(tǒng)會(huì)判斷用戶是否設(shè)置了使用模式,如果用戶有自定義設(shè)置,則按照用戶要求來(lái)使用系統(tǒng)。否則按照如下步驟自動(dòng)啟動(dòng)框架。
2.3.1 連接數(shù)據(jù)庫(kù)
判斷數(shù)據(jù)庫(kù)能否連接成功,如果能連接成功,則跳轉(zhuǎn)步驟2)。否則使用廣播模式,如下所示:
1)服務(wù)端廣播服務(wù)信息:服務(wù)端每隔3 min將本地服務(wù)信息廣播給局域網(wǎng)內(nèi)其他機(jī)器。
2)客戶端獲取服務(wù)信息:客戶端判斷本地緩存的服務(wù)列表是否為空,為空則廣播發(fā)送獲取服務(wù)消息。
2.3.2 創(chuàng)建服務(wù)注冊(cè)表
判斷數(shù)據(jù)庫(kù)中是否已經(jīng)存在服務(wù)注冊(cè)表。如果存在,則跳過(guò)。否則創(chuàng)建服務(wù)注冊(cè)表。
2.3.3 服務(wù)端每隔30 s更新服務(wù)注冊(cè)信息
服務(wù)端每隔30 s將本地服務(wù)地址和服務(wù)器時(shí)間更新到服務(wù)注冊(cè)表中。
2.3.4 客戶端每隔30 s拉取服務(wù)注冊(cè)信息
客戶端每隔30 s從服務(wù)注冊(cè)表中拉取服務(wù)信息,并更新本地緩存。
通過(guò)上述步驟可以得出,系統(tǒng)默認(rèn)優(yōu)先使用數(shù)據(jù)庫(kù)模式,在數(shù)據(jù)庫(kù)無(wú)法連接的情況則使用廣播模式。
Thrift-Eureka改進(jìn)的微服務(wù)架構(gòu)主要解決的是航天型號(hào)軟件部署維護(hù)復(fù)雜的問(wèn)題,為此設(shè)計(jì)了對(duì)照實(shí)驗(yàn)來(lái)比較原型Thrift-Eureka框架和改進(jìn)的Thrift-Eureka框架的部署耗時(shí)。首先針對(duì)某航天型號(hào)軟件A,分別使用Thrift-Eureka框架構(gòu)建系統(tǒng)B,使用改進(jìn)的Thrift-Eureka框架構(gòu)建系統(tǒng)C。
從開(kāi)發(fā)組、測(cè)試組和運(yùn)維組總共抽取了45名同事,將這45名同事隨機(jī)分成5個(gè)隊(duì),每隊(duì)9人,包括3名開(kāi)發(fā)、3名測(cè)試和3名運(yùn)維同事。
每隊(duì)需要同時(shí)部署系統(tǒng)A、系統(tǒng)B和系統(tǒng)C。耗時(shí)情況如表1所示。
表1 系統(tǒng)部署耗時(shí)比較 s
從表1中可以看出部署系統(tǒng)A和系統(tǒng)C的耗時(shí)基本相同,這符合實(shí)驗(yàn)預(yù)期。因?yàn)楦倪M(jìn)的Thrift-Eureka框架構(gòu)不需要額外部署軟件,實(shí)驗(yàn)隊(duì)員部署系統(tǒng)A和系統(tǒng)C的步驟基本相同。但是部署系統(tǒng)B的耗時(shí)明顯增加,這是因?yàn)槌瞬渴鸹A(chǔ)的型號(hào)系統(tǒng)A之外,還需要部署配置Thrift-Eureka框架。
首先介紹了航天型號(hào)軟件開(kāi)發(fā)框架遇到的問(wèn)題,分析了航天型號(hào)垂直應(yīng)用框架和微服務(wù)框架的優(yōu)缺點(diǎn),著重介紹了目前互聯(lián)網(wǎng)領(lǐng)域流行的微服務(wù)框架Thrift-Eureka和Dubbo。接著描述了互聯(lián)網(wǎng)領(lǐng)域的微服務(wù)框架適配航天型號(hào)軟件領(lǐng)域遇到的問(wèn)題。然后基于微服務(wù)框架思想和Dubbo微服務(wù)框架,提出了一種適用于航天型號(hào)軟件領(lǐng)域的微服務(wù)框架。該服務(wù)框架有兩種使用模式:一種適用于包含數(shù)據(jù)庫(kù)的型號(hào)軟件系統(tǒng);另一種適用于不包含數(shù)據(jù)庫(kù)的型號(hào)軟件系統(tǒng)。針對(duì)有數(shù)據(jù)庫(kù)的型號(hào)軟件系統(tǒng),利用數(shù)據(jù)庫(kù)系統(tǒng)來(lái)實(shí)現(xiàn)微服務(wù)框架的注冊(cè)中心功能。針對(duì)沒(méi)有數(shù)據(jù)庫(kù)的型號(hào)軟件系統(tǒng),利用廣播協(xié)議、本地日志來(lái)實(shí)現(xiàn)微服務(wù)框架注冊(cè)中心功能。經(jīng)在某項(xiàng)目中實(shí)踐后可見(jiàn),該方案能夠?qū)嶋H解決航天型號(hào)軟件微服務(wù)框架使用的問(wèn)題。