本發(fā)明涉及計(jì)算機(jī)網(wǎng)絡(luò)技術(shù)領(lǐng)域,具體涉及一種基于共享內(nèi)存的服務(wù)發(fā)現(xiàn)方法、裝置及系統(tǒng)、服務(wù)器。
背景技術(shù):
服務(wù)發(fā)現(xiàn)組件記錄了(大規(guī)模)分布式系統(tǒng)中所有服務(wù)的信息,人們或者其它服務(wù)可以據(jù)此找到這些服務(wù)。DNS就是一個(gè)簡(jiǎn)單的例子。當(dāng)然,復(fù)雜系統(tǒng)的服務(wù)發(fā)現(xiàn)組件要提供更多的功能,例如,服務(wù)元數(shù)據(jù)存儲(chǔ)、健康監(jiān)控、多種查詢(xún)和實(shí)時(shí)更新等。服務(wù)發(fā)現(xiàn)給當(dāng)前互聯(lián)網(wǎng)架構(gòu)的網(wǎng)絡(luò)公司帶來(lái)的好處就是零配置,不需要硬編碼網(wǎng)絡(luò)地址到應(yīng)用中,只需有服務(wù)的名字即可找到該服務(wù)的后端服務(wù)列表和網(wǎng)絡(luò)拓?fù)湫畔ⅰ?/p>
目前業(yè)界提供了多種服務(wù)發(fā)現(xiàn)的解決方案,但是目前公開(kāi)的各種服務(wù)發(fā)現(xiàn)解決方案都沒(méi)有完美的解決所有問(wèn)題。舉例來(lái)說(shuō),DNS,在小規(guī)模系統(tǒng)可以先使用DNS作為服務(wù)發(fā)現(xiàn)手段。一旦服務(wù)節(jié)點(diǎn)的啟動(dòng)和銷(xiāo)毀變得更加動(dòng)態(tài),DNS就會(huì)出現(xiàn)問(wèn)題,因?yàn)镈NS記錄傳播的速度可能跟不上服務(wù)節(jié)點(diǎn)變化的速度。常見(jiàn)的服務(wù)發(fā)現(xiàn)相關(guān)的解決方案還有類(lèi)似dubbo這種基于某個(gè)編程語(yǔ)言的,但是這種基于特定語(yǔ)言的服務(wù)發(fā)現(xiàn)問(wèn)題也是顯而易見(jiàn)的,因?yàn)榇蠖鄶?shù)互聯(lián)網(wǎng)公司內(nèi)部使用的編程語(yǔ)言都不止一種,限定到語(yǔ)言級(jí)別則會(huì)將服務(wù)發(fā)現(xiàn)的能力大大降低。
技術(shù)實(shí)現(xiàn)要素:
鑒于上述問(wèn)題,提出了本發(fā)明以便提供一種克服上述問(wèn)題或者至少部分地解決上述問(wèn)題的基于共享內(nèi)存的服務(wù)發(fā)現(xiàn)方法、裝置及系統(tǒng)、服務(wù)器。
根據(jù)本發(fā)明的一個(gè)方面,提供了一種基于共享內(nèi)存的服務(wù)發(fā)現(xiàn)方法,包括:
監(jiān)聽(tīng)并獲取消息隊(duì)列中記錄的服務(wù)名稱(chēng);其中,所述服務(wù)名稱(chēng)是客戶(hù)端接收到應(yīng)用層訪問(wèn)服務(wù)的請(qǐng)求之后,在共享內(nèi)存中未查詢(xún)到所述服務(wù)的服務(wù)提供者信息而寫(xiě)入到消息隊(duì)列中;
根據(jù)所述服務(wù)名稱(chēng),從服務(wù)注冊(cè)組件處獲取所述服務(wù)的服務(wù)提供者信息;
將所述服務(wù)的服務(wù)提供者信息寫(xiě)入共享內(nèi)存中,以供客戶(hù)端從共享內(nèi)存中讀取所述服務(wù)的服務(wù)提供者信息并返回給應(yīng)用層。
根據(jù)本發(fā)明的另一方面,提供了一種基于共享內(nèi)存的服務(wù)發(fā)現(xiàn)裝置,包括:
監(jiān)聽(tīng)模塊,適于監(jiān)聽(tīng)并獲取消息隊(duì)列中記錄的服務(wù)名稱(chēng);其中,所述服務(wù)名稱(chēng)是客戶(hù)端接收到應(yīng)用層訪問(wèn)服務(wù)的請(qǐng)求之后,在共享內(nèi)存中未查詢(xún)到所述服務(wù)的服務(wù)提供者信息而寫(xiě)入到消息隊(duì)列中;
獲取模塊,適于根據(jù)所述服務(wù)名稱(chēng),從服務(wù)注冊(cè)組件處獲取所述服務(wù)的服務(wù)提供者信息;
寫(xiě)入模塊,適于將所述服務(wù)的服務(wù)提供者信息寫(xiě)入共享內(nèi)存中,以供客戶(hù)端從共享內(nèi)存中讀取所述服務(wù)的服務(wù)提供者信息并返回給應(yīng)用層。
根據(jù)本發(fā)明的另一方面,提供了一種基于共享內(nèi)存的服務(wù)發(fā)現(xiàn)系統(tǒng),包括:上述基于共享內(nèi)存的服務(wù)發(fā)現(xiàn)裝置、共享內(nèi)存、客戶(hù)端以及服務(wù)注冊(cè)組件;
所述客戶(hù)端適于:在接收到應(yīng)用層訪問(wèn)服務(wù)的請(qǐng)求之后,在共享內(nèi)存中查詢(xún)到所述服務(wù)的服務(wù)提供者信息,若未查詢(xún)到,則將服務(wù)名稱(chēng)寫(xiě)入到消息隊(duì)列中;若查詢(xún)到,則從共享內(nèi)存中讀取所述服務(wù)的服務(wù)提供者信息并返回給應(yīng)用層。
根據(jù)本發(fā)明的又一方面,提供了一種服務(wù)器,包括:處理器、存儲(chǔ)器、通信接口和通信總線,所述處理器、所述存儲(chǔ)器和所述通信接口通過(guò)所述通信總線完成相互間的通信;
所述存儲(chǔ)器用于存放至少一可執(zhí)行指令,所述可執(zhí)行指令使所述處理器執(zhí)行上述基于共享內(nèi)存的服務(wù)發(fā)現(xiàn)方法對(duì)應(yīng)的操作。
根據(jù)本發(fā)明的再一方面,提供了一種計(jì)算機(jī)存儲(chǔ)介質(zhì),所述存儲(chǔ)介質(zhì)中存儲(chǔ)有至少一可執(zhí)行指令,所述可執(zhí)行指令使所述處理器執(zhí)行如上述基于共享內(nèi)存的服務(wù)發(fā)現(xiàn)方法對(duì)應(yīng)的操作。
根據(jù)本發(fā)明提供的基于共享內(nèi)存的服務(wù)發(fā)現(xiàn)方法、裝置及系統(tǒng)、服務(wù)器,在客戶(hù)端接收到應(yīng)用層訪問(wèn)服務(wù)的請(qǐng)求之后,首先在共享內(nèi)存中查詢(xún)服務(wù)的服務(wù)提供者信息,若查詢(xún)到,則直接在共享內(nèi)存中讀取服務(wù)提供者信息;若未查詢(xún)到,則通過(guò)網(wǎng)絡(luò)去服務(wù)注冊(cè)組件中獲取服務(wù)提供者信息。利用本方案,達(dá)到了應(yīng)用層在獲取服務(wù)列表配置信息時(shí)和獲取本地內(nèi)存讀寫(xiě)一樣的性能,減少了網(wǎng)絡(luò)延遲,提升了讀取速度,這種與后端分布式集群通信產(chǎn)生共享內(nèi)存并提供客戶(hù)端供應(yīng)用使用的方式,避免了客戶(hù)端和分布式集群之間用長(zhǎng)連接方式進(jìn)行對(duì)接而導(dǎo)致的資源占用過(guò)多、服務(wù)注冊(cè)組件處理效率低下的問(wèn)題。
上述說(shuō)明僅是本發(fā)明技術(shù)方案的概述,為了能夠更清楚了解本發(fā)明的技術(shù)手段,而可依照說(shuō)明書(shū)的內(nèi)容予以實(shí)施,并且為了讓本發(fā)明的上述和其它目的、特征和優(yōu)點(diǎn)能夠更明顯易懂,以下特舉本發(fā)明的具體實(shí)施方式。
附圖說(shuō)明
通過(guò)閱讀下文優(yōu)選實(shí)施方式的詳細(xì)描述,各種其他的優(yōu)點(diǎn)和益處對(duì)于本領(lǐng)域普通技術(shù)人員將變得清楚明了。附圖僅用于示出優(yōu)選實(shí)施方式的目的,而并不認(rèn)為是對(duì)本發(fā)明的限制。而且在整個(gè)附圖中,用相同的參考符號(hào)表示相同的部件。在附圖中:
圖1示出了根據(jù)本發(fā)明一個(gè)實(shí)施例的基于共享內(nèi)存的服務(wù)發(fā)現(xiàn)方法的流程圖;
圖2示出了本發(fā)明一個(gè)實(shí)施例中服務(wù)發(fā)現(xiàn)數(shù)據(jù)結(jié)構(gòu)存儲(chǔ)模型的示意圖;
圖3示出了根據(jù)本發(fā)明另一個(gè)實(shí)施例的基于共享內(nèi)存的服務(wù)發(fā)現(xiàn)方法的流程圖;
圖4示出了實(shí)現(xiàn)本發(fā)明一個(gè)實(shí)施例的基于共享內(nèi)存的服務(wù)發(fā)現(xiàn)方法的系統(tǒng)架構(gòu)示意圖;
圖5示出了本發(fā)明一個(gè)實(shí)施例中agent內(nèi)部線程模型的示意圖;
圖6示出了本發(fā)明一個(gè)實(shí)施例中各個(gè)語(yǔ)言接入共享內(nèi)存進(jìn)行通信的示意圖;
圖7示出了根據(jù)本發(fā)明一個(gè)實(shí)施例的服務(wù)發(fā)現(xiàn)協(xié)議的分層模型示意圖;
圖8示出了根據(jù)本發(fā)明一個(gè)實(shí)施例的服務(wù)注冊(cè)集群中服務(wù)健康檢查的架構(gòu)示意圖;
圖9示出了根據(jù)本發(fā)明一個(gè)實(shí)施例的基于共享內(nèi)存的服務(wù)發(fā)現(xiàn)裝置的功能框圖;
圖10示出了根據(jù)本發(fā)明一個(gè)實(shí)施例的基于共享內(nèi)存的服務(wù)發(fā)現(xiàn)系統(tǒng)的功能框圖;
圖11示出了根據(jù)本發(fā)明實(shí)施例六的一種服務(wù)器的結(jié)構(gòu)示意圖。
具體實(shí)施方式
下面將參照附圖更詳細(xì)地描述本公開(kāi)的示例性實(shí)施例。雖然附圖中顯示了本公開(kāi)的示例性實(shí)施例,然而應(yīng)當(dāng)理解,可以以各種形式實(shí)現(xiàn)本公開(kāi)而不應(yīng)被這里闡述的實(shí)施例所限制。相反,提供這些實(shí)施例是為了能夠更透徹地理解本公開(kāi),并且能夠?qū)⒈竟_(kāi)的范圍完整的傳達(dá)給本領(lǐng)域的技術(shù)人員。
在對(duì)本發(fā)明的技術(shù)方案進(jìn)行介紹之前,首先對(duì)本發(fā)明實(shí)施例中所涉及的技術(shù)術(shù)語(yǔ)進(jìn)行簡(jiǎn)單介紹:
服務(wù)發(fā)現(xiàn):當(dāng)某個(gè)服務(wù)添加的服務(wù)集群中時(shí),該服務(wù)所暴露的調(diào)用地址能夠被其使用方自動(dòng)感知到并進(jìn)行調(diào)用。
共享內(nèi)存(SHM):在多處理器的計(jì)算機(jī)系統(tǒng)中,可以被不同中央處理器(CPU)訪問(wèn)的大容量?jī)?nèi)存。
進(jìn)程間通信(IPC):一組編程接口,讓程序員能夠協(xié)調(diào)不同的進(jìn)程,使之能在一個(gè)操作系統(tǒng)里同時(shí)運(yùn)行,并相互傳遞、交換信息。
負(fù)載均衡(LB):建立在網(wǎng)絡(luò)結(jié)構(gòu)之上,能夠?qū)⒄?qǐng)求分?jǐn)偟蕉鄠€(gè)操作單元上進(jìn)行執(zhí)行,例如Web服務(wù)器、FTP服務(wù)器、企業(yè)關(guān)鍵應(yīng)用服務(wù)器和其它關(guān)鍵任務(wù)服務(wù)器等,從而共同完成工作任務(wù)。常見(jiàn)的負(fù)載均衡軟件有HAPROXY,nginx,LVS等。
服務(wù)注冊(cè)組件:一個(gè)通用的分布式組件,該組件通常通過(guò)的分布式算法進(jìn)行實(shí)現(xiàn),主要用于保障分布式復(fù)雜網(wǎng)絡(luò)環(huán)境,多個(gè)服務(wù)器針對(duì)某個(gè)服務(wù)的事務(wù)性,一致性,可靠性。這種服務(wù)注冊(cè)組件常見(jiàn)的開(kāi)源實(shí)現(xiàn)有zookeeper,etcd,consul等。
本發(fā)明的發(fā)明人在研究現(xiàn)有技術(shù)的過(guò)程中,發(fā)現(xiàn)現(xiàn)有技術(shù)提供的服務(wù)發(fā)現(xiàn)解決方案存在以下未解決的難題,并對(duì)這些難題未解決的原因進(jìn)行了具體分析。
難題一,應(yīng)用層在獲取服務(wù)列表配置信息時(shí)不能保證和獲取本地內(nèi)存讀寫(xiě)一樣的性能,之所以說(shuō)保持內(nèi)存讀寫(xiě)級(jí)別的性能是個(gè)難題,主要有以下幾個(gè)原因?qū)е拢?/p>
(1)當(dāng)客戶(hù)端獲取在服務(wù)注冊(cè)組件所注冊(cè)的服務(wù)時(shí),如果每個(gè)客戶(hù)端都走長(zhǎng)連接,由于應(yīng)用數(shù)量和應(yīng)用進(jìn)程數(shù)不可控,會(huì)導(dǎo)致長(zhǎng)連接過(guò)多致使服務(wù)注冊(cè)組件處理效率低下,資源占用過(guò)多;
(2)當(dāng)客戶(hù)端獲取在服務(wù)注冊(cè)組件所注冊(cè)的服務(wù)時(shí),如果每個(gè)客戶(hù)端走短連接,那么獲取服務(wù)注冊(cè)組件的服務(wù)本身就需要有個(gè)網(wǎng)絡(luò)層1到5ms的開(kāi)銷(xiāo),使得服務(wù)性能低下;
(3)常見(jiàn)的分布式組件應(yīng)用設(shè)計(jì)上大多考慮更多的是分布式一致性和可靠性問(wèn)題,對(duì)分布式服務(wù)本身提供的高性能方面有先天性不足。舉例來(lái)說(shuō),當(dāng)分布式組件集群中有一個(gè)或者多個(gè)節(jié)點(diǎn)宕機(jī)時(shí),這時(shí)分布式組件集群為了保證可靠性和重新選舉策略,一般都會(huì)有相當(dāng)大的開(kāi)銷(xiāo),這時(shí)該分布式組件的寫(xiě)入和讀取性能有較大的損失。
難題二,跨語(yǔ)言的通用性服務(wù)發(fā)現(xiàn)實(shí)現(xiàn)困難,其難以實(shí)現(xiàn)的主要原因由以下幾個(gè)方面:
(1)不是所有的編程語(yǔ)言都支持長(zhǎng)連接的方式進(jìn)行實(shí)時(shí)通信;
(2)不是所有的語(yǔ)言對(duì)分布式組件比如zookeeper,etcd等都有完善的API支持;
(3)實(shí)現(xiàn)某個(gè)特定語(yǔ)言的客戶(hù)端對(duì)分布式組件(比如:zookeeper)的使用已經(jīng)非常困難,要實(shí)現(xiàn)各個(gè)語(yǔ)言保持一致的使用方式的使用更是難上加難。
難題三,基于統(tǒng)一模型的服務(wù)發(fā)現(xiàn)技術(shù)需要兼容服務(wù)端的服務(wù)發(fā)現(xiàn)機(jī)制和客戶(hù)端的服務(wù)發(fā)現(xiàn)機(jī)制。
傳統(tǒng)的服務(wù)發(fā)現(xiàn)的架構(gòu)模式要么是服務(wù)端服務(wù)發(fā)現(xiàn),要么是客戶(hù)端服務(wù)發(fā)現(xiàn),兩個(gè)方案各有優(yōu)缺點(diǎn),在實(shí)際生產(chǎn)環(huán)境的應(yīng)用上,往往需要兼容服務(wù)端的服務(wù)發(fā)現(xiàn)和客戶(hù)端的服務(wù)發(fā)現(xiàn)。常見(jiàn)的服務(wù)端服務(wù)發(fā)現(xiàn)的架構(gòu)模式一般都是將服務(wù)動(dòng)態(tài)注冊(cè)到一個(gè)LB(load balancer,負(fù)載均衡)上,然后客戶(hù)端的調(diào)用從LB獲取服務(wù)。常見(jiàn)的客戶(hù)端服務(wù)發(fā)現(xiàn)的架構(gòu)模式是在客戶(hù)端綁定一個(gè)負(fù)載均衡邏輯塊,該負(fù)載均衡邏輯塊負(fù)責(zé)和服務(wù)注冊(cè)中心通訊獲取服務(wù)列表然后通過(guò)負(fù)載均衡算法進(jìn)行返回。
為了克服以上至少一個(gè)難題,本發(fā)明提供了一種基于共享內(nèi)存的服務(wù)發(fā)現(xiàn)方法。下面通過(guò)幾個(gè)具體的實(shí)施例對(duì)本發(fā)明的具體實(shí)現(xiàn)方案進(jìn)行詳細(xì)介紹。
實(shí)施例一
圖1示出了根據(jù)本發(fā)明一個(gè)實(shí)施例的基于共享內(nèi)存的服務(wù)發(fā)現(xiàn)方法的流程圖。如圖1所示,該方法包括如下步驟:
步驟S101,監(jiān)聽(tīng)并獲取消息隊(duì)列中記錄的服務(wù)名稱(chēng);其中,服務(wù)名稱(chēng)是客戶(hù)端接收到應(yīng)用層訪問(wèn)服務(wù)的請(qǐng)求之后,在共享內(nèi)存中未查詢(xún)到服務(wù)的服務(wù)提供者信息而寫(xiě)入到消息隊(duì)列中。
步驟S102,根據(jù)服務(wù)名稱(chēng),從服務(wù)注冊(cè)組件處獲取服務(wù)的服務(wù)提供者信息。
步驟S103,將服務(wù)的服務(wù)提供者信息寫(xiě)入共享內(nèi)存中,以供客戶(hù)端從共享內(nèi)存中讀取服務(wù)的服務(wù)提供者信息并返回給應(yīng)用層。
本發(fā)明實(shí)施例中,服務(wù)注冊(cè)組件用來(lái)存儲(chǔ)服務(wù)節(jié)點(diǎn)相關(guān)的元數(shù)據(jù)。在服務(wù)注冊(cè)系統(tǒng)中,存在監(jiān)聽(tīng)單元,負(fù)責(zé)監(jiān)聽(tīng)新加入的服務(wù)提供者,將服務(wù)提供者進(jìn)行抽象為服務(wù)注冊(cè)節(jié)點(diǎn),并獲取服務(wù)注冊(cè)節(jié)點(diǎn)的元數(shù)據(jù)(包含主機(jī)端口,名稱(chēng)等),調(diào)用接口將服務(wù)注冊(cè)節(jié)點(diǎn)的元數(shù)據(jù)寫(xiě)入到服務(wù)注冊(cè)組件中。常見(jiàn)的服務(wù)注冊(cè)節(jié)點(diǎn)的數(shù)據(jù)存儲(chǔ)模型都是樹(shù)形結(jié)構(gòu),針對(duì)該種類(lèi)型的數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)的服務(wù)發(fā)現(xiàn)存儲(chǔ)模型如圖2所示。
namespace:名字空間(即服務(wù)名稱(chēng)),每個(gè)服務(wù)都會(huì)有一個(gè)namespace與之對(duì)應(yīng)。每個(gè)namespace又會(huì)有兩個(gè)子節(jié)點(diǎn)providers和consumers;
providers:服務(wù)提供者,用于通過(guò)名字空間獲??;服務(wù)提供者信息包含提供服務(wù)的各個(gè)主機(jī)的主機(jī)端口;
consumers:服務(wù)消費(fèi)者,用于記錄使用該服務(wù)的節(jié)點(diǎn)信息,服務(wù)消費(fèi)者信息包含使用服務(wù)的各個(gè)主機(jī)的主機(jī)端口。
為了保障應(yīng)用層在獲取服務(wù)列表配置信息時(shí)能和獲取本地內(nèi)存讀寫(xiě)一樣的性能,并且在服務(wù)注冊(cè)組件中服務(wù)列表變更時(shí)能夠同步實(shí)時(shí)的感知到服務(wù)的變更信息,本發(fā)明的解決方案提供一個(gè)共享內(nèi)存和agent,該agent負(fù)責(zé)和服務(wù)注冊(cè)組件進(jìn)行通信并保證服務(wù)注冊(cè)組件內(nèi)的變更能夠?qū)崟r(shí)通知到該agent,然后該agent產(chǎn)生共享內(nèi)存供其他應(yīng)用使用。
在上述步驟S101中,客戶(hù)端接收到應(yīng)用層訪問(wèn)服務(wù)的請(qǐng)求之后,在共享內(nèi)存中查詢(xún)服務(wù)的服務(wù)提供者(providers)信息,若未查詢(xún)到,則將服務(wù)名稱(chēng)(namespace)寫(xiě)入agent的消息隊(duì)列中。agent實(shí)時(shí)監(jiān)聽(tīng)和獲取消息隊(duì)列中記錄的服務(wù)名稱(chēng)。
在上述步驟S102中,若agent監(jiān)聽(tīng)到消息隊(duì)列中存在服務(wù)名稱(chēng),則從中提取出服務(wù)名稱(chēng),從服務(wù)注冊(cè)組件處獲取服務(wù)的服務(wù)提供者信息。
在上述步驟S103中,agent將服務(wù)的服務(wù)提供者信息寫(xiě)入共享內(nèi)存中,以供客戶(hù)端從共享內(nèi)存中讀取服務(wù)的服務(wù)提供者信息并返回給應(yīng)用層。
由于linux跨進(jìn)程通信中基于共享內(nèi)存的方式具有高性能,可靠性的特點(diǎn)因此本方案通過(guò)將與服務(wù)注冊(cè)組件進(jìn)行網(wǎng)絡(luò)通信的模塊移交到agent中,然后讓agent產(chǎn)生共享內(nèi)存供其他客戶(hù)端使用,利用這種方式,避免了客戶(hù)端本身和服務(wù)注冊(cè)組件進(jìn)行通信的網(wǎng)絡(luò)開(kāi)銷(xiāo),也使得客戶(hù)端本身幾乎沒(méi)有額外的性能開(kāi)銷(xiāo)。
實(shí)施例二
圖3示出了根據(jù)本發(fā)明另一個(gè)實(shí)施例的基于共享內(nèi)存的服務(wù)發(fā)現(xiàn)方法的流程圖,圖4示出了實(shí)現(xiàn)本發(fā)明一個(gè)實(shí)施例的基于共享內(nèi)存的服務(wù)發(fā)現(xiàn)方法的系統(tǒng)架構(gòu)示意圖,圖5示出了本發(fā)明一個(gè)實(shí)施例中agent內(nèi)部線程模型的示意圖。下面結(jié)合圖3、圖4和圖5對(duì)本發(fā)明實(shí)施例二的詳細(xì)步驟進(jìn)行介紹。
如圖3所示,該方法包括如下步驟:
步驟S200,服務(wù)注冊(cè)步驟。
服務(wù)注冊(cè)一般都會(huì)有服務(wù)注冊(cè)組件用來(lái)存儲(chǔ)服務(wù)節(jié)點(diǎn)相關(guān)的元數(shù)據(jù)。如圖2所示,常見(jiàn)的服務(wù)注冊(cè)節(jié)點(diǎn)的數(shù)據(jù)存儲(chǔ)模型都是樹(shù)形結(jié)構(gòu)。從使用方角度來(lái)講服務(wù)自身的注冊(cè)邏輯應(yīng)當(dāng)盡可能的簡(jiǎn)單,最好簡(jiǎn)單到一步即可完成,但是又考慮到服務(wù)注冊(cè)本身并不是任何應(yīng)用均可以隨意注冊(cè),其自身還需要有權(quán)限管理和授權(quán)機(jī)制,因此本發(fā)明實(shí)施例抽象出一個(gè)API層專(zhuān)門(mén)用于服務(wù)注冊(cè)到服務(wù)注冊(cè)組件上,該API層實(shí)現(xiàn)的API主要基于以上樹(shù)形結(jié)構(gòu)的服務(wù)注冊(cè)組件元信息進(jìn)行開(kāi)發(fā),API概要如下:
1,獲取namespace列表接口
GET/zkapi/v1/namespace
2,創(chuàng)建namespace接口
POST/zkapi/v1/{namespace}
data={"name":"namespace"}邏輯上會(huì)創(chuàng)建namespace節(jié)點(diǎn)以及其子節(jié)點(diǎn)providers和consumers
3,刪除namespace接口
DEL/zkapi/v1/{namespace}
4,獲取某個(gè)namespace下提供的服務(wù)列表和服務(wù)策略
GET/zkapi/v1/{namespace}/providers
5,添加或更新一個(gè)服務(wù)提供者到某個(gè)namespace
POST/zkapi/v1/{namespace}/providers/{service_name}
data={"host":"192.168.56.32","port":"4455"}
6,刪除某個(gè)namespace下的一個(gè)服務(wù)提供者
DEL/zkapi/v1/{namespace}/providers/{service_name}
7,獲取某個(gè)namespace下消費(fèi)者的列表
GET/zkapi/v1/{namespace}/consumers
8,刪除某個(gè)namespace下的消費(fèi)者
DEL/zkapi/v1/{namespace}/consumers/{consumer_name}
9,添加消費(fèi)者到某個(gè)namespace下
POST/zkapi/v1/{namespace}/consumers/{service_name}
data={"service_value":"ip:port"}
10,修改某個(gè)namespace下providers節(jié)點(diǎn)值屬性
POST/zkapi/v1/{namespace}/providers
data={"load_banlance":"RR","on_faile":"url"}
步驟S201,生成動(dòng)態(tài)鏈接庫(kù)向利用不同編程語(yǔ)言實(shí)現(xiàn)的客戶(hù)端提供統(tǒng)一的共享內(nèi)存查詢(xún)接口。
為了解決跨語(yǔ)言的通用性服務(wù)發(fā)現(xiàn)實(shí)現(xiàn)困難的難題,本實(shí)施例提供的解決方案是不再在各個(gè)語(yǔ)言?xún)?nèi)部進(jìn)行服務(wù)注冊(cè)組件的實(shí)現(xiàn),而是使用統(tǒng)一的編程語(yǔ)言,如C++編程語(yǔ)言對(duì)服務(wù)注冊(cè)組件API進(jìn)行調(diào)用和服務(wù)發(fā)現(xiàn)邏輯的封裝,用C++生成動(dòng)態(tài)鏈接庫(kù)的方式來(lái)對(duì)外提供統(tǒng)一的服務(wù)發(fā)現(xiàn)的API。圖6示出了本發(fā)明一個(gè)實(shí)施例中各個(gè)語(yǔ)言接入共享內(nèi)存進(jìn)行通信的示意圖。如圖6所示,服務(wù)發(fā)現(xiàn)策略實(shí)現(xiàn)的各個(gè)語(yǔ)言接入主要支持:Java,Python,php,C/C++,lua等,還可支持shell,go等語(yǔ)言。各個(gè)語(yǔ)言接入共享內(nèi)存主要通過(guò)動(dòng)態(tài)鏈接庫(kù)(.so文件)來(lái)和共享內(nèi)存進(jìn)行通信,各個(gè)語(yǔ)言通過(guò)封裝動(dòng)態(tài)鏈接庫(kù)和服務(wù)發(fā)現(xiàn)邏輯提供的服務(wù)發(fā)現(xiàn)的接口只有一個(gè)即:get_service,接口參數(shù)為namespace和algorithm,該函數(shù)根據(jù)algorithm參數(shù)對(duì)namespace下的providers進(jìn)行篩選從而返回一個(gè)provider出來(lái)給應(yīng)用層使用。
步驟S202,客戶(hù)端接收到應(yīng)用層訪問(wèn)服務(wù)的請(qǐng)求之后,在共享內(nèi)存中查詢(xún)?cè)摲?wù)的服務(wù)提供者信息,若查詢(xún)到,則執(zhí)行步驟S207;若未查詢(xún)到,則執(zhí)行步驟S203。
客戶(hù)端在接收到應(yīng)用層訪問(wèn)服務(wù)的請(qǐng)求之后,首先在共享內(nèi)存中查詢(xún)?cè)摲?wù)的providers信息,若共享內(nèi)存中預(yù)先存儲(chǔ)有該服務(wù)的providers信息,則可直接讀取。若共享內(nèi)存中沒(méi)有存儲(chǔ)該服務(wù)的providers信息,繼續(xù)執(zhí)行步驟S203。
本實(shí)施例主要是利用服務(wù)注冊(cè)集群中的節(jié)點(diǎn)變更通知特性監(jiān)聽(tīng)節(jié)點(diǎn)事件的發(fā)生,從而進(jìn)行共享內(nèi)存中節(jié)點(diǎn)的增刪改查,盡量保證共享內(nèi)存中節(jié)點(diǎn)信息與服務(wù)注冊(cè)組件中的節(jié)點(diǎn)信息一致。具體地,監(jiān)聽(tīng)服務(wù)注冊(cè)組件中的內(nèi)容變更,將這些變更情況同步到共享內(nèi)存中。
步驟S203,將該服務(wù)的服務(wù)名稱(chēng)寫(xiě)入到消息隊(duì)列中。
步驟S204,代理agent監(jiān)聽(tīng)并獲取消息隊(duì)列中記錄的服務(wù)名稱(chēng)。
步驟S205,根據(jù)服務(wù)名稱(chēng),從服務(wù)注冊(cè)組件處獲取該服務(wù)的服務(wù)提供者信息。
步驟S206,將該服務(wù)的服務(wù)提供者信息寫(xiě)入共享內(nèi)存中。
代理agent內(nèi)部主要使用4個(gè)線程保證服務(wù)穩(wěn)定可靠,如圖5所示,主線程啟動(dòng)后,從消息隊(duì)列中獲取待查詢(xún)的服務(wù)名稱(chēng),然后從服務(wù)注冊(cè)組件處獲取該服務(wù)的服務(wù)提供者信息,并更新到共享內(nèi)存中。如果更新共享內(nèi)存成功,主線程還會(huì)將查詢(xún)到的數(shù)據(jù)發(fā)送到另一隊(duì)列中用于一些額外的操作。
消息線程負(fù)責(zé)從消息隊(duì)列里取服務(wù)名稱(chēng)。因?yàn)橄到y(tǒng)的消息隊(duì)列大小有限制,若隊(duì)列內(nèi)的數(shù)據(jù)未及時(shí)取走,則可能因?yàn)榭蛻?hù)端在短時(shí)間內(nèi)大量寫(xiě)入服務(wù)名稱(chēng)而將隊(duì)列填滿(mǎn),之后的服務(wù)名稱(chēng)將無(wú)法再寫(xiě)入,造成錯(cuò)誤。而agent獲得服務(wù)名稱(chēng)后,需要通過(guò)網(wǎng)絡(luò)去服務(wù)注冊(cè)組件上取得服務(wù)提供者信息,相對(duì)較慢(10ms左右),因此很可能發(fā)生隊(duì)列的積壓填滿(mǎn)。為了避免出現(xiàn)這種問(wèn)題,agent監(jiān)聽(tīng)消息隊(duì)列中記錄的服務(wù)名稱(chēng),將消息隊(duì)列中記錄的服務(wù)名稱(chēng)讀到內(nèi)存中,并及時(shí)清除消息隊(duì)列中記錄的服務(wù)名稱(chēng),防止填滿(mǎn)隊(duì)列。主線程從內(nèi)存里獲得需要讀取的服務(wù)名稱(chēng),再去服務(wù)注冊(cè)組件上取值。
輔助線程負(fù)責(zé)每隔預(yù)定時(shí)間掃描共享內(nèi)存中的服務(wù)提供者信息;將共享內(nèi)存中的服務(wù)提供者信息與服務(wù)注冊(cè)組件中的服務(wù)提供者信息進(jìn)行比對(duì);若比對(duì)不一致,則根據(jù)服務(wù)注冊(cè)組件中的服務(wù)提供者信息更新共享內(nèi)存中的服務(wù)提供者信息。
因?yàn)榉?wù)注冊(cè)組件的watcher機(jī)制不能設(shè)置為持久監(jiān)視,而是一次性的,也就是說(shuō),一個(gè)事件被觸發(fā)一次后,該watcher就被自動(dòng)銷(xiāo)毀,如果要繼續(xù)監(jiān)視下次事件,只能重新注冊(cè)watcher。所以本發(fā)明采取的策略是事件發(fā)生后,第一時(shí)間先重新注冊(cè)watcher,再執(zhí)行具體的處理邏輯,盡量減少上個(gè)watcher銷(xiāo)毀與下個(gè)watcher注冊(cè)的時(shí)間間隔。盡管如此,這二者仍然不是事務(wù)性操作,因此仍有極小概率會(huì)丟失事件。為了防止這種情況發(fā)生,本發(fā)明會(huì)每隔30-60分鐘掃描共享內(nèi)存里的所有節(jié)點(diǎn),并與服務(wù)注冊(cè)組件上的最新值比較,若有差異則更新到最新值,并為可能遺漏監(jiān)視的節(jié)點(diǎn)重新注冊(cè)watcher。
觸發(fā)線程實(shí)際上是一個(gè)多功能線程,主要是數(shù)據(jù)在共享內(nèi)存更新完成后需要執(zhí)行的額外操作,當(dāng)前主要操作有備份(dump),執(zhí)行腳本以及信息反饋。
步驟S207,客戶(hù)端從共享內(nèi)存中讀取該服務(wù)的服務(wù)提供者信息。
從圖4所示的系統(tǒng)架構(gòu)圖上可以看出,agent與客戶(hù)端并沒(méi)有直接的通訊,二者的交互的一個(gè)渠道是共享內(nèi)存。共享內(nèi)存的作用在于,客戶(hù)端可能會(huì)多次讀取相同的配置項(xiàng)(其值可能并不會(huì)每次都改變),如果沒(méi)有在本機(jī)存儲(chǔ)這些配置項(xiàng),那么就必然需要每次通過(guò)網(wǎng)絡(luò)去服務(wù)注冊(cè)組件服務(wù)端讀取(相同的值),一是存在網(wǎng)絡(luò)延遲,二是服務(wù)注冊(cè)組件本身性能并不高,不適合大量的頻繁讀操作。之所以選用共享內(nèi)存這種存儲(chǔ)方式,是看中了其性能優(yōu)勢(shì),節(jié)點(diǎn)信息在共享內(nèi)存里以哈希表的形式存儲(chǔ),因此查詢(xún)時(shí)間是常數(shù)級(jí),實(shí)際測(cè)試一次讀取耗時(shí)在16us左右,完全可以滿(mǎn)足用戶(hù)對(duì)低延遲的要求。
agent與客戶(hù)端交互的另一個(gè)渠道是消息隊(duì)列??蛻?hù)端接收到應(yīng)用層訪問(wèn)服務(wù)的請(qǐng)求之后,先去共享內(nèi)存里檢索,若找到則直接返回,若未找到,則將該服務(wù)的名稱(chēng)寫(xiě)入消息隊(duì)列。而agent時(shí)刻監(jiān)視消息隊(duì)列中是否有數(shù)據(jù),一旦有數(shù)據(jù)被寫(xiě)入,agent即讀出數(shù)據(jù)(服務(wù)名),再根據(jù)服務(wù)名去服務(wù)注冊(cè)組件把服務(wù)提供者信息讀取回來(lái),并寫(xiě)入共享內(nèi)存??蛻?hù)端會(huì)等待直到共享內(nèi)存里出現(xiàn)所要讀取的服務(wù)提供者信息,然后讀出服務(wù)提供者信息并返回。
步驟S208,根據(jù)讀取的服務(wù)的服務(wù)提供者信息計(jì)算MD5值,將計(jì)算得到的MD5值與共享內(nèi)存中存儲(chǔ)的MD5值進(jìn)行比對(duì)是否一致,若是,則執(zhí)行步驟S209;否則,執(zhí)行步驟S207。
由于涉及到多個(gè)進(jìn)程(agent和客戶(hù)端進(jìn)程)對(duì)共享內(nèi)存的同時(shí)讀寫(xiě),所以需要避免沖突。共享內(nèi)存里同時(shí)存儲(chǔ)服務(wù)提供者信息與其MD5值,客戶(hù)端會(huì)把二者一次全讀出,然后根據(jù)讀取的服務(wù)提供者信息計(jì)算MD5值,校驗(yàn)MD5值是否正確,若不正確則會(huì)重新讀取,這就避免了agent尚未寫(xiě)入完整的服務(wù)提供者信息被客戶(hù)端讀走,也消除了鎖爭(zhēng)用,進(jìn)一步提升性能。
步驟S209,客戶(hù)端將該服務(wù)的服務(wù)提供者信息返回給應(yīng)用層。
另外,針對(duì)基于統(tǒng)一模型的服務(wù)發(fā)現(xiàn)技術(shù)需要兼容服務(wù)端的服務(wù)發(fā)現(xiàn)機(jī)制和客戶(hù)端的服務(wù)發(fā)現(xiàn)機(jī)制的問(wèn)題,該問(wèn)題主要集中在一套服務(wù)發(fā)現(xiàn)協(xié)議如何保證服務(wù)端的服務(wù)發(fā)現(xiàn)和客戶(hù)端的服務(wù)發(fā)現(xiàn)擁有相同的特性。常見(jiàn)的服務(wù)發(fā)現(xiàn)組件有Nginx,Haproxy,LVS等,其中Nginx工作在網(wǎng)絡(luò)協(xié)議的第七層(應(yīng)用層),Haproxy既可以工作在4層又可以工作在七層,LVS只能工作在4層。從高性能、可靠性、易用性、可擴(kuò)展性上,經(jīng)對(duì)比發(fā)現(xiàn)Nginx在實(shí)現(xiàn)負(fù)載均衡的策略上較其他幾個(gè)有更好的應(yīng)用場(chǎng)景。
圖7示出了根據(jù)本發(fā)明一個(gè)實(shí)施例的服務(wù)發(fā)現(xiàn)協(xié)議的分層模型示意圖,如圖7所示,本發(fā)明基于Nginx開(kāi)發(fā)了一個(gè)LB擴(kuò)展模塊,使得nginx層可以通過(guò)該LB擴(kuò)展模塊來(lái)動(dòng)態(tài)獲取上游(upstream)的配置,從而解決了服務(wù)端的服務(wù)發(fā)現(xiàn)問(wèn)題。本發(fā)明使用nginx做反向代理來(lái)提供服務(wù),nginx代理的服務(wù)需要能夠自動(dòng)注冊(cè)到nginx中,避免了因修改nginx的配置文件而重啟nginx。
客戶(hù)端的解決方案相對(duì)服務(wù)端來(lái)說(shuō)沒(méi)有依賴(lài)某個(gè)特定LB的場(chǎng)景,其實(shí)現(xiàn)也就比較簡(jiǎn)單,因?yàn)閹缀跛械恼Z(yǔ)言都支持linux環(huán)境下跨進(jìn)程通信(IPC)機(jī)制,因此只要幫助各個(gè)語(yǔ)言實(shí)現(xiàn)一個(gè)從共享內(nèi)存中獲取服務(wù)信息的API的客戶(hù)端即可,又由于本發(fā)明基于C++開(kāi)發(fā)和服務(wù)注冊(cè)組件通信時(shí)生成了動(dòng)態(tài)鏈接庫(kù),因此只要該編程語(yǔ)言支持動(dòng)態(tài)語(yǔ)言的接口即能快速實(shí)現(xiàn)其客戶(hù)端讀取服務(wù)的列表。
根據(jù)本發(fā)明上述實(shí)施例提供的基于共享內(nèi)存的服務(wù)發(fā)現(xiàn)方法,在客戶(hù)端接收到應(yīng)用層訪問(wèn)服務(wù)的請(qǐng)求之后,首先在共享內(nèi)存中查詢(xún)服務(wù)的服務(wù)提供者信息,若查詢(xún)到,則直接在共享內(nèi)存中讀取服務(wù)提供者信息;若未查詢(xún)到,則通過(guò)網(wǎng)絡(luò)去服務(wù)注冊(cè)組件中獲取服務(wù)提供者信息。利用本方法,達(dá)到了應(yīng)用層在獲取服務(wù)列表配置信息時(shí)和獲取本地內(nèi)存讀寫(xiě)一樣的性能,減少了網(wǎng)絡(luò)延遲,提升了讀取速度,這種與后端分布式集群通信產(chǎn)生共享內(nèi)存并提供client供應(yīng)用使用的方式,避免了客戶(hù)端和分布式集群之間用長(zhǎng)連接方式進(jìn)行對(duì)接而導(dǎo)致的資源占用過(guò)多、服務(wù)注冊(cè)組件處理效率低下的問(wèn)題。另外,本方法通過(guò)生成動(dòng)態(tài)鏈接庫(kù)向利用不同編程語(yǔ)言實(shí)現(xiàn)的客戶(hù)端提供統(tǒng)一的共享內(nèi)存查詢(xún)接口,解決了跨語(yǔ)言的通用性服務(wù)發(fā)現(xiàn)實(shí)現(xiàn)困難的問(wèn)題。本發(fā)明基于Nginx開(kāi)發(fā)了一個(gè)擴(kuò)展模塊,使得nginx層可以通過(guò)該擴(kuò)展模塊來(lái)動(dòng)態(tài)獲取upstream的配置,從而解決了服務(wù)端的服務(wù)發(fā)現(xiàn)問(wèn)題,又由于本發(fā)明基于C++開(kāi)發(fā)和服務(wù)注冊(cè)組件通信時(shí)生成了動(dòng)態(tài)鏈接庫(kù),因此只要該編程語(yǔ)言支持動(dòng)態(tài)語(yǔ)言的接口即能快速實(shí)現(xiàn)其客戶(hù)端讀取服務(wù)的列表,因而最終實(shí)現(xiàn)了兼容服務(wù)端的服務(wù)發(fā)現(xiàn)機(jī)制和客戶(hù)端的服務(wù)發(fā)現(xiàn)機(jī)制。
本發(fā)明實(shí)施例還提供了一種服務(wù)注冊(cè)集群中服務(wù)健康檢查的方法,其中服務(wù)健康檢查的作用主要是針對(duì)不健康的服務(wù)節(jié)點(diǎn)(服務(wù)提供者和/或服務(wù)消費(fèi)者)進(jìn)行動(dòng)態(tài)的摘除,以提升服務(wù)注冊(cè)集群的穩(wěn)定性和可靠性。該方法中,分布式健康檢查策略設(shè)計(jì)為主從(master-slave)架構(gòu)。
圖8示出了根據(jù)本發(fā)明一個(gè)實(shí)施例的服務(wù)注冊(cè)集群中服務(wù)健康檢查的架構(gòu)示意圖。如圖8所示,以服務(wù)注冊(cè)集群利用zookeeper技術(shù)實(shí)現(xiàn)為例,master選舉靠zookeeper來(lái)維系,主要涉及如下內(nèi)容:
1.所有健康檢查服務(wù)啟動(dòng)后都將自己做為臨時(shí)節(jié)點(diǎn)注冊(cè)到zookeeper中;
2.所有的節(jié)點(diǎn)都監(jiān)聽(tīng)zookeeper路徑/arch_group/healthcheck/election,當(dāng)有變更時(shí)表示需要重新選舉master;
3.master節(jié)點(diǎn)負(fù)責(zé)任務(wù)分配和健康檢查,具體分配方式是添加一個(gè)任務(wù)給自己,并將其他無(wú)關(guān)任務(wù)移除;
4.master的任務(wù)負(fù)責(zé)按照周期輪詢(xún)所有的providers,然后將這些providers的健康檢查分配給其他的健康檢查節(jié)點(diǎn);
5.分配給其他節(jié)點(diǎn)的策略是發(fā)送一個(gè)HTTP請(qǐng)求讓slave節(jié)點(diǎn)添加一個(gè)健康檢查的任務(wù)。
slave節(jié)點(diǎn)需要執(zhí)行健康檢查任務(wù),主要涉及如下內(nèi)容:
1.slave節(jié)點(diǎn)除了監(jiān)聽(tīng)master選舉外默認(rèn)啟動(dòng)后什么都不做;
2.slave節(jié)點(diǎn)當(dāng)收到master節(jié)點(diǎn)發(fā)過(guò)來(lái)的添加任務(wù)的請(qǐng)求后開(kāi)始執(zhí)行健康檢查任務(wù)。
有節(jié)點(diǎn)掛掉后策略:
1.由于所有的節(jié)點(diǎn)都監(jiān)聽(tīng)了zookeeper的master選舉節(jié)點(diǎn),當(dāng)有節(jié)點(diǎn)變更時(shí)集群所有節(jié)點(diǎn)都有感知;
2.當(dāng)感知到master節(jié)點(diǎn)掛掉后,重新選舉master,然后執(zhí)行master的任務(wù);
3.當(dāng)感知到slave節(jié)點(diǎn)掛掉后,master節(jié)點(diǎn)不再分配任務(wù)給該掛掉的slave節(jié)點(diǎn)。
實(shí)施例三
圖9示出了根據(jù)本發(fā)明一個(gè)實(shí)施例的基于共享內(nèi)存的服務(wù)發(fā)現(xiàn)裝置的功能框圖。如圖9所示,該裝置包括:監(jiān)聽(tīng)模塊301,獲取模塊302,寫(xiě)入模塊303。
監(jiān)聽(tīng)模塊301,適于監(jiān)聽(tīng)并獲取消息隊(duì)列中記錄的服務(wù)名稱(chēng);其中,服務(wù)名稱(chēng)是客戶(hù)端接收到應(yīng)用層訪問(wèn)服務(wù)的請(qǐng)求之后,在共享內(nèi)存中未查詢(xún)到所述服務(wù)的服務(wù)提供者信息而寫(xiě)入到消息隊(duì)列中。
獲取模塊302,適于根據(jù)所述服務(wù)名稱(chēng),從服務(wù)注冊(cè)組件處獲取所述服務(wù)的服務(wù)提供者信息;
寫(xiě)入模塊303,適于將所述服務(wù)的服務(wù)提供者信息寫(xiě)入共享內(nèi)存中,以供客戶(hù)端從共享內(nèi)存中讀取所述服務(wù)的服務(wù)提供者信息并返回給應(yīng)用層。
監(jiān)聽(tīng)模塊301進(jìn)一步適于:監(jiān)聽(tīng)消息隊(duì)列中記錄的服務(wù)名稱(chēng);將消息隊(duì)列中記錄的服務(wù)名稱(chēng)讀到內(nèi)存中,并及時(shí)清除消息隊(duì)列中記錄的服務(wù)名稱(chēng);從內(nèi)存中獲取所述服務(wù)名稱(chēng)。
監(jiān)聽(tīng)模塊301負(fù)責(zé)從消息隊(duì)列里取服務(wù)名稱(chēng)。因?yàn)橄到y(tǒng)的消息隊(duì)列大小有限制,若隊(duì)列內(nèi)的數(shù)據(jù)未及時(shí)取走,則可能因?yàn)榭蛻?hù)端在短時(shí)間內(nèi)大量寫(xiě)入服務(wù)名稱(chēng)而將隊(duì)列填滿(mǎn),之后的服務(wù)名稱(chēng)將無(wú)法再寫(xiě)入,造成錯(cuò)誤。而本裝置獲得服務(wù)名稱(chēng)后,需要通過(guò)網(wǎng)絡(luò)去服務(wù)注冊(cè)組件上取得服務(wù)提供者信息,相對(duì)較慢(10ms左右),因此很可能發(fā)生隊(duì)列的積壓填滿(mǎn)。為了避免出現(xiàn)這種問(wèn)題,監(jiān)聽(tīng)模塊301監(jiān)聽(tīng)消息隊(duì)列中記錄的服務(wù)名稱(chēng),將消息隊(duì)列中記錄的服務(wù)名稱(chēng)讀到內(nèi)存中,并及時(shí)清除消息隊(duì)列中記錄的服務(wù)名稱(chēng),防止填滿(mǎn)隊(duì)列。獲取模塊302從內(nèi)存里獲得需要讀取的服務(wù)名稱(chēng),再去服務(wù)注冊(cè)組件上取值。
進(jìn)一步的,該裝置還可包括:掃描模塊304,比對(duì)模塊305,更新模塊306。
掃描模塊304,適于每隔預(yù)定時(shí)間掃描共享內(nèi)存中的服務(wù)提供者信息;
比對(duì)模塊305,適于將共享內(nèi)存中的服務(wù)提供者信息與服務(wù)注冊(cè)組件中的服務(wù)提供者信息進(jìn)行比對(duì);
更新模塊306,適于若比對(duì)不一致,則根據(jù)服務(wù)注冊(cè)組件中的服務(wù)提供者信息更新共享內(nèi)存中的服務(wù)提供者信息。
因?yàn)榉?wù)注冊(cè)組件的watcher機(jī)制不能設(shè)置為持久監(jiān)視,而是一次性的,也就是說(shuō),一個(gè)事件被觸發(fā)一次后,該watcher就被自動(dòng)銷(xiāo)毀,如果要繼續(xù)監(jiān)視下次事件,只能重新注冊(cè)watcher。所以本發(fā)明采取的策略是事件發(fā)生后,第一時(shí)間先重新注冊(cè)watcher,再執(zhí)行具體的處理邏輯,盡量減少上個(gè)watcher銷(xiāo)毀與下個(gè)watcher注冊(cè)的時(shí)間間隔。盡管如此,這二者仍然不是事務(wù)性操作,因此仍有極小概率會(huì)丟失事件。為了防止這種情況發(fā)生,掃描模塊304會(huì)每隔30-60分鐘掃描共享內(nèi)存里的所有節(jié)點(diǎn),比對(duì)模塊305將其與服務(wù)注冊(cè)組件上的最新值比較,若有差異則由更新模塊306更新到最新值,并為可能遺漏監(jiān)視的節(jié)點(diǎn)重新注冊(cè)watcher。
進(jìn)一步的,該裝置還可包括:生成模塊307,適于生成動(dòng)態(tài)鏈接庫(kù)向利用不同編程語(yǔ)言實(shí)現(xiàn)的客戶(hù)端提供統(tǒng)一的共享內(nèi)存查詢(xún)接口。
為了解決跨語(yǔ)言的通用性服務(wù)發(fā)現(xiàn)實(shí)現(xiàn)困難的難題,本裝置提供的解決方案是不再在各個(gè)語(yǔ)言?xún)?nèi)部進(jìn)行服務(wù)注冊(cè)組件的實(shí)現(xiàn),而是使用統(tǒng)一的編程語(yǔ)言,如C++編程語(yǔ)言對(duì)服務(wù)注冊(cè)組件API進(jìn)行調(diào)用和服務(wù)發(fā)現(xiàn)邏輯的封裝,用C++生成動(dòng)態(tài)鏈接庫(kù)的方式來(lái)對(duì)外提供統(tǒng)一的服務(wù)發(fā)現(xiàn)的API。如圖6所示,服務(wù)發(fā)現(xiàn)策略實(shí)現(xiàn)的各個(gè)語(yǔ)言接入主要支持:Java,Python,php,C/C++,lua等,還可支持shell,go等語(yǔ)言。各個(gè)語(yǔ)言接入共享內(nèi)存主要通過(guò)動(dòng)態(tài)鏈接庫(kù)來(lái)和共享內(nèi)存進(jìn)行通信,各個(gè)語(yǔ)言通過(guò)封裝動(dòng)態(tài)鏈接庫(kù)和服務(wù)發(fā)現(xiàn)邏輯提供的服務(wù)發(fā)現(xiàn)的接口只有一個(gè)即:get_service,接口參數(shù)為namespace和algorithm,該函數(shù)根據(jù)algorithm參數(shù)對(duì)namespace下的providers進(jìn)行篩選從而返回一個(gè)provider出來(lái)給應(yīng)用層使用。
實(shí)施例四
圖10示出了根據(jù)本發(fā)明一個(gè)實(shí)施例的基于共享內(nèi)存的服務(wù)發(fā)現(xiàn)系統(tǒng)的功能框圖。如圖10所示,該系統(tǒng)包括:上述實(shí)施例描述的基于共享內(nèi)存的服務(wù)發(fā)現(xiàn)裝置401、共享內(nèi)存402、客戶(hù)端403以及服務(wù)注冊(cè)組件404。
客戶(hù)端403適于:在接收到應(yīng)用層訪問(wèn)服務(wù)的請(qǐng)求之后,在共享內(nèi)存中查詢(xún)到所述服務(wù)的服務(wù)提供者信息,若未查詢(xún)到,則將服務(wù)名稱(chēng)寫(xiě)入到消息隊(duì)列中;若查詢(xún)到,則從共享內(nèi)存中讀取所述服務(wù)的服務(wù)提供者信息并返回給應(yīng)用層。
客戶(hù)端404還適于:根據(jù)讀取的所述服務(wù)的服務(wù)提供者信息計(jì)算MD5值,將計(jì)算得到的MD5值與共享內(nèi)存中存儲(chǔ)的MD5值進(jìn)行比對(duì),若比對(duì)不一致,則重新從共享內(nèi)存中讀取所述服務(wù)的服務(wù)提供者信息。
從圖4所示的系統(tǒng)架構(gòu)圖上可以看出,裝置401與客戶(hù)端403并沒(méi)有直接的通訊,二者的交互的一個(gè)渠道是共享內(nèi)存402。共享內(nèi)存402的作用在于,客戶(hù)端403可能會(huì)多次讀取相同的配置項(xiàng)(其值可能并不會(huì)每次都改變),如果沒(méi)有在本機(jī)存儲(chǔ)這些配置項(xiàng),那么就必然需要每次通過(guò)網(wǎng)絡(luò)去服務(wù)注冊(cè)組件404服務(wù)端讀取(相同的值),一是存在網(wǎng)絡(luò)延遲,二是服務(wù)注冊(cè)組件404本身性能并不高,不適合大量的頻繁讀操作。之所以選用共享內(nèi)存402這種存儲(chǔ)方式,是看中了其性能優(yōu)勢(shì),節(jié)點(diǎn)信息在共享內(nèi)存402里以哈希表的形式存儲(chǔ),因此查詢(xún)時(shí)間是常數(shù)級(jí),實(shí)際測(cè)試一次讀取耗時(shí)在16us左右,完全可以滿(mǎn)足用戶(hù)對(duì)低延遲的要求。
裝置401與客戶(hù)端403交互的另一個(gè)渠道是消息隊(duì)列??蛻?hù)端403接收到應(yīng)用層訪問(wèn)服務(wù)的請(qǐng)求之后,先去共享內(nèi)存402里檢索,若找到則直接返回,若未找到,則將該服務(wù)的名稱(chēng)寫(xiě)入消息隊(duì)列。而裝置401時(shí)刻監(jiān)視消息隊(duì)列中是否有數(shù)據(jù),一旦有數(shù)據(jù)被寫(xiě)入,裝置401即讀出數(shù)據(jù)(服務(wù)名),再根據(jù)服務(wù)名去服務(wù)注冊(cè)組件404把服務(wù)提供者信息讀取回來(lái),并寫(xiě)入共享內(nèi)存402??蛻?hù)端403會(huì)等待直到共享內(nèi)存402里出現(xiàn)所要讀取的服務(wù)提供者信息,然后讀出服務(wù)提供者信息并返回。
由于涉及到多個(gè)進(jìn)程(裝置和客戶(hù)端進(jìn)程)對(duì)共享內(nèi)存402的同時(shí)讀寫(xiě),所以需要避免沖突。共享內(nèi)存402里同時(shí)存儲(chǔ)服務(wù)提供者信息與其MD5值,客戶(hù)端403會(huì)把二者一次全讀出,然后根據(jù)讀取的服務(wù)提供者信息計(jì)算MD5值,校驗(yàn)MD5值是否正確,若不正確則會(huì)重新讀取,這就避免了裝置401尚未寫(xiě)入完整的服務(wù)提供者信息被客戶(hù)端403讀走,也消除了鎖爭(zhēng)用,進(jìn)一步提升性能。
進(jìn)一步的,如圖7所示,本系統(tǒng)基于Nginx開(kāi)發(fā)了一個(gè)LB擴(kuò)展模塊,與客戶(hù)端和共享內(nèi)存通信連接,使客戶(hù)端通過(guò)LB擴(kuò)展模塊與共享內(nèi)存進(jìn)行通信。具體地,使得nginx層可以通過(guò)該LB擴(kuò)展模塊來(lái)動(dòng)態(tài)獲取上游(upstream)的配置,從而解決了服務(wù)端的服務(wù)發(fā)現(xiàn)問(wèn)題。
客戶(hù)端的解決方案相對(duì)服務(wù)端來(lái)說(shuō)沒(méi)有依賴(lài)某個(gè)特定LB的場(chǎng)景,其實(shí)現(xiàn)也就比較簡(jiǎn)單,因?yàn)閹缀跛械恼Z(yǔ)言都支持linux環(huán)境下跨進(jìn)程通信(IPC)機(jī)制,因此只要幫助各個(gè)語(yǔ)言實(shí)現(xiàn)一個(gè)從共享內(nèi)存中獲取服務(wù)信息的API的客戶(hù)端即可,又由于本發(fā)明基于C++開(kāi)發(fā)和服務(wù)注冊(cè)組件通信時(shí)生成了動(dòng)態(tài)鏈接庫(kù),因此只要該編程語(yǔ)言支持動(dòng)態(tài)語(yǔ)言的接口即能快速實(shí)現(xiàn)其客戶(hù)端讀取服務(wù)的列表。
根據(jù)本發(fā)明上述實(shí)施例提供的基于共享內(nèi)存的服務(wù)發(fā)現(xiàn)裝置及系統(tǒng),在客戶(hù)端接收到應(yīng)用層訪問(wèn)服務(wù)的請(qǐng)求之后,首先在共享內(nèi)存中查詢(xún)服務(wù)的服務(wù)提供者信息,若查詢(xún)到,則直接在共享內(nèi)存中讀取服務(wù)提供者信息;若未查詢(xún)到,則通過(guò)網(wǎng)絡(luò)去服務(wù)注冊(cè)組件中獲取服務(wù)提供者信息。利用本裝置及系統(tǒng),達(dá)到了應(yīng)用層在獲取服務(wù)列表配置信息時(shí)和獲取本地內(nèi)存讀寫(xiě)一樣的性能,減少了網(wǎng)絡(luò)延遲,提升了讀取速度,這種與后端分布式集群通信產(chǎn)生共享內(nèi)存并提供client供應(yīng)用使用的方式,避免了客戶(hù)端和分布式集群之間用長(zhǎng)連接方式進(jìn)行對(duì)接而導(dǎo)致的資源占用過(guò)多、服務(wù)注冊(cè)組件處理效率低下的問(wèn)題。另外,本裝置及系統(tǒng)通過(guò)生成動(dòng)態(tài)鏈接庫(kù)向利用不同編程語(yǔ)言實(shí)現(xiàn)的客戶(hù)端提供統(tǒng)一的共享內(nèi)存查詢(xún)接口,解決了跨語(yǔ)言的通用性服務(wù)發(fā)現(xiàn)實(shí)現(xiàn)困難的問(wèn)題。本系統(tǒng)基于Nginx開(kāi)發(fā)了一個(gè)擴(kuò)展模塊,使得nginx層可以通過(guò)該擴(kuò)展模塊來(lái)動(dòng)態(tài)獲取upstream的配置,從而解決了服務(wù)端的服務(wù)發(fā)現(xiàn)問(wèn)題,又由于本發(fā)明基于C++開(kāi)發(fā)和服務(wù)注冊(cè)組件通信時(shí)生成了動(dòng)態(tài)鏈接庫(kù),因此只要該編程語(yǔ)言支持動(dòng)態(tài)語(yǔ)言的接口即能快速實(shí)現(xiàn)其客戶(hù)端讀取服務(wù)的列表,因而最終實(shí)現(xiàn)了兼容服務(wù)端的服務(wù)發(fā)現(xiàn)機(jī)制和客戶(hù)端的服務(wù)發(fā)現(xiàn)機(jī)制。
實(shí)施例五
本申請(qǐng)實(shí)施例五提供了一種非易失性計(jì)算機(jī)存儲(chǔ)介質(zhì),所述計(jì)算機(jī)存儲(chǔ)介質(zhì)存儲(chǔ)有至少一可執(zhí)行指令,該計(jì)算機(jī)可執(zhí)行指令可執(zhí)行上述任意方法實(shí)施例中的基于共享內(nèi)存的服務(wù)發(fā)現(xiàn)方法。
實(shí)施例六
圖11示出了根據(jù)本發(fā)明實(shí)施例六的一種服務(wù)器的結(jié)構(gòu)示意圖,本發(fā)明具體實(shí)施例并不對(duì)服務(wù)器的具體實(shí)現(xiàn)做限定。
如圖11所示,該服務(wù)器可以包括:處理器(processor)602、通信接口(Communications Interface)604、存儲(chǔ)器(memory)606、以及通信總線608。
其中:
處理器602、通信接口604、以及存儲(chǔ)器606通過(guò)通信總線608完成相互間的通信。
通信接口604,用于與其它設(shè)備比如客戶(hù)端或其它服務(wù)器等的網(wǎng)元通信。
處理器602,用于執(zhí)行程序610,具體可以執(zhí)行上述基于共享內(nèi)存的服務(wù)發(fā)現(xiàn)方法實(shí)施例中的相關(guān)步驟。
具體地,程序610可以包括程序代碼,該程序代碼包括計(jì)算機(jī)操作指令。
處理器602可能是中央處理器CPU,或者是特定集成電路ASIC(Application Specific Integrated Circuit),或者是被配置成實(shí)施本發(fā)明實(shí)施例的一個(gè)或多個(gè)集成電路。服務(wù)器包括的一個(gè)或多個(gè)處理器,可以是同一類(lèi)型的處理器,如一個(gè)或多個(gè)CPU;也可以是不同類(lèi)型的處理器,如一個(gè)或多個(gè)CPU以及一個(gè)或多個(gè)ASIC。
存儲(chǔ)器606,用于存放程序610。存儲(chǔ)器606可能包含高速RAM存儲(chǔ)器,也可能還包括非易失性存儲(chǔ)器(non-volatile memory),例如至少一個(gè)磁盤(pán)存儲(chǔ)器。
程序610具體可以用于使得處理器602執(zhí)行以下操作:監(jiān)聽(tīng)并獲取消息隊(duì)列中記錄的服務(wù)名稱(chēng);其中,所述服務(wù)名稱(chēng)是客戶(hù)端接收到應(yīng)用層訪問(wèn)服務(wù)的請(qǐng)求之后,在共享內(nèi)存中未查詢(xún)到所述服務(wù)的服務(wù)提供者信息而寫(xiě)入到消息隊(duì)列中;根據(jù)所述服務(wù)名稱(chēng),從服務(wù)注冊(cè)組件處獲取所述服務(wù)的服務(wù)提供者信息;將所述服務(wù)的服務(wù)提供者信息寫(xiě)入共享內(nèi)存中,以供客戶(hù)端從共享內(nèi)存中讀取所述服務(wù)的服務(wù)提供者信息并返回給應(yīng)用層。
在一種可選的實(shí)施方式中,客戶(hù)端接收到應(yīng)用層訪問(wèn)服務(wù)的請(qǐng)求之后,在共享內(nèi)存中查詢(xún)到所述服務(wù)的服務(wù)提供者信息,從共享內(nèi)存中讀取所述服務(wù)的服務(wù)提供者信息并返回給應(yīng)用層。
在一種可選的實(shí)施方式中,程序610用于使得處理器602監(jiān)聽(tīng)消息隊(duì)列中記錄的服務(wù)名稱(chēng);將消息隊(duì)列中記錄的服務(wù)名稱(chēng)讀到內(nèi)存中,并及時(shí)清除消息隊(duì)列中記錄的服務(wù)名稱(chēng);從內(nèi)存中獲取所述服務(wù)名稱(chēng)。
在一種可選的實(shí)施方式中,程序610用于使得處理器602每隔預(yù)定時(shí)間掃描共享內(nèi)存中的服務(wù)提供者信息;將共享內(nèi)存中的服務(wù)提供者信息與服務(wù)注冊(cè)組件中的服務(wù)提供者信息進(jìn)行比對(duì);若比對(duì)不一致,則根據(jù)服務(wù)注冊(cè)組件中的服務(wù)提供者信息更新共享內(nèi)存中的服務(wù)提供者信息。
在一種可選的實(shí)施方式中,所述共享內(nèi)存中存儲(chǔ)有服務(wù)提供者信息及其MD5值;程序610用于使得處理器602根據(jù)讀取的所述服務(wù)的服務(wù)提供者信息計(jì)算MD5值,將計(jì)算得到的MD5值與共享內(nèi)存中存儲(chǔ)的MD5值進(jìn)行比對(duì),若比對(duì)不一致,則重新從共享內(nèi)存中讀取所述服務(wù)的服務(wù)提供者信息。
在一種可選的實(shí)施方式中,程序610用于使得處理器602生成動(dòng)態(tài)鏈接庫(kù)向利用不同編程語(yǔ)言實(shí)現(xiàn)的客戶(hù)端提供統(tǒng)一的共享內(nèi)存查詢(xún)接口。
綜上,本發(fā)明實(shí)施例提供的上述解決方案達(dá)到了如下技術(shù)效果:
1.以客戶(hù)端最小侵入性的方式實(shí)現(xiàn)客戶(hù)端層服務(wù)發(fā)現(xiàn);
2.獲取服務(wù)列表實(shí)現(xiàn)了超高的性能和原生讀取內(nèi)存幾乎無(wú)差異;
3.客戶(hù)端層服務(wù)發(fā)現(xiàn)和服務(wù)端層LB都實(shí)現(xiàn)了使用統(tǒng)一接口的服務(wù)發(fā)現(xiàn)方式;
4.服務(wù)端層LB的服務(wù)發(fā)現(xiàn)使得后端服務(wù)動(dòng)態(tài)擴(kuò)容/縮容更獨(dú)立,無(wú)需通知依賴(lài)方服務(wù)變更,配置維護(hù)成本更低;
5.客戶(hù)端層服務(wù)發(fā)現(xiàn)使得客戶(hù)端有了自主負(fù)載均衡策略,客戶(hù)端對(duì)后端服務(wù)的選擇有了更大的自主空間,當(dāng)后端服務(wù)出現(xiàn)阻塞卡頓時(shí),客戶(hù)端可以根據(jù)自己的重試策略來(lái)解決;
6.獨(dú)立的分布式服務(wù)健康檢查方案來(lái)實(shí)現(xiàn)服務(wù)節(jié)點(diǎn)的摘除策略;
7.與后端分布式集群通信產(chǎn)生共享內(nèi)存并提供client供應(yīng)用使用的方式,避免了客戶(hù)端和分布式集群之間用長(zhǎng)連接方式進(jìn)行對(duì)接而導(dǎo)致的資源占用過(guò)多、服務(wù)注冊(cè)組件處理效率低下的問(wèn)題;
8.統(tǒng)一通過(guò)REST(Representational State Transfer,表述性狀態(tài)傳遞)風(fēng)格的API提供對(duì)后端分布式集群進(jìn)行修改和刪除操作,使得節(jié)點(diǎn)變更前后能夠得到統(tǒng)一的控制。
在此提供的算法和顯示不與任何特定計(jì)算機(jī)、虛擬系統(tǒng)或者其它設(shè)備固有相關(guān)。各種通用系統(tǒng)也可以與基于在此的示教一起使用。根據(jù)上面的描述,構(gòu)造這類(lèi)系統(tǒng)所要求的結(jié)構(gòu)是顯而易見(jiàn)的。此外,本發(fā)明也不針對(duì)任何特定編程語(yǔ)言。應(yīng)當(dāng)明白,可以利用各種編程語(yǔ)言實(shí)現(xiàn)在此描述的本發(fā)明的內(nèi)容,并且上面對(duì)特定語(yǔ)言所做的描述是為了披露本發(fā)明的最佳實(shí)施方式。
在此處所提供的說(shuō)明書(shū)中,說(shuō)明了大量具體細(xì)節(jié)。然而,能夠理解,本發(fā)明的實(shí)施例可以在沒(méi)有這些具體細(xì)節(jié)的情況下實(shí)踐。在一些實(shí)例中,并未詳細(xì)示出公知的方法、結(jié)構(gòu)和技術(shù),以便不模糊對(duì)本說(shuō)明書(shū)的理解。
類(lèi)似地,應(yīng)當(dāng)理解,為了精簡(jiǎn)本公開(kāi)并幫助理解各個(gè)發(fā)明方面中的一個(gè)或多個(gè),在上面對(duì)本發(fā)明的示例性實(shí)施例的描述中,本發(fā)明的各個(gè)特征有時(shí)被一起分組到單個(gè)實(shí)施例、圖、或者對(duì)其的描述中。然而,并不應(yīng)將該公開(kāi)的方法解釋成反映如下意圖:即所要求保護(hù)的本發(fā)明要求比在每個(gè)權(quán)利要求中所明確記載的特征更多的特征。更確切地說(shuō),如下面的權(quán)利要求書(shū)所反映的那樣,發(fā)明方面在于少于前面公開(kāi)的單個(gè)實(shí)施例的所有特征。因此,遵循具體實(shí)施方式的權(quán)利要求書(shū)由此明確地并入該具體實(shí)施方式,其中每個(gè)權(quán)利要求本身都作為本發(fā)明的單獨(dú)實(shí)施例。
本領(lǐng)域那些技術(shù)人員可以理解,可以對(duì)實(shí)施例中的設(shè)備中的模塊進(jìn)行自適應(yīng)性地改變并且把它們?cè)O(shè)置在與該實(shí)施例不同的一個(gè)或多個(gè)設(shè)備中。可以把實(shí)施例中的模塊或單元或組件組合成一個(gè)模塊或單元或組件,以及此外可以把它們分成多個(gè)子模塊或子單元或子組件。除了這樣的特征和/或過(guò)程或者單元中的至少一些是相互排斥之外,可以采用任何組合對(duì)本說(shuō)明書(shū)(包括伴隨的權(quán)利要求、摘要和附圖)中公開(kāi)的所有特征以及如此公開(kāi)的任何方法或者設(shè)備的所有過(guò)程或單元進(jìn)行組合。除非另外明確陳述,本說(shuō)明書(shū)(包括伴隨的權(quán)利要求、摘要和附圖)中公開(kāi)的每個(gè)特征可以由提供相同、等同或相似目的的替代特征來(lái)代替。
此外,本領(lǐng)域的技術(shù)人員能夠理解,盡管在此所述的一些實(shí)施例包括其它實(shí)施例中所包括的某些特征而不是其它特征,但是不同實(shí)施例的特征的組合意味著處于本發(fā)明的范圍之內(nèi)并且形成不同的實(shí)施例。例如,在下面的權(quán)利要求書(shū)中,所要求保護(hù)的實(shí)施例的任意之一都可以以任意的組合方式來(lái)使用。
應(yīng)該注意的是上述實(shí)施例對(duì)本發(fā)明進(jìn)行說(shuō)明而不是對(duì)本發(fā)明進(jìn)行限制,并且本領(lǐng)域技術(shù)人員在不脫離所附權(quán)利要求的范圍的情況下可設(shè)計(jì)出替換實(shí)施例。在權(quán)利要求中,不應(yīng)將位于括號(hào)之間的任何參考符號(hào)構(gòu)造成對(duì)權(quán)利要求的限制。單詞“包含”不排除存在未列在權(quán)利要求中的元件或步驟。位于元件之前的單詞“一”或“一個(gè)”不排除存在多個(gè)這樣的元件。本發(fā)明可以借助于包括有若干不同元件的硬件以及借助于適當(dāng)編程的計(jì)算機(jī)來(lái)實(shí)現(xiàn)。在列舉了若干裝置的單元權(quán)利要求中,這些裝置中的若干個(gè)可以是通過(guò)同一個(gè)硬件項(xiàng)來(lái)具體體現(xiàn)。單詞第一、第二、以及第三等的使用不表示任何順序。可將這些單詞解釋為名稱(chēng)。
本發(fā)明公開(kāi)了:A1、一種基于共享內(nèi)存的服務(wù)發(fā)現(xiàn)方法,包括:
監(jiān)聽(tīng)并獲取消息隊(duì)列中記錄的服務(wù)名稱(chēng);其中,所述服務(wù)名稱(chēng)是客戶(hù)端接收到應(yīng)用層訪問(wèn)服務(wù)的請(qǐng)求之后,在共享內(nèi)存中未查詢(xún)到所述服務(wù)的服務(wù)提供者信息而寫(xiě)入到消息隊(duì)列中;
根據(jù)所述服務(wù)名稱(chēng),從服務(wù)注冊(cè)組件處獲取所述服務(wù)的服務(wù)提供者信息;
將所述服務(wù)的服務(wù)提供者信息寫(xiě)入共享內(nèi)存中,以供客戶(hù)端從共享內(nèi)存中讀取所述服務(wù)的服務(wù)提供者信息并返回給應(yīng)用層。
A2、根據(jù)A1所述的方法,其中,所述方法還包括:客戶(hù)端接收到應(yīng)用層訪問(wèn)服務(wù)的請(qǐng)求之后,在共享內(nèi)存中查詢(xún)到所述服務(wù)的服務(wù)提供者信息,從共享內(nèi)存中讀取所述服務(wù)的服務(wù)提供者信息并返回給應(yīng)用層。
A3、根據(jù)A1所述的方法,其中,所述監(jiān)聽(tīng)并獲取消息隊(duì)列中記錄的服務(wù)名稱(chēng)進(jìn)一步包括:
監(jiān)聽(tīng)消息隊(duì)列中記錄的服務(wù)名稱(chēng);
將消息隊(duì)列中記錄的服務(wù)名稱(chēng)讀到內(nèi)存中,并及時(shí)清除消息隊(duì)列中記錄的服務(wù)名稱(chēng);
從內(nèi)存中獲取所述服務(wù)名稱(chēng)。
A4、根據(jù)A1所述的方法,其中,所述方法還包括:
每隔預(yù)定時(shí)間掃描共享內(nèi)存中的服務(wù)提供者信息;
將共享內(nèi)存中的服務(wù)提供者信息與服務(wù)注冊(cè)組件中的服務(wù)提供者信息進(jìn)行比對(duì);
若比對(duì)不一致,則根據(jù)服務(wù)注冊(cè)組件中的服務(wù)提供者信息更新共享內(nèi)存中的服務(wù)提供者信息。
A5、根據(jù)A1或A2所述的方法,其中,所述共享內(nèi)存中存儲(chǔ)有服務(wù)提供者信息及其MD5值;
在客戶(hù)端從共享內(nèi)存中讀取所述服務(wù)的服務(wù)提供者信息之后,所述方法還包括:根據(jù)讀取的所述服務(wù)的服務(wù)提供者信息計(jì)算MD5值,將計(jì)算得到的MD5值與共享內(nèi)存中存儲(chǔ)的MD5值進(jìn)行比對(duì),若比對(duì)不一致,則重新從共享內(nèi)存中讀取所述服務(wù)的服務(wù)提供者信息。
A6、根據(jù)A1所述的方法,其中,所述方法還包括:生成動(dòng)態(tài)鏈接庫(kù)向利用不同編程語(yǔ)言實(shí)現(xiàn)的客戶(hù)端提供統(tǒng)一的共享內(nèi)存查詢(xún)接口。
本發(fā)明還公開(kāi)了:B7、一種基于共享內(nèi)存的服務(wù)發(fā)現(xiàn)裝置,包括:
監(jiān)聽(tīng)模塊,適于監(jiān)聽(tīng)并獲取消息隊(duì)列中記錄的服務(wù)名稱(chēng);其中,所述服務(wù)名稱(chēng)是客戶(hù)端接收到應(yīng)用層訪問(wèn)服務(wù)的請(qǐng)求之后,在共享內(nèi)存中未查詢(xún)到所述服務(wù)的服務(wù)提供者信息而寫(xiě)入到消息隊(duì)列中;
獲取模塊,適于根據(jù)所述服務(wù)名稱(chēng),從服務(wù)注冊(cè)組件處獲取所述服務(wù)的服務(wù)提供者信息;
寫(xiě)入模塊,適于將所述服務(wù)的服務(wù)提供者信息寫(xiě)入共享內(nèi)存中,以供客戶(hù)端從共享內(nèi)存中讀取所述服務(wù)的服務(wù)提供者信息并返回給應(yīng)用層。
B8、根據(jù)B7所述的裝置,其中,所述監(jiān)聽(tīng)模塊進(jìn)一步適于:
監(jiān)聽(tīng)消息隊(duì)列中記錄的服務(wù)名稱(chēng);
將消息隊(duì)列中記錄的服務(wù)名稱(chēng)讀到內(nèi)存中,并及時(shí)清除消息隊(duì)列中記錄的服務(wù)名稱(chēng);
從內(nèi)存中獲取所述服務(wù)名稱(chēng)。
B9、根據(jù)B7所述的裝置,其中,所述裝置還包括:
掃描模塊,適于每隔預(yù)定時(shí)間掃描共享內(nèi)存中的服務(wù)提供者信息;
比對(duì)模塊,適于將共享內(nèi)存中的服務(wù)提供者信息與服務(wù)注冊(cè)組件中的服務(wù)提供者信息進(jìn)行比對(duì);
更新模塊,適于若比對(duì)不一致,則根據(jù)服務(wù)注冊(cè)組件中的服務(wù)提供者信息更新共享內(nèi)存中的服務(wù)提供者信息。
B10、根據(jù)B7所述的裝置,其中,所述裝置還包括:生成模塊,適于生成動(dòng)態(tài)鏈接庫(kù)向利用不同編程語(yǔ)言實(shí)現(xiàn)的客戶(hù)端提供統(tǒng)一的共享內(nèi)存查詢(xún)接口。
本發(fā)明還公開(kāi)了:C11、一種基于共享內(nèi)存的服務(wù)發(fā)現(xiàn)系統(tǒng),包括:B7-B10任一項(xiàng)所述的基于共享內(nèi)存的服務(wù)發(fā)現(xiàn)裝置、共享內(nèi)存、客戶(hù)端以及服務(wù)注冊(cè)組件;
所述客戶(hù)端適于:在接收到應(yīng)用層訪問(wèn)服務(wù)的請(qǐng)求之后,在共享內(nèi)存中查詢(xún)到所述服務(wù)的服務(wù)提供者信息,若未查詢(xún)到,則將服務(wù)名稱(chēng)寫(xiě)入到消息隊(duì)列中;若查詢(xún)到,則從共享內(nèi)存中讀取所述服務(wù)的服務(wù)提供者信息并返回給應(yīng)用層。
C12、根據(jù)C11所述的系統(tǒng),其中,所述客戶(hù)端還適于:根據(jù)讀取的所述服務(wù)的服務(wù)提供者信息計(jì)算MD5值,將計(jì)算得到的MD5值與共享內(nèi)存中存儲(chǔ)的MD5值進(jìn)行比對(duì),若比對(duì)不一致,則重新從共享內(nèi)存中讀取所述服務(wù)的服務(wù)提供者信息。
C13、根據(jù)C11所述的系統(tǒng),其中,還包括:LB擴(kuò)展模塊,與客戶(hù)端和共享內(nèi)存通信連接,使客戶(hù)端通過(guò)LB擴(kuò)展模塊與共享內(nèi)存進(jìn)行通信。
本發(fā)明還公開(kāi)了:D14、一種服務(wù)器,包括:處理器、存儲(chǔ)器、通信接口和通信總線,所述處理器、所述存儲(chǔ)器和所述通信接口通過(guò)所述通信總線完成相互間的通信;
所述存儲(chǔ)器用于存放至少一可執(zhí)行指令,所述可執(zhí)行指令使所述處理器執(zhí)行如A1-A6中任一項(xiàng)所述的基于共享內(nèi)存的服務(wù)發(fā)現(xiàn)方法對(duì)應(yīng)的操作。
本發(fā)明還公開(kāi)了:E15、一種計(jì)算機(jī)存儲(chǔ)介質(zhì),所述存儲(chǔ)介質(zhì)中存儲(chǔ)有至少一可執(zhí)行指令,所述可執(zhí)行指令使所述處理器執(zhí)行如A1-A6中任一項(xiàng)所述的基于共享內(nèi)存的服務(wù)發(fā)現(xiàn)方法對(duì)應(yīng)的操作。