基于容器的微服務(wù)架構(gòu)剖析
隨著容器技術(shù)的成熟和大規(guī)模實(shí)踐,基于容器的微服務(wù)架構(gòu)憑借其對(duì)云服務(wù)的天然適應(yīng)性,以及能夠快速迭代和擴(kuò)展應(yīng)用的特點(diǎn),成為互聯(lián)網(wǎng)創(chuàng)業(yè)公司的技術(shù)首選。如何更好地利用計(jì)算資源?如何更方便地維護(hù)越來(lái)越復(fù)雜的應(yīng)用程序?由七牛主辦的開發(fā)者最佳實(shí)踐日第15期,我們邀請(qǐng)到專業(yè)CaaS服務(wù)提供者靈雀科技的產(chǎn)品經(jīng)理成然,京東服務(wù)平臺(tái)資深架構(gòu)師李鑫和對(duì)容器技術(shù)有深刻見解的七牛云技術(shù)總監(jiān)肖勤,和大家一起分享微服務(wù)的架構(gòu)實(shí)踐、容器技術(shù)的應(yīng)用,以及對(duì)微服務(wù)底層的技術(shù)框架支持。
“微服務(wù)+”從理念到行動(dòng)
為了便于理解微服務(wù)的內(nèi)涵,七牛云技術(shù)總監(jiān)肖勤先拋出了一個(gè)簡(jiǎn)單的問題:線上服務(wù)器看到很多請(qǐng)求日志,有成功有失敗,如何統(tǒng)計(jì)出成功或者失敗的日志數(shù)量?對(duì)此,采用AWK這樣強(qiáng)大的工具,或是采用CUT、SORT這樣的小工具都可以解決問題,而二者在思路上則存在著明顯的差別:AWK是非常強(qiáng)大的工具,在面對(duì)復(fù)雜的問題時(shí),可以以很多分支和循環(huán)的方式去分析和應(yīng)對(duì);而像CUT、SORT、UNIQ這樣的程序,各自能做的事情非常簡(jiǎn)單。比如說(shuō)把每一行的前幾項(xiàng)分隔開,用SORT做簡(jiǎn)單地排序,UNIQ把相同的剝離出來(lái)。通過(guò)把它們結(jié)合起來(lái),一樣可以處理復(fù)雜的事情。
將這個(gè)例子放大到應(yīng)用和產(chǎn)品層面,就會(huì)發(fā)現(xiàn),第二種思路是用一些功能比較明確、業(yè)務(wù)比較精練的服務(wù)去解決更大、更實(shí)際的問題,這就是微服務(wù)架構(gòu)的本質(zhì)。
微服務(wù)架構(gòu)基礎(chǔ)案例
下圖是一個(gè)描述微服務(wù)的典型案例。具體場(chǎng)景類似于打車派單類的服務(wù),左邊是采用一個(gè)大而全的架構(gòu),來(lái)處理包括管理司機(jī)和乘客,訂單分配和費(fèi)用支付等所有問題,而右邊是進(jìn)行拆分,分別采用相對(duì)獨(dú)立的服務(wù)對(duì)各方面進(jìn)行管理,彼此之間使用統(tǒng)一的接口來(lái)進(jìn)行交流。
從結(jié)構(gòu)來(lái)看,右邊的網(wǎng)狀結(jié)構(gòu)其實(shí)比左邊星型的結(jié)構(gòu)更復(fù)雜,聯(lián)系更多。那么這樣一個(gè)復(fù)雜架構(gòu)的好處表現(xiàn)在哪里?
1.復(fù)雜度可控:在將應(yīng)用分解的同時(shí),規(guī)避了原本復(fù)雜度無(wú)止境的積累。每一個(gè)微服務(wù)專注于單一功能,并通過(guò)定義良好的接口清晰表述服務(wù)邊界。由于體積小、復(fù)雜度低,每個(gè)微服務(wù)可由一個(gè)小規(guī)模開發(fā)團(tuán)隊(duì)完全掌控,易于保持高可維護(hù)性和開發(fā)效率。
2.獨(dú)立部署:由于微服務(wù)具備獨(dú)立的運(yùn)行進(jìn)程,所以每個(gè)微服務(wù)也可以獨(dú)立部署。當(dāng)某個(gè)微服務(wù)發(fā)生變更時(shí)無(wú)需編譯、部署整個(gè)應(yīng)用。由微服務(wù)組成的應(yīng)用相當(dāng)于具備一系列可并行的發(fā)布流程,使得發(fā)布更加高效,同時(shí)降低對(duì)生產(chǎn)環(huán)境所造成的風(fēng)險(xiǎn),最終縮短應(yīng)用交付周期。
3.技術(shù)選型靈活:微服務(wù)架構(gòu)下,技術(shù)選型是去中心化的。每個(gè)團(tuán)隊(duì)可以根據(jù)自身服務(wù)的需求和行業(yè)發(fā)展的現(xiàn)狀,自由選擇最適合的技術(shù)棧。由于每個(gè)微服務(wù)相對(duì)簡(jiǎn)單,當(dāng)需要對(duì)技術(shù)棧進(jìn)行升級(jí)時(shí)所面臨的風(fēng)險(xiǎn)較低,甚至完全重構(gòu)一個(gè)微服務(wù)也是可行的。
4.容錯(cuò):當(dāng)某一組建發(fā)生故障時(shí),在單一進(jìn)程的傳統(tǒng)架構(gòu)下,故障很有可能在進(jìn)程內(nèi)擴(kuò)散,形成應(yīng)用全局性的不可用。在微服務(wù)架構(gòu)下,故障會(huì)被隔離在單個(gè)服務(wù)中。若設(shè)計(jì)良好,其他服務(wù)可通過(guò)重試、平穩(wěn)退化等機(jī)制實(shí)現(xiàn)應(yīng)用層面的容錯(cuò)。
5.擴(kuò)展:?jiǎn)螇K架構(gòu)應(yīng)用也可以實(shí)現(xiàn)橫向擴(kuò)展,就是將整個(gè)應(yīng)用完整的復(fù)制到不同的節(jié)點(diǎn)。當(dāng)應(yīng)用的不同組件在擴(kuò)展需求上存在差異時(shí),微服務(wù)架構(gòu)便體現(xiàn)出其靈活性,因?yàn)槊總€(gè)服務(wù)可以根據(jù)實(shí)際需求獨(dú)立進(jìn)行擴(kuò)展。
七牛圖片處理微服務(wù)應(yīng)用案例
以七牛云的圖片處理(簡(jiǎn)稱FOP)場(chǎng)景為例。七牛能夠?yàn)橛脩籼峁└袷睫D(zhuǎn)換、尺寸和加水印等圖片處理服務(wù),從而幫助他們節(jié)省計(jì)算資源和帶寬資源。FOP服務(wù)早期的架構(gòu)很簡(jiǎn)單,以它的每一個(gè)應(yīng)用為后端。但由于原始圖片一般都很大,隨著用戶越來(lái)越多,流量越來(lái)越高,負(fù)載均衡逐漸出現(xiàn)了帶寬和流量的壓力。而面對(duì)這種情況,加更多的前端只是權(quán)宜之計(jì),因?yàn)閳D像處理對(duì)于CPU要求很高,意味著后端的數(shù)量會(huì)越來(lái)越多,負(fù)載均衡和后端流量方面始終是不平衡的,并且這也不是一個(gè)環(huán)保和節(jié)省資源的方式。
于是,F(xiàn)OP服務(wù)做了一個(gè)架構(gòu)上的調(diào)整:把服務(wù)再做拆分。圖像處理服務(wù)拆成兩個(gè)部分,分別負(fù)責(zé)處理文件的傳輸和圖像本身的處理。從負(fù)載均衡過(guò)來(lái)的請(qǐng)求不再是完整的文件,而是文件的地址。這樣,我們可以以更靈活來(lái)處理,把負(fù)載均衡和流量?jī)?yōu)化,優(yōu)化和部署也可以跟整個(gè)圖像處理沒有關(guān)系,可以做單獨(dú)的部署。下面兩幅圖即是一個(gè)對(duì)微服務(wù)再進(jìn)行細(xì)分的例子。
而細(xì)分之后,對(duì)于稍微復(fù)雜一些的請(qǐng)求,比如一個(gè)圖片需要改變格式和尺寸,并且打上自定義水印。那么就用管道的方式把不同的服務(wù)串聯(lián)起來(lái)最終實(shí)現(xiàn)。
容器在微服務(wù)中的應(yīng)用
目前微服務(wù)架構(gòu)的主流技術(shù)方案中都使用了Docker,七牛也是如此。將Docker理解為輕量級(jí)的虛擬機(jī),它的一些特性如隔離、物理機(jī)制等可以說(shuō)和微服務(wù)架構(gòu)有天然的契合度。但是Docker并不能解決微服務(wù)的所有問題,它最初是一個(gè)單機(jī)的工具,雖然后來(lái)官方也推出了很多的工具鏈,要真正解決部署的問題,還有很長(zhǎng)的路要走。
肖勤推薦了一個(gè)去年谷歌發(fā)布的開源容器系統(tǒng)Kubernetes。 Kubernetes提供了管理多個(gè)容器的方式,能夠令它們?cè)谡嬲奈锢頇C(jī)或者虛擬機(jī)以一個(gè)合理的方式運(yùn)用起來(lái),供外界訪問。Kubernetes存在的意義,是因?yàn)樗鉀Q了微服務(wù)另外一個(gè)部署的問題,拆分之后不同模塊之間的聯(lián)系和依賴會(huì)更加復(fù)雜,勢(shì)必對(duì)于運(yùn)營(yíng)和部署有更高的要求,如果沒有工具和系統(tǒng)能夠提供這樣的能力,或者沒有更好的方法去做的話,微服務(wù)就是空中樓閣。而Kubernetes提供的能力是用戶只需要去定義它的服務(wù)期望的狀態(tài),而不用去關(guān)心它的過(guò)程。整個(gè)調(diào)度的過(guò)程,整個(gè)提供服務(wù)的過(guò)程都由這個(gè)系統(tǒng)去幫你實(shí)現(xiàn)。
Kubernetes提出了很多概念。比如說(shuō)Kubernetes Master,它是一個(gè)中心的服務(wù)而不是工具。首先由API接受容器的配置,提供一個(gè)調(diào)度器,把容器調(diào)度到合理的位置運(yùn)行,再提供一定的控制技術(shù),保證容器運(yùn)行的狀態(tài)。Minion可以理解為容器運(yùn)行的真正節(jié)點(diǎn),Pods是一個(gè)或者一組容器,在Kubernetes 中是可以調(diào)動(dòng)的最小程序,Replication Controller保證了它運(yùn)行的數(shù)據(jù),如果它掛掉了,就不能再提供服務(wù)?,F(xiàn)在也會(huì)有很多服務(wù)的副本,以保證Pods的數(shù)量和運(yùn)行狀態(tài)。另外一個(gè)標(biāo)簽是Labels,是容器運(yùn)行時(shí)附加的。它的作用是容器在被使用的時(shí)候,能夠有一個(gè)規(guī)則讓前面的服務(wù)正確找到它。服務(wù)是一個(gè)虛擬的概念,是描述一組Pods對(duì)外提供的接口和對(duì)外提供的能力,通過(guò)代理的方式來(lái)實(shí)現(xiàn)。
上圖是Kubernetes官方文檔中的描述。值得注意的是,Kubernetes系統(tǒng)是按照微服務(wù)架構(gòu)設(shè)計(jì)的。因?yàn)轫?xiàng)目很多部分和逐漸,比如說(shuō)調(diào)度器和復(fù)制器,甚至包括Docker在整個(gè)系統(tǒng)中都會(huì)被替換,如果有更好的容器,Docker有可能會(huì)被棄用,變成另外的技術(shù)。
如何評(píng)價(jià)Kubernetes系統(tǒng)呢?是不是整個(gè)微服務(wù)在實(shí)踐上的一個(gè)未來(lái)呢?目前無(wú)法確定,因?yàn)閺膶W(xué)習(xí)的角度上來(lái)看, Kubernetes也表現(xiàn)出了一定的局限性。比如說(shuō)Pods的網(wǎng)絡(luò),雖然它提供了文檔可以某些方式體現(xiàn),但是1.0提供的方式還是和自己的云服務(wù)相關(guān)。這些局限性可能跟谷歌的策略有關(guān),因?yàn)楣雀璺浅OMネ扑腉CE平臺(tái)。我們發(fā)現(xiàn)Kubernetes在設(shè)計(jì)當(dāng)中,如果不適用他們的云服務(wù),摘出來(lái)的話,這一部分還需要做很多事情,才可以把Kubernetes在自己的基礎(chǔ)上做一個(gè)比較好的網(wǎng)絡(luò)服務(wù)。
基于Docker的微服務(wù)架構(gòu)云端實(shí)踐
應(yīng)用設(shè)計(jì)架構(gòu)的演變
十年前想構(gòu)建一個(gè)具備基本功能流程的電子商務(wù)網(wǎng)站,包括用戶瀏覽產(chǎn)品信息、加入購(gòu)物車、下單,在線支付和完成配送,在進(jìn)行系統(tǒng)構(gòu)建時(shí),典型做法是把功能模塊簡(jiǎn)單地做一些劃分,后臺(tái)會(huì)訪問統(tǒng)一數(shù)據(jù)庫(kù),包括用戶管理、商品信息、支付。后來(lái)有些程序員意識(shí)到可以把一些軟件應(yīng)用當(dāng)中的最底層和數(shù)據(jù)庫(kù)獨(dú)立起來(lái),緊接著出現(xiàn)了很多的工具做這些東西,如JDBC、ADO.Net等。
接下來(lái)就出現(xiàn)了比較傳統(tǒng)的經(jīng)典三層架構(gòu)Web方式:最上面是展現(xiàn)層,主要是處理UI,中間層處理基本業(yè)務(wù),下面是數(shù)據(jù)訪問層,后面是作為它的存儲(chǔ)方。如下圖所示。
時(shí)至今日,這種多層次的應(yīng)用構(gòu)架仍然具備一些優(yōu)勢(shì):層次劃分清晰,層與層之間有比較清晰的接口,每層之間非常清晰。展現(xiàn)層只負(fù)責(zé)UI,邏輯層負(fù)責(zé)業(yè)務(wù)邏輯,每一層又可以進(jìn)而被分解成邏輯的組建。特別是業(yè)務(wù)邏輯層,一般來(lái)說(shuō)都會(huì)把它分為邏輯組建,包括服務(wù)于用戶管理的,服務(wù)于產(chǎn)品信息的,服務(wù)于支付的,等等。而處于最下面的數(shù)據(jù)訪問層,雖然能夠被分成若干個(gè)模塊和組建,但是從部署上來(lái)講,仍然是單塊的組建。所有的程序基本上運(yùn)行在一個(gè)進(jìn)程上,所有的代碼都會(huì)被打包、編譯和部署,我們把它做成一塊的東西。
在項(xiàng)目初期,多層架構(gòu)能夠使程序員更容易開發(fā)、測(cè)試和部署。但隨著應(yīng)用程序逐漸增長(zhǎng),業(yè)務(wù)復(fù)雜度會(huì)變的越來(lái)越高。這種情況下三層構(gòu)架并不是特別適合業(yè)務(wù)的繼續(xù)發(fā)展,可維護(hù)性和敏捷程度都會(huì)變差,并且團(tuán)隊(duì)擴(kuò)大后成員之間的溝通也會(huì)影響產(chǎn)品的交付。從而最終影響到對(duì)市場(chǎng)需求新的跟進(jìn)。而微服務(wù),就是解決這些問題的一個(gè)很好的方案。
什么是微服務(wù)
上圖即為通過(guò)微服務(wù)架構(gòu)把原來(lái)的應(yīng)用拆分成一系列的微服務(wù),它們之間可以用比較輕量級(jí)的協(xié)議互相溝通,因?yàn)槊總€(gè)服務(wù)是運(yùn)行在自己獨(dú)立的進(jìn)程上,完全可以進(jìn)行非常獨(dú)立的部署和維護(hù)。另外一點(diǎn)微服務(wù)提倡的是技術(shù)選型去中心化,在不同的服務(wù)中可以選擇最適合這部分的持久化方案。
靈雀云對(duì)已Docker化的微服務(wù)的支撐
靈雀云認(rèn)為,Docker是運(yùn)行微服務(wù)的最佳解決方案。Docker實(shí)際上是一個(gè)應(yīng)用容器的引擎,可以讓開發(fā)者非常方便地把自己的應(yīng)用以及這個(gè)應(yīng)用所需要的所有依賴都打進(jìn)容器鏡像當(dāng)中,且具有可移植性,能夠部署到任何服務(wù)器上。靈雀云是基于Docker構(gòu)建的,如果把封裝的微服務(wù)比喻成集裝箱的話,靈雀云則提供了一個(gè)大輪船,裝載了所有集裝箱,為微服務(wù)運(yùn)行提供一個(gè)穩(wěn)定的運(yùn)行環(huán)境,用戶也可以在此基礎(chǔ)上進(jìn)行管理。這里就可以享受到很多云端服務(wù)的優(yōu)勢(shì)。
創(chuàng)建:靈雀云的鏡像構(gòu)建和持續(xù)集成服務(wù)幫助用戶將獨(dú)立、可復(fù)用的微服務(wù)打包,轉(zhuǎn)化為隨時(shí)可以部署的容器鏡像。
集成:靈雀云不僅在平臺(tái)的鏡像倉(cāng)庫(kù)中匯集了大量來(lái)自社區(qū)的優(yōu)質(zhì)鏡像,也支持平臺(tái)以外的任意鏡像源。用戶可以自由組合、復(fù)用數(shù)以萬(wàn)計(jì)的容器化微服務(wù),像搭積木一樣輕松集成應(yīng)用。
部署:微服務(wù)由于組件數(shù)量眾多,云端部署成為實(shí)踐上的一個(gè)難點(diǎn)。靈雀云以容器為應(yīng)用發(fā)布的載體,用戶不必指定傳統(tǒng)部署方式中繁瑣的步驟,只需提供容器鏡像和簡(jiǎn)單的容器配置,平臺(tái)會(huì)將整個(gè)部署流程自動(dòng)化。靈雀云與docker-compose兼容,實(shí)現(xiàn)對(duì)于由多個(gè)微服務(wù)容器組成的完整應(yīng)用的一鍵部署。
運(yùn)維:微服務(wù)由于獨(dú)立進(jìn)程眾多,部署后的運(yùn)維、管理成為實(shí)踐上的另一個(gè)難點(diǎn)。靈雀云完全屏蔽底層云主機(jī)和基礎(chǔ)架構(gòu)運(yùn)維,讓用戶專注于應(yīng)用。同時(shí),靈雀云通過(guò)容器編排、自動(dòng)修復(fù)、自動(dòng)擴(kuò)展、監(jiān)控日志等高級(jí)應(yīng)用生命周期服務(wù)實(shí)現(xiàn)容器化微服務(wù)的智能托管,進(jìn)一步幫助用戶降低運(yùn)維成本和難度。
網(wǎng)絡(luò):微服務(wù)架構(gòu)下各組件之間的溝通、協(xié)調(diào)對(duì)網(wǎng)絡(luò)有較高要求,尤其在云端實(shí)踐中,各個(gè)微服務(wù)組件的物理位置是動(dòng)態(tài)的,且不受應(yīng)用控制。靈雀云提供完整的容器網(wǎng)絡(luò)解決方案,支持負(fù)載均衡、服務(wù)發(fā)現(xiàn)、跨主機(jī)關(guān)聯(lián),以及應(yīng)用安全內(nèi)網(wǎng)來(lái)確保微服務(wù)對(duì)內(nèi)、對(duì)外網(wǎng)絡(luò)的可用性及安全性。
存儲(chǔ):微服務(wù)提倡多元化持久性(Polyglot Persistence),應(yīng)用內(nèi)的每個(gè)微服務(wù)可根據(jù)實(shí)際需求選擇最合適的數(shù)據(jù)服務(wù)。靈雀云將持久性云存儲(chǔ)抽象成數(shù)據(jù)卷,可以直接掛載在容器上,并在容器重啟、遷移中自動(dòng)重新掛載??芍С秩我馊萜骰瘮?shù)據(jù)服務(wù),供微服務(wù)應(yīng)用集成。
微服務(wù)架構(gòu)的誕生和容器技術(shù)的流行,幾乎是同時(shí)發(fā)生的,這并不是偶然。這是互聯(lián)網(wǎng)時(shí)代倒逼傳統(tǒng)技術(shù)和架構(gòu)而產(chǎn)生的變革,最前線的開發(fā)者和他們所在的互聯(lián)網(wǎng)企業(yè)最先感受到了這場(chǎng)變革。靈雀云希望與開發(fā)者一起共同引領(lǐng)這場(chǎng)變革,幫助互聯(lián)網(wǎng)企業(yè)真正專注于自身的核心業(yè)務(wù),并在技術(shù)和架構(gòu)上保持領(lǐng)先。
京東對(duì)于微服務(wù)底層的技術(shù)支持實(shí)踐
京東資深架構(gòu)師李鑫主要負(fù)責(zé)京東的服務(wù)框架, 他所分享的內(nèi)容是對(duì)微服務(wù)底層的技術(shù)框架支持。
為何要微服務(wù)化?
原因有以下幾點(diǎn)。
1.系統(tǒng)規(guī)模隨著業(yè)務(wù)的發(fā)展⽽而增長(zhǎng),原有系統(tǒng)架構(gòu)模式中邏輯過(guò)于耦合,不再適應(yīng);
2.拆分后的⼦系統(tǒng)邏輯內(nèi)聚,易于局部擴(kuò)展;
3.⼦系統(tǒng)之間通過(guò)接⼝口來(lái)進(jìn)⾏交互,接⼝契約不變的情況下可獨(dú)⽴變化。
上圖中,左邊是幾年前京東的架構(gòu),很多服務(wù)都是訪問同樣一個(gè)DB。這種架構(gòu)的問題在于:流量來(lái)了以后全部壓力都在DB上。而且在之前京東的架構(gòu)里比較強(qiáng)調(diào)快速開發(fā),很多邏輯比如說(shuō)倉(cāng)儲(chǔ)配送服務(wù)都不存在,全都依靠BD來(lái)進(jìn)行。這樣可擴(kuò)展性相當(dāng)差,性能也不太可控。后來(lái),我們根據(jù)業(yè)務(wù)模塊和特性進(jìn)行水平拆分,應(yīng)用和應(yīng)用之間都要通過(guò)接口進(jìn)行交互,有同步和異步接口。
京東服務(wù)平臺(tái)演變歷程
下圖是京東服務(wù)平臺(tái)的基本功能構(gòu)成。
在2012年初,京東開始做第一代服務(wù)框架,用的是zookeeper集群作為注冊(cè)中心,base on開源的服務(wù)體系。如下圖所示。
第一代架構(gòu)在運(yùn)營(yíng)過(guò)程中,暴露出了很多問題。
1. 客戶端
• 許多邏輯放到客戶端,客戶端邏輯太多,一旦需要修改,就面臨升級(jí)問題。
2. 注冊(cè)中⼼
• 將ZooKeeper作為注冊(cè)中⼼,功能定制擴(kuò)展受限。
3. 服務(wù)治理
• 缺乏流控手段,大流量打爆線程池;
• 更改配置需要重啟,對(duì)于運(yùn)營(yíng)不夠友好;
• 缺乏調(diào)用監(jiān)控,沒有調(diào)用分析圖表。
為了解決以上問題,團(tuán)隊(duì)在2014年推出了新服務(wù)平臺(tái)JSF,其框架示意圖如下。
可以看出,服務(wù)注冊(cè)和尋址沒有太大變化,主要變化在于注冊(cè)中心。采用團(tuán)隊(duì)自己寫的服務(wù),并提供了index服務(wù)數(shù)據(jù)庫(kù)。相對(duì)來(lái)講,詢問注冊(cè)中心地址,會(huì)進(jìn)行一個(gè)服務(wù)的調(diào)用。因?yàn)檫@一塊有自己內(nèi)部的邏輯,沒有辦法實(shí)現(xiàn),所以定期會(huì)發(fā)送性能統(tǒng)計(jì)數(shù)據(jù)。把RPC轉(zhuǎn)化,生成負(fù)載均衡管理重試策略,然后經(jīng)過(guò)序列化以后發(fā)送到server并解碼,再進(jìn)行實(shí)際的業(yè)務(wù)調(diào)用,然后進(jìn)行一些過(guò)濾的邏輯。
京東服務(wù)平臺(tái)核心技術(shù)
1.協(xié)議
• 采⽤異步事件通訊框架Netty來(lái)實(shí)現(xiàn)⺴絡(luò)協(xié)議棧;
• 同⼀端⼝同時(shí)支持Http、TCP協(xié)議訪問,根據(jù)數(shù)據(jù)包情況掛載不同解碼器;
• TCP長(zhǎng)鏈接下使⽤用⾃定義二進(jìn)制協(xié)議;
• HTTP網(wǎng)關(guān)來(lái)應(yīng)對(duì)跨語(yǔ)⾔言訪問。
2.RPC-callback
• TCP長(zhǎng)鏈接是雙⼯的,服務(wù)方可以主動(dòng)推送消息到調(diào)⽤方;
• 調(diào)⽤端檢測(cè)到參數(shù)列表中有Callback類型,登記相應(yīng)的callback對(duì)象;服務(wù)端收到調(diào)用時(shí),生成相應(yīng)的反向調(diào)用代理;
• 服務(wù)端持有此代理,并在需要時(shí)調(diào)用此代理來(lái)推送消息
3.負(fù)載均衡
一個(gè)服務(wù)至少部署兩個(gè)以上實(shí)例,掛了一個(gè)以后,另外一個(gè)可以正常服務(wù)。服務(wù)消費(fèi)者這一塊,有一個(gè)負(fù)載均衡的算法選擇服務(wù)提供者,可以設(shè)置權(quán)重。有一個(gè)可用列表,還有一個(gè)重連列,系統(tǒng)會(huì)定時(shí)連接。還有一個(gè)是非健康列表,雖然可以長(zhǎng)鏈接建立起來(lái),這個(gè)時(shí)候給出的反饋是不正常的,維護(hù)的時(shí)候會(huì)把它挪動(dòng)可用列表里。
4.性能優(yōu)化
首先有一個(gè)批量處理,請(qǐng)求先寫入RingBuffer為,打成序列化與反序列化這種耗時(shí)的操作從Netty的I/O線程中挪到用戶線程池中。啟用壓縮以應(yīng)對(duì)大數(shù)據(jù)量的請(qǐng)求,默認(rèn)snappy壓縮算法。最后是定制msgpack序列化,序列化模板,同時(shí)還支持fast json、hessian等多種序列化協(xié)議。
5.注冊(cè)中心
京東有很多機(jī)房,對(duì)于跨機(jī)房來(lái)說(shuō)是耗用更多資源,也占用了專線資源。這里實(shí)現(xiàn)了優(yōu)先訪問本機(jī)房的注冊(cè)中心,不可用的話才會(huì)去連起來(lái)機(jī)房。對(duì)于注冊(cè)中心來(lái)說(shuō),后面會(huì)連一個(gè)數(shù)據(jù)庫(kù)。但是這一塊連數(shù)據(jù)庫(kù)失敗的話,也會(huì)有一些單點(diǎn)的問題。對(duì)于這種情況,實(shí)現(xiàn)了一個(gè)LDS,在寫數(shù)據(jù)庫(kù)的同時(shí)會(huì)寫到本地的存儲(chǔ),在后臺(tái)進(jìn)行數(shù)據(jù)的同步。如果說(shuō)DB服務(wù)不可用的話,還是可以取得相應(yīng)的注冊(cè)。
6.配置
配置這一塊是服務(wù)提供者列表維護(hù),動(dòng)態(tài)推送。可以查看當(dāng)前服務(wù)生效的配置和狀態(tài),可以看出調(diào)用的平均耗時(shí)和失敗的次數(shù)。對(duì)服務(wù)動(dòng)態(tài)分組無(wú)須啟動(dòng),而且機(jī)房也有備份,出現(xiàn)問題直接調(diào)用就可以了。
7.限流
每一個(gè)服務(wù)調(diào)用者都有可能成為潛在的DDOS攻擊者,這里會(huì)給服務(wù)的所有調(diào)用者帶上標(biāo)示,在系統(tǒng)環(huán)境變量中帶上APPID。此外,開發(fā)了計(jì)數(shù)器服務(wù),限定單位時(shí)間內(nèi)最大調(diào)用次數(shù)。如果說(shuō)你是一個(gè)推送服務(wù),限定每分鐘四百次,其實(shí)調(diào)用已經(jīng)超限了。為了保護(hù)服務(wù)端,系統(tǒng)同時(shí)限定了并發(fā)數(shù),服務(wù)端執(zhí)行時(shí)檢查請(qǐng)求的狀態(tài),如等待時(shí)間大于超時(shí)時(shí)間,直接丟棄。
8.降級(jí)
• 每個(gè)服務(wù)接⼝口的每個(gè)⽅方法都有災(zāi)備降級(jí)開關(guān);
• 配置mock邏輯,返回的結(jié)果⽤用json格式預(yù)先設(shè)好;
• 降級(jí)開關(guān)打開時(shí)將在consumer端短路RPC調(diào)⽤用,直接返回JSON結(jié) 果。
9.彈性云部署
在京東內(nèi)部,CAP負(fù)責(zé)資源調(diào)度,JDOS負(fù)責(zé)資源的虛擬和部署。CAP會(huì)定時(shí)調(diào)度JSF監(jiān)控平臺(tái)的方法,如果說(shuō)告訴它調(diào)用的次數(shù)已經(jīng)超了,CAP會(huì)調(diào)用JDOS,分配具體的服務(wù)資源,把一些新服務(wù)自動(dòng)部署。最終,到注冊(cè)中心進(jìn)行注冊(cè)。
下一步研發(fā)方向
首先會(huì)做的是服務(wù)治理,根據(jù)應(yīng)用ID的一系列管理增強(qiáng)。增強(qiáng)接口文檔管理,建立接口文檔中心,幫助用戶使用接口。最后是增強(qiáng)跨語(yǔ)言支持,對(duì)于一些比較小規(guī)模的,直接通過(guò)網(wǎng)站來(lái)更新。
以上是牛小七對(duì)于本次開發(fā)者最佳實(shí)踐日內(nèi)容的概括性介紹,如需獲取詳細(xì)的演講信息和往期內(nèi)容回顧,可以訪問活動(dòng)專題。