操禮長(zhǎng) 王小雨 申健 王小旗 鄧德鑫
摘要:傳統(tǒng)的航天測(cè)控系統(tǒng)監(jiān)控軟件采用單體式應(yīng)用架構(gòu),存在維護(hù)難度大、周期長(zhǎng)、擴(kuò)展性差等弊端,并且無(wú)法滿(mǎn)足資源可動(dòng)態(tài)重構(gòu)擴(kuò)展的需求?;贗ceGrid微服務(wù)架構(gòu)的系統(tǒng)監(jiān)控軟件具有良好的穩(wěn)定性與分布式能力,可以很好地解決上述問(wèn)題。闡述了IceGrid微服務(wù)架構(gòu)的基礎(chǔ)框架,并提出基于Redis的服務(wù)主備仲裁機(jī)制與競(jìng)爭(zhēng)分布式鎖的服務(wù)主備切換方式,實(shí)現(xiàn)各類(lèi)服務(wù)自主切換,并且有效解決了系統(tǒng)網(wǎng)絡(luò)不穩(wěn)定或者單服務(wù)器死機(jī)等異常情況下系統(tǒng)出現(xiàn)嚴(yán)重卡頓甚至數(shù)據(jù)丟失的問(wèn)題,提高了航天測(cè)控系統(tǒng)運(yùn)行的穩(wěn)定性與可靠性。
關(guān)鍵詞:微服務(wù)架構(gòu);Redis;主備切換;分布式鎖
中圖分類(lèi)號(hào):TP311文獻(xiàn)標(biāo)志碼:A文章編號(hào):1008-1739(2022)13-64-5
隨著航天測(cè)控系統(tǒng)監(jiān)控軟件的業(yè)務(wù)功能不斷擴(kuò)展和復(fù)雜化,軟件生態(tài)系統(tǒng)中模塊與組件之間的調(diào)用依賴(lài)關(guān)系也變得越來(lái)越復(fù)雜,傳統(tǒng)單體式應(yīng)用架構(gòu)存在維護(hù)難度大、周期長(zhǎng)、擴(kuò)展性差、升級(jí)難度高等弊端[1],并且新組件的大量引入與迭代數(shù)據(jù)的快速更新,很容易導(dǎo)致軟件生態(tài)系統(tǒng)的不穩(wěn)定和不平衡[2]。另一方面,為了提高共用設(shè)備資源的利用率,實(shí)現(xiàn)測(cè)控設(shè)備快速接入能力,航天測(cè)控資源重組系統(tǒng)對(duì)監(jiān)控軟件提出可動(dòng)態(tài)重構(gòu)擴(kuò)展的需求,即資源重組系統(tǒng)不停機(jī)接入的需求。故由單體式應(yīng)用架構(gòu)轉(zhuǎn)為微服務(wù)架構(gòu)是解決復(fù)雜問(wèn)題,以及滿(mǎn)足資源重組系統(tǒng)不停機(jī)接入需求的必經(jīng)途徑[3]。
網(wǎng)絡(luò)通信引擎(Internet Communications Engine,ICE)是ZeroC公司開(kāi)發(fā)的一款高效的開(kāi)源中間件平臺(tái),可以快速開(kāi)發(fā)出高效的分布式軟件[4]。IceGrid服務(wù)是ICE中間件的服務(wù)注冊(cè)中心,客戶(hù)端的所有服務(wù)定位請(qǐng)求都需通過(guò)IceGrid進(jìn)行處理,當(dāng)IceGrid發(fā)生故障,整個(gè)服務(wù)集群將會(huì)處于癱瘓狀態(tài),導(dǎo)致系統(tǒng)無(wú)法正常工作,雖然IceGrid實(shí)現(xiàn)了高可用,但是在進(jìn)行故障切換時(shí),主節(jié)點(diǎn)和從節(jié)點(diǎn)之間的關(guān)系轉(zhuǎn)換卻不是完全自動(dòng)的,需要人工進(jìn)行處理,對(duì)于大型的分布式系統(tǒng)是不現(xiàn)實(shí)的[5]。本文提出的基于Redis的主備服務(wù)仲裁及切換機(jī)制可以實(shí)現(xiàn)主備服務(wù)自主切換,并且在系統(tǒng)網(wǎng)絡(luò)不穩(wěn)定或者單服務(wù)器死機(jī)等異常情況下,仍能保證航天測(cè)控系統(tǒng)的正常運(yùn)行。
1.1微服務(wù)架構(gòu)
微服務(wù)架構(gòu)是一種將單一應(yīng)用拆分為多個(gè)子服務(wù)的系統(tǒng)服務(wù)架構(gòu),采用輕量通信機(jī)制進(jìn)行服務(wù)之間的相互通信、協(xié)調(diào)與配合,每個(gè)服務(wù)都對(duì)應(yīng)一個(gè)獨(dú)立的業(yè)務(wù)模塊,能夠獨(dú)立運(yùn)行、獨(dú)立部署、獨(dú)立升級(jí),不同服務(wù)間既相互獨(dú)立又相互配合。故微服務(wù)之間高內(nèi)聚低耦合的特點(diǎn),可極大地提高系統(tǒng)架構(gòu)的容錯(cuò)性、靈活性與可擴(kuò)展性,有效避免因單個(gè)服務(wù)更新導(dǎo)致整個(gè)系統(tǒng)升級(jí)的問(wèn)題[6]。
1.2基于IceGrid的微服務(wù)架構(gòu)
在以ICE中間件內(nèi)建的多種服務(wù)構(gòu)建的微服務(wù)框架中,IceGrid是整個(gè)框架的核心服務(wù),為客戶(hù)端提供位置請(qǐng)求、應(yīng)用部署、負(fù)載均衡等服務(wù),為服務(wù)端提供服務(wù)管理和服務(wù)發(fā)現(xiàn)等[7]。IceGrid分布式部署如圖1所示,主要組件包括服務(wù)注冊(cè)中心、服務(wù)節(jié)點(diǎn)以及消息中心。IceGrid即為注冊(cè)中心Registry與Node服務(wù)器的集合,注冊(cè)中心和Node監(jiān)控服務(wù)器相互配合共同管理應(yīng)用程序的服務(wù)進(jìn)程。每一個(gè)應(yīng)用程序都被分成了若干進(jìn)程服務(wù)分別部署在不同的Node監(jiān)控服務(wù)器中,由Node監(jiān)控服務(wù)器對(duì)部署在該服務(wù)器中的所有服務(wù)進(jìn)行管理。
服務(wù)注冊(cè)中心是分布式監(jiān)控系統(tǒng)的服務(wù)管理中心,為了監(jiān)控系統(tǒng)的可靠性,采用一主一從部署策略。注冊(cè)中心的信息寫(xiě)在Node監(jiān)控服務(wù)器的配置文件中,Node監(jiān)控服務(wù)器啟動(dòng)后向所有注冊(cè)中心進(jìn)行動(dòng)態(tài)注冊(cè)。服務(wù)節(jié)點(diǎn)為2臺(tái)監(jiān)控服務(wù)器,負(fù)責(zé)與注冊(cè)中心直接通信以及服務(wù)容器的生命周期管理。服務(wù)容器是ICE服務(wù)的管理容器,采取集中式的策略對(duì)服務(wù)進(jìn)行加載、管理,各類(lèi)服務(wù)被設(shè)計(jì)為可動(dòng)態(tài)加載的組件以動(dòng)態(tài)庫(kù)的形式按需配置到服務(wù)容器,該方式解耦了監(jiān)控服務(wù)器和服務(wù),可以按照需要組合服務(wù)或分離服務(wù)。
注冊(cè)中心、Node服務(wù)器、服務(wù)容器的關(guān)系連接如圖2所示,在系統(tǒng)正常運(yùn)行時(shí),Node服務(wù)器會(huì)對(duì)服務(wù)容器進(jìn)行全生命周期管理,包括啟動(dòng)、檢測(cè)、故障重啟等。Node服務(wù)器會(huì)向所有注冊(cè)中心定時(shí)上報(bào)自身及服務(wù)容器的運(yùn)行狀態(tài),所有注冊(cè)中心都會(huì)自動(dòng)感知各類(lèi)服務(wù)的工作狀態(tài)。
1.3服務(wù)的發(fā)布與調(diào)用
微服務(wù)平臺(tái)的服務(wù)通信在底層都是基于網(wǎng)絡(luò)來(lái)完成,對(duì)應(yīng)用層則主要有服務(wù)調(diào)用和消息發(fā)布2種方式。微服務(wù)平臺(tái)服務(wù)發(fā)布與調(diào)用流程如圖3所示。服務(wù)在發(fā)生調(diào)用時(shí),服務(wù)消費(fèi)者向注冊(cè)中心查詢(xún)服務(wù)提供者,注冊(cè)中心會(huì)向服務(wù)消費(fèi)者提供一個(gè)可用的服務(wù)信息列表。
服務(wù)的發(fā)布流程所示:
①首先注冊(cè)中心根據(jù)IceGrid的配置信息將服務(wù)發(fā)布到對(duì)應(yīng)的Node節(jié)點(diǎn),并啟動(dòng)對(duì)應(yīng)的服務(wù)定位服務(wù);
②在Node節(jié)點(diǎn)接收服務(wù)文件之后,根據(jù)服務(wù)配置文件啟動(dòng)對(duì)應(yīng)的服務(wù)程序。
完成上述部署過(guò)程后,整個(gè)分布式部署即完成,系統(tǒng)此時(shí)可對(duì)外提供服務(wù)。服務(wù)調(diào)用過(guò)程如下:
①監(jiān)控客戶(hù)端首先根據(jù)服務(wù)標(biāo)識(shí)訪問(wèn)服務(wù)定位服務(wù);
②服務(wù)定位服務(wù)從注冊(cè)中心獲取對(duì)應(yīng)的服務(wù)所在節(jié)點(diǎn)信息并將結(jié)果返回監(jiān)控客戶(hù)端;
③監(jiān)控客戶(hù)端收到查詢(xún)結(jié)果后,定位到服務(wù)所在網(wǎng)絡(luò)位置,操作對(duì)應(yīng)的服務(wù)接口調(diào)用服務(wù)。
Redis全名為遠(yuǎn)程字典服務(wù),是一個(gè)基于內(nèi)存的鍵—值數(shù)據(jù)庫(kù),很大程度上彌補(bǔ)了內(nèi)存緩沖存儲(chǔ)的匱乏[8]。因其具有讀取速度快、支持發(fā)布/訂閱模式、高可用以及分布式等特點(diǎn),在各大系統(tǒng)中廣泛應(yīng)用。
監(jiān)控軟件的主備服務(wù)仲裁基本策略為:在系統(tǒng)初始化啟動(dòng)后,監(jiān)控服務(wù)器根據(jù)仲裁機(jī)制首先選舉出主用Redis、備用Redis,每類(lèi)服務(wù)向主用Redis申請(qǐng)分布式鎖,根據(jù)申請(qǐng)的狀態(tài)來(lái)決定每類(lèi)服務(wù)的主備,并且在異常發(fā)生時(shí)自動(dòng)開(kāi)展服務(wù)主備切換。
2.1 Redis主備仲裁及切換機(jī)制
Redis內(nèi)存數(shù)據(jù)庫(kù)在監(jiān)控服務(wù)器A機(jī)、B機(jī)中各部署一套,互為主備關(guān)系。仲裁機(jī)制中對(duì)Redis的主備狀態(tài)進(jìn)行決策仲裁的服務(wù)為Redis-Cache,以負(fù)載均衡的形式部署于監(jiān)控系統(tǒng)2臺(tái)服務(wù)器中,該服務(wù)與Redis共同組成分布式內(nèi)存數(shù)據(jù)庫(kù)集群,系統(tǒng)監(jiān)控軟硬件部署如圖4所示。
仲裁機(jī)制如圖5所示,監(jiān)控服務(wù)器中運(yùn)行的所有服務(wù)會(huì)將各自?xún)?nèi)部狀態(tài)信息每秒定時(shí)存入到主用Redis內(nèi)存數(shù)據(jù)庫(kù)中,存入的信息中包含時(shí)間標(biāo)簽。Redis-Cache服務(wù)每秒從Redis內(nèi)存數(shù)據(jù)庫(kù)中獲取所有服務(wù)的信息,根據(jù)這些信息,按照仲裁策略進(jìn)行服務(wù)仲裁。
為了保證仲裁機(jī)制的可靠性,利用系統(tǒng)自帶的監(jiān)控網(wǎng)絡(luò)交換機(jī)作為第三方,通過(guò)實(shí)時(shí)監(jiān)測(cè)Redis與其他Redis、監(jiān)控網(wǎng)絡(luò)交換機(jī)的通斷狀態(tài)來(lái)進(jìn)行主備Redis的仲裁和切換。其中Redis與監(jiān)控網(wǎng)絡(luò)交換機(jī)的通斷狀態(tài)判別方法為:系統(tǒng)運(yùn)行過(guò)程中,監(jiān)控服務(wù)器與網(wǎng)絡(luò)交換機(jī)管理IP進(jìn)行ping操作,如果交換機(jī)管理IP連續(xù)ping通,則認(rèn)為Redis與網(wǎng)絡(luò)交換機(jī)狀態(tài)通,反之則不通。RedisA,RedisB間狀態(tài)通斷判別方法為:系統(tǒng)運(yùn)行過(guò)程中,監(jiān)控服務(wù)器A機(jī)、B機(jī)一直互發(fā)心跳數(shù)據(jù)包,雙方收到則雙方狀態(tài)為通,否則為不通。心跳數(shù)據(jù)包內(nèi)容有:當(dāng)前主用Redis的IP和端口(初始狀態(tài)下沒(méi)有主用Redis的情況下,IP和端口都填空)、本地服務(wù)器IP地址、本地Redis主備狀態(tài)、成為主用Redis的時(shí)間、與網(wǎng)絡(luò)交換機(jī)的通斷狀態(tài)。
仲裁具體流程如下:
①監(jiān)控系統(tǒng)初始啟動(dòng)時(shí),服務(wù)器A機(jī)、B機(jī)的“Redis主備狀態(tài)”均為備用。
②如果服務(wù)器A機(jī)、B機(jī)收到對(duì)方心跳數(shù)據(jù)包,根據(jù)“本地Redis主備狀態(tài)”判斷是否存在主用Redis,如果存在主用Redis,維持現(xiàn)有主備機(jī)狀態(tài),否則選擇“服務(wù)器IP地址”較小的一方作為主機(jī)。
③如果連續(xù)10 s(可配置)沒(méi)有收到對(duì)方心跳數(shù)據(jù)包,則需要依據(jù)Redis與網(wǎng)絡(luò)交換機(jī)(第三方)的通斷狀態(tài)進(jìn)行判斷。若主用Redis與網(wǎng)絡(luò)交換機(jī)不通則降自身為備用,否則維持當(dāng)前狀態(tài);若備用Redis與網(wǎng)絡(luò)交換機(jī)不通,則維持當(dāng)前狀態(tài),否則將自身升為主機(jī)。
④如果連續(xù)10 s(可配置)沒(méi)有收到對(duì)方心跳數(shù)據(jù)包,服務(wù)器A機(jī)、B機(jī)都與第三方設(shè)備斷開(kāi),則可能存在雙備Redis的狀態(tài)。后續(xù)在服務(wù)器A機(jī)、B機(jī)收到對(duì)方心跳后,根據(jù)“成為主Redis的時(shí)間”進(jìn)行判斷,以成為主機(jī)時(shí)間最長(zhǎng)的Redis優(yōu)先作為主機(jī),如果成為主機(jī)時(shí)間相同,則以IP最小的Redis優(yōu)先作為主用。
⑤如果連續(xù)10 s(可配置)沒(méi)有收到對(duì)方心跳數(shù)據(jù)包,服務(wù)器A機(jī)、B機(jī)都與第三方設(shè)備連通,則可能存在雙主Redis的狀態(tài)。后續(xù)在服務(wù)器A機(jī)、B機(jī)收到對(duì)方心跳后,根據(jù)“成為主Redis的時(shí)間”判斷以成為主機(jī)時(shí)間最長(zhǎng)的Redis優(yōu)先作為主機(jī),如果成為主機(jī)時(shí)間相同則以IP最小的優(yōu)先作為主機(jī)。
2.2主備服務(wù)切換機(jī)制
主備服務(wù)根據(jù)預(yù)先配置部署在監(jiān)控服務(wù)器A機(jī)、B機(jī)中,每類(lèi)服務(wù)向主用Redis采用競(jìng)爭(zhēng)分布式鎖的方式來(lái)決定主備服務(wù)的控制權(quán)。分布式鎖是指在分布式的場(chǎng)景下,通過(guò)鎖機(jī)制使訪問(wèn)某一共享資源的多個(gè)客戶(hù)端互斥的對(duì)資源進(jìn)行訪問(wèn)的一種方式[9]。分布式鎖的構(gòu)建規(guī)則為:同類(lèi)型主備服務(wù)的鎖Key相同,不同類(lèi)型的主備服務(wù)的鎖不相同,且相同Key的分布式鎖在集群中只存在一個(gè),只能夠被集群內(nèi)的一個(gè)服務(wù)獲取并使用。每個(gè)服務(wù)根據(jù)該Key并附帶鎖的超時(shí)時(shí)間去申請(qǐng)?jiān)撴i,并根據(jù)申請(qǐng)的狀態(tài)來(lái)決定服務(wù)的主備,當(dāng)異常發(fā)生時(shí)開(kāi)展主備切換。
2.2.1分布式鎖的申請(qǐng)
系統(tǒng)監(jiān)控服務(wù)器程序啟動(dòng)之后,所有主備類(lèi)型的服務(wù)均默認(rèn)為備用。主用Redis根據(jù)規(guī)則構(gòu)建分布式鎖,各類(lèi)服務(wù)定時(shí)(每秒)申請(qǐng)Redis分布式鎖,如果申請(qǐng)到鎖,則將該服務(wù)升為主用,失去鎖則將該服務(wù)降為備用,服務(wù)申請(qǐng)鎖流程如圖6所示。
2.2.2分布式鎖的續(xù)約
分布式鎖申請(qǐng)均附帶了超時(shí)時(shí)間,即超時(shí)時(shí)間到達(dá)后,該鎖自動(dòng)釋放。續(xù)鎖只針對(duì)主服務(wù),備服務(wù)主要負(fù)責(zé)申請(qǐng)鎖。續(xù)鎖機(jī)制主要為了保證在獲得鎖的服務(wù)異常退出后,系統(tǒng)可以將該鎖回收。主服務(wù)續(xù)鎖流程如圖7所示。
主用服務(wù)申請(qǐng)到鎖之后,在每秒定時(shí)時(shí)鐘周期申請(qǐng)續(xù)鎖,如果續(xù)鎖失敗,則進(jìn)行累計(jì)續(xù)鎖計(jì)數(shù)(累計(jì)續(xù)鎖次數(shù)可配置,本系統(tǒng)配置為5次)。如果連續(xù)續(xù)鎖累計(jì)失敗次數(shù)超過(guò)閾值,則降低自身服務(wù)為備用。如果在閾值時(shí)間內(nèi)有續(xù)鎖成功,則清空失敗累計(jì)計(jì)數(shù)值,并維持自身主用的狀態(tài)。若主用服務(wù)續(xù)鎖失敗,則分布鎖將被釋放,由于備用服務(wù)也在定時(shí)申請(qǐng)分布式鎖,因此備用服務(wù)將會(huì)申請(qǐng)到鎖并提升自身作為主用服務(wù)來(lái)執(zhí)行業(yè)務(wù)運(yùn)行。
2.2.3主備服務(wù)切換流程
主備服務(wù)切換流程如圖8所示,系統(tǒng)初始化運(yùn)行后,會(huì)自動(dòng)啟動(dòng)Redis,若Redis工作不正常或未啟動(dòng),由Redis-Cache保證對(duì)Redis的重啟工作;若Redis工作正常,各類(lèi)服務(wù)開(kāi)始向Redis申請(qǐng)分布鎖,申請(qǐng)到鎖的服務(wù)為主用服務(wù),未申請(qǐng)到鎖的服務(wù)為備用服務(wù),后續(xù)主用服務(wù)定時(shí)開(kāi)展續(xù)鎖,保證系統(tǒng)運(yùn)行的穩(wěn)定性。
系統(tǒng)采用基于Redis的分布式鎖申請(qǐng)與續(xù)鎖機(jī)制,使各個(gè)服務(wù)自主完成主備競(jìng)爭(zhēng),在網(wǎng)絡(luò)發(fā)生高頻率短間隔的閃爍時(shí),可由分布式鎖的續(xù)約機(jī)制來(lái)維持現(xiàn)有主備狀態(tài)不會(huì)發(fā)生變化。若網(wǎng)絡(luò)前后通斷間隔時(shí)間超過(guò)鎖的續(xù)約時(shí)間,服務(wù)可自行完成主備切換操作,對(duì)系統(tǒng)的自動(dòng)化運(yùn)行與穩(wěn)定性無(wú)影響。
若單臺(tái)服務(wù)器出現(xiàn)故障,并且故障服務(wù)器上運(yùn)行主用Redis,根據(jù)Redis仲裁機(jī)制,主用Redis降為備用,另一臺(tái)服務(wù)器中運(yùn)行的備用Redis自動(dòng)升為主用,在Redis主備仲裁完成后,各類(lèi)服務(wù)向主用Redis申請(qǐng)分布式鎖進(jìn)行主備切換。故障服務(wù)器恢復(fù)正常后,保持運(yùn)行狀態(tài)不變。
該監(jiān)控軟件平臺(tái)已通過(guò)測(cè)試驗(yàn)證,并在多套航天測(cè)控系統(tǒng)中得以應(yīng)用,有效規(guī)避了系統(tǒng)網(wǎng)絡(luò)不穩(wěn)定或者單服務(wù)器死機(jī)等異常情況下監(jiān)控系統(tǒng)運(yùn)行不穩(wěn)定的情況,為航天測(cè)控任務(wù)的成功執(zhí)行提供保證。隨著技術(shù)的進(jìn)步,微服務(wù)平臺(tái)與Redis的發(fā)展必將更加成熟,并應(yīng)用于各式各樣的系統(tǒng)中。
[1]趙磊,王運(yùn)成,王娟.微服務(wù)在人臉識(shí)別考勤系統(tǒng)中的應(yīng)用[J].電子技術(shù)與軟件工程,2021(13):30-31.
[2]馮志勇,徐硯偉,薛霄,等.微服務(wù)技術(shù)發(fā)展的現(xiàn)狀與展望[J].計(jì)算機(jī)研究與發(fā)展,2020,57(5):1103-1122.
[3]田浩.基于SOA的高并發(fā)與高可用網(wǎng)站開(kāi)發(fā)框架設(shè)計(jì)與實(shí)現(xiàn)[D].呼和浩特:內(nèi)蒙古大學(xué),2017.
[4]江卓逞,黃瑋,曾加剛.基于ICE中間件的分布式應(yīng)用開(kāi)發(fā)研究[J].信息與電腦(理論版),2017(9):38-40.
[5]馮戰(zhàn)勝.基于ICE中間件的改進(jìn)與實(shí)現(xiàn)[D].北京:中國(guó)電子科技集團(tuán)公司電子科學(xué)研究院,2019.
[6]鄭文靖,王婷.微服務(wù)架構(gòu)研究方法[J].現(xiàn)代信息科技,2019,3(15):72-73,77.
[7]馮戰(zhàn)勝,張激,彭宏,等.基于Zookeeper的分布式ICE中間件研究[J].計(jì)算機(jī)系統(tǒng)應(yīng)用,2018,27(12):222-226.
[8]王嫣如.Redis消息推送機(jī)制應(yīng)用技術(shù)研究[J].科技廣場(chǎng), 2016(8):41-44.
[9]陳鵬.基于分布式緩存和消息中間件的選課系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)[D].重慶:重慶大學(xué),2019.