Terminator服務(wù)虛擬化
問(wèn)題
在開(kāi)發(fā)/測(cè)試一個(gè)復(fù)雜系統(tǒng)的時(shí)候我們經(jīng)常遇到開(kāi)發(fā)/測(cè)試中的模塊依賴(lài)其它服務(wù)的情況。比如一個(gè)系統(tǒng)有兩個(gè)模塊A和B,A模塊依賴(lài)于B模塊提供的服務(wù):
B部分功能還未完成開(kāi)發(fā)導(dǎo)致A模塊開(kāi)發(fā)被阻塞;
B模塊有些數(shù)據(jù)不好構(gòu)造,開(kāi)發(fā)時(shí)無(wú)法自測(cè)到所有情況;
對(duì)A模塊進(jìn)行集成測(cè)試時(shí),寫(xiě)了一些自動(dòng)化用例。但由于B模塊不可控,B模塊的數(shù)據(jù)經(jīng)常變動(dòng)導(dǎo)致返回給A模塊的數(shù)據(jù)也變化了,這時(shí)候依賴(lài)B模塊返回?cái)?shù)據(jù)的斷言將失??;
B模塊不是自己團(tuán)隊(duì)維護(hù),經(jīng)常出現(xiàn)不穩(wěn)定,導(dǎo)致開(kāi)發(fā)環(huán)境中整個(gè)系統(tǒng)不穩(wěn)定。
解決方案
服務(wù)虛擬化指的就是虛擬出不穩(wěn)定、不可用、未開(kāi)發(fā)完全的服務(wù)。通常有兩種方法:
針對(duì)協(xié)議的通用樁,可以預(yù)先設(shè)置請(qǐng)求對(duì)應(yīng)的返回值以及匹配條件,這樣系統(tǒng)未開(kāi)發(fā)完之前可以使用這個(gè)樁來(lái)代替真實(shí)的服務(wù);
錄制回放方式,在第三方服務(wù)可用的時(shí)候?qū)㈡溌飞系臄?shù)據(jù)錄制下來(lái),當(dāng)不穩(wěn)定或者不可用時(shí),回放當(dāng)時(shí)錄制的數(shù)據(jù)。
其中方案1主要針對(duì)問(wèn)題一和二,方案2主要針對(duì)問(wèn)題三和四。Terminator(寓意:明暗交界線)實(shí)現(xiàn)了以上兩種方式。
Terminator中每個(gè)鏈路可以看成是一個(gè)代理,運(yùn)行在兩個(gè)服務(wù)之間,現(xiàn)在支持四種工作模式:
TUNNEL:隧道模式,鏈路服務(wù)負(fù)責(zé)接收和轉(zhuǎn)發(fā)鏈路上的數(shù)據(jù),但不做任何存儲(chǔ),相當(dāng)于通透狀態(tài);
RECORD:錄制模式,鏈路服務(wù)將鏈路上的請(qǐng)求和響應(yīng)存儲(chǔ)下來(lái),并記錄請(qǐng)求響應(yīng)的對(duì)應(yīng)關(guān)系;
REPLAY:回放模式,鏈路服務(wù)不會(huì)連接后端的依賴(lài)服務(wù),當(dāng)請(qǐng)求過(guò)來(lái)時(shí)當(dāng)符合某些條件時(shí)直接返回當(dāng)時(shí)錄制的響應(yīng);
STUB:通用樁模式,鏈路服務(wù)能夠預(yù)設(shè)返回結(jié)果與匹配規(guī)則,當(dāng)請(qǐng)求過(guò)來(lái)時(shí)符合匹配規(guī)則即返回預(yù)設(shè)結(jié)果。
整體架構(gòu)
網(wǎng)絡(luò)通信:主要在TCP層建立Socket收發(fā)鏈路上的通信數(shù)據(jù),這里采用的是netty框架;
協(xié)議編解碼器:主要將二進(jìn)制數(shù)據(jù)包解析為協(xié)議數(shù)據(jù)或者反過(guò)來(lái)將協(xié)議數(shù)據(jù)轉(zhuǎn)化為二進(jìn)制數(shù)據(jù),netty本身提供了HTTP、SSL/TLS、WebSockets、Google Protocol Buffer的編解碼器,如果需要擴(kuò)展可以自己定義協(xié)議編解碼器;
工作模式處理器:本系統(tǒng)的核心,現(xiàn)在提供的錄制回放、通用樁都是這里實(shí)現(xiàn)的。這里提供了較多的擴(kuò)展接口,可以基于定制化需求實(shí)現(xiàn)新的模式, 比如當(dāng)后端服務(wù)down掉的情況下啟動(dòng)之前的錄制數(shù)據(jù)。另外對(duì)于錄制回放模式,簽名類(lèi)是一個(gè)核心組件,它的作用是如何標(biāo)識(shí)一個(gè)請(qǐng)求,對(duì)于不同系統(tǒng)可能有不 一樣的實(shí)現(xiàn);對(duì)于通用樁模式,抽取類(lèi)是一個(gè)核心組件,他的作用是如何提取一個(gè)請(qǐng)求,涉及到如何設(shè)置匹配條件,對(duì)于不同系統(tǒng)(特別是協(xié)議)也可能有不一樣的 實(shí)現(xiàn)。所以這些都是系統(tǒng)提供的可擴(kuò)展接口。
APIs:為了使用上的方便(比如持續(xù)集成),系統(tǒng)基本所有的功能都通過(guò)REST API提供。
