RSF分布式服務(wù)框架設(shè)計(jì):Hasor-RSF
是時(shí)候設(shè)計(jì)一個(gè)分布式服務(wù)框架了。我先將它定名為 Hasor-RSF,“RSF”為 Remote Service Framework 的縮寫(xiě)。
RSF的目的是為了提供一種高效的遠(yuǎn)程服務(wù)訪(fǎng)問(wèn)方式,例如“A機(jī)器訪(fǎng)問(wèn)在B機(jī)器上的一個(gè)服務(wù)”。當(dāng)然首先它是運(yùn)行在Java上的,但是我并不希望 Java 成為 RSF的唯一平臺(tái)。
它應(yīng)該是分布式的,就是說(shuō)服務(wù) A 可能會(huì)分布在若干臺(tái)機(jī)器內(nèi)。 當(dāng)我的應(yīng)用打算調(diào)用這個(gè)服務(wù)時(shí)我應(yīng)該可以在這若干服務(wù)提供的機(jī)器上隨機(jī)調(diào)用。這樣做的好處是有助于高并發(fā)、高訪(fǎng)問(wèn)、高可用。
RSF 的本質(zhì)其實(shí)就是 RPC 那么我們可以先對(duì)比一下 RPC 里都有什么可以被我們拿來(lái)選用。下面列出來(lái)的只是其中一些我相信聰明的朋友們會(huì)列舉出更多的解決方案,我也敢保證你們知道的比我還多。
- Java原生的 RMI。
- Hessian
- WebServices
- Restful
- HTTP Request
- RTMP/AMF
- 淘寶的 HSF、Dubbo
RMI,這個(gè) Java 原生的東東似乎從一開(kāi)始就沒(méi)有被人們所看好,究其原因是速度太慢。但是它的好處是Java原生,使用 RMI 不需要引入其它任何第三方軟件包。不過(guò)挑剔的同學(xué)們似乎不太看好這個(gè)優(yōu)點(diǎn)。
Hessian,原則上說(shuō)Hessian我并不認(rèn)為它是一個(gè)遠(yuǎn)程服務(wù)框架范疇的東西。我更覺(jué)得 Hessian 是一種數(shù)據(jù)交互格式。就像是 JSON,XML-RPC,AMF,Kryo 一類(lèi)的東西。Hessian 的優(yōu)點(diǎn)是大量的兼容平臺(tái)例如:“IOS、Java、.net、C++、Python、Flash、Ruby、PHP”,其次它的第二個(gè)有點(diǎn)是二進(jìn)制格式。在大對(duì)象序列化上會(huì)占有很大的優(yōu)勢(shì)。
WebServices,一個(gè)老牌技術(shù)解決方案。在我印象中 WebServices 是跟隨著 SOA 這個(gè)東西一起出名的,他有一個(gè)***的好處是防火墻穿透。畢竟人家是靠 80 端口吃飯的,牛叉的很。不過(guò)話(huà)說(shuō)回來(lái)WebServices的***要害就是,Xml傳輸格式。把一個(gè)對(duì)象序列化成為一個(gè)Xml數(shù)據(jù)是一件很容易的事,但是反序列化成本似乎是很高。再加上 SOAP 協(xié)議本身是建立在 XML 形式上,這就使得 Web Service 奇慢無(wú)比了。當(dāng)然因素還有很多我就不多說(shuō)了。
Restful,其實(shí) restful 我更覺(jué)得它是一種 API 表述規(guī)范。但在社區(qū)論壇中討論看來(lái),restful 的應(yīng)用似乎也延伸到遠(yuǎn)程服務(wù)的領(lǐng)域。所以有必要說(shuō)明一下。restful 最初是出現(xiàn)在 web 上,究其本質(zhì)是還是 HTTP。例如對(duì)于:“http://xxxxx/xxxx”這個(gè)資源的訪(fǎng)問(wèn)可以利用 HTTP 的“GET、PUT、DELETE”等方法對(duì)資源操作加以描述說(shuō)明。我個(gè)人覺(jué)得這東西用在 RPC 上并不合適。
HTTP,這是我用過(guò)最多的一種遠(yuǎn)程交互方式。遠(yuǎn)離很見(jiàn)dna,服務(wù)發(fā)布者將服務(wù)發(fā)布成為一個(gè)http資源。調(diào)用者請(qǐng)求這個(gè)http資源。數(shù)據(jù)傳輸格式完全程序雙方自行協(xié)商。這種方法簡(jiǎn)單除暴行之有效。不過(guò)缺點(diǎn)是我們要自己補(bǔ)充通信協(xié)議,例如請(qǐng)求參數(shù)和響應(yīng)數(shù)據(jù)格式。常規(guī)的交互格式有 JSON、XML。
RTMP/AMF,這個(gè)組合的確是一套很完善的遠(yuǎn)程調(diào)用解決方案。RTMP協(xié)議中專(zhuān)門(mén)為 Invoke 開(kāi)辟了一條通道,在配合 AMF 格式極大的方便了 Flash 下遠(yuǎn)程服務(wù)訪(fǎng)問(wèn)。不過(guò)這些都是 Flash下的東西,即使是擁有 Red5 這樣的神器讓我們?cè)?java 下可以使用 rtmp 但是究其目的還是為了和 flash 通信。一般 flash 調(diào)用業(yè)務(wù)系統(tǒng)的方式還都停留在 http 請(qǐng)求或者通過(guò) red5 服務(wù)器代為轉(zhuǎn)發(fā)。
HSF,這個(gè)東西是淘寶內(nèi)部用的很廣泛的遠(yuǎn)程服務(wù)框架。它是使用NIO、Mina 并且工作在長(zhǎng)連接模式下。話(huà)說(shuō)這個(gè)東西的確是個(gè)好東西,淘寶也將其開(kāi)源了!只可惜,開(kāi)源了 hsf 但是相關(guān)配套依賴(lài)沒(méi)有開(kāi)源。在加上 hsf 依賴(lài)繁雜。這個(gè)東西也就只能讓局外人膜拜一下,在淘系之外的同學(xué)們是無(wú)福享受了。
Dubbo,也是淘系的另外一個(gè)服務(wù)框架,它比較 HSF 來(lái)說(shuō)要輕巧很多。依賴(lài)會(huì)少一些,這個(gè)東東目前也是開(kāi)源狀態(tài)。由于我對(duì) dubbo 一點(diǎn)都不了解,在這里保持沉默不做評(píng)價(jià)。
***補(bǔ)充一下,真正原生就支持分布式服務(wù)調(diào)用的也就只有“HSF、Dubbo”至于京東內(nèi)部是否有更好的解決方案我并不知道。哦還有一點(diǎn),如果您想脫離 Spring 的話(huà) HSF、Dubbo 會(huì)讓你失望的。這就是說(shuō)您的技術(shù)構(gòu)架如果是非 Spring 陣營(yíng)的會(huì)比較悲催。
so,上面提到了很多可用的技術(shù)方案,想必***符合要求也就只有其中 HSF 和 Dubbo 了。為什么其它的方案都不入選呢?原因就是它們雖然可以完成 RPC 但是并不支持分布式。當(dāng)然您可以通過(guò)架設(shè)集群來(lái)提高它們的可靠性,這些都是您需要額外付出的。
------------------------------
下面這個(gè)是 RSF 的架構(gòu)圖,包括服務(wù)生產(chǎn)著和消費(fèi)者在內(nèi) RSF 被分為 6 層(網(wǎng)絡(luò)層、協(xié)議層、請(qǐng)求響應(yīng)層、調(diào)度層、接口層、消費(fèi)者生產(chǎn)者)。
關(guān)鍵5層:
Netty,其中位于最下層的網(wǎng)通信部分 RSF 采用 Netty 實(shí)現(xiàn)。Netty 是一款非常優(yōu)秀的網(wǎng)絡(luò)通信框架,使用 Netty 可以幫助 RSF 減少大量底層網(wǎng)絡(luò)上的代碼開(kāi)發(fā)。這也就意味著 RSF 將采用 Selector 方式實(shí)現(xiàn)異步IO。
Protocol,協(xié)議層。該層主要的目的是負(fù)責(zé)解釋翻譯 RSF 數(shù)據(jù)包,并將 RSF 數(shù)據(jù)包轉(zhuǎn)意成為 Request 和 Response 對(duì)象。協(xié)議層可以是一個(gè)協(xié)議棧,這就意味您可以通過(guò) RTMP 、或者其它自定義網(wǎng)絡(luò)協(xié)議傳輸 RSF 數(shù)據(jù)包。
Request/Response層,請(qǐng)求響應(yīng)層。這個(gè)在這個(gè)層中,RSF 脫離了底層網(wǎng)絡(luò)方面的特性將每次調(diào)用請(qǐng)求對(duì)象化為一個(gè) Request 對(duì)象,并且將調(diào)用結(jié)果封裝成為一個(gè) Response 對(duì)象。這種編程模式和 Web 很像。
調(diào)度層,這一層最為復(fù)雜。它負(fù)責(zé)管理本地 RSF 服務(wù)的注冊(cè),遠(yuǎn)程傳輸對(duì)象序列化方式的管理,并且還要負(fù)責(zé)實(shí)現(xiàn)其它更加復(fù)雜的功能。
接口層,這一層是最終 RSF 暴露給業(yè)務(wù)系統(tǒng)的接口,將會(huì)由兩個(gè)類(lèi)提供。一個(gè)代表服務(wù)生產(chǎn)著,另一個(gè)是服務(wù)消費(fèi)者。
序列化格式:
RSF 規(guī)定在網(wǎng)絡(luò)中傳輸?shù)臄?shù)據(jù)格式可以是任意的。這就意味著您可以使用 AMF 作為 RSF 數(shù)據(jù)傳輸格式發(fā)布(同時(shí)如果協(xié)議層支持 RTMP 那您可以在 Flash 中無(wú)需通過(guò) red5 這樣的中間代理直接訪(fǎng)問(wèn) RSF 服務(wù))。同樣的,如果您使用 Hessian 作為數(shù)據(jù)傳輸格式,在其它平臺(tái)。例如 .net、php。也會(huì)很方便的調(diào)用 RSF 服務(wù)(需要解析 RSF 數(shù)據(jù)包)。如果協(xié)議采用 HTTP,RSF序列化格式采用 JSON ,那么運(yùn)行在瀏覽器中的 javascript 也可以繞過(guò) web 服務(wù)器,直接訪(fǎng)問(wèn) RSF 服務(wù)。
服務(wù)配置Config:
說(shuō)是服務(wù)配置,其實(shí)就是路由的功能。先假設(shè)我們有4臺(tái)服務(wù)器,其中有兩臺(tái)是位于北京機(jī)房,另外兩臺(tái)分別位于青島和內(nèi)蒙古。這四臺(tái)機(jī)器上都運(yùn)行著 RSF,跑著相同的業(yè)務(wù)系統(tǒng),這種架構(gòu)通常前端會(huì)有一個(gè) CDN 之類(lèi)的東西負(fù)責(zé)讓用戶(hù)就近訪(fǎng)問(wèn)網(wǎng)站。
如果沒(méi)有服務(wù)路由的情況下,用戶(hù)A在北京即使訪(fǎng)問(wèn)了最近的北京服務(wù)器,但是由于調(diào)用的 RDS 服務(wù)是青島的,那么也會(huì)降低訪(fǎng)問(wèn)速度。因此服務(wù)配置所負(fù)責(zé)的 路由特性可以很方便的高速服務(wù)調(diào)用程序,優(yōu)先選用北京機(jī)房的 RSF 服務(wù)。只有當(dāng)北京機(jī)房的服務(wù)撐不住的情況下才會(huì)動(dòng)用其它地域的 RSF 服務(wù)。
流量管控:高級(jí)一點(diǎn)的特性是可以通過(guò)服務(wù)路由來(lái)控制服務(wù)流量。假如目前要做一個(gè)全國(guó)范圍的活動(dòng),我們充分的為每個(gè)地方準(zhǔn)備了若干機(jī)器。但是在活動(dòng)現(xiàn)場(chǎng)很可能某一個(gè)地區(qū)的服務(wù)使用量達(dá)到了臨界點(diǎn),服務(wù)路由應(yīng)該可以通過(guò)配置的方式讓附近地區(qū)的機(jī)器提供一定的流量來(lái)減緩這個(gè)地區(qū)的訪(fǎng)問(wèn)壓力。