微服務(wù)架構(gòu)上云最佳實踐

一、微服務(wù)拆分

首先從真實的案例開始講起乎折,當(dāng)一些客戶接觸到了一些微服務(wù)之后,他們就會將原本經(jīng)典的分層架構(gòu)模式拆分成為微服務(wù)侵歇。如下圖所示骂澄,客戶原本的架構(gòu)是比較經(jīng)典的分層架構(gòu)模型,可以看到每一層的結(jié)構(gòu)都非常清晰惕虑,當(dāng)此時想要做微服務(wù)拆分的時候第一步就是將DAO層直接拆分出來坟冲。而大家都知道磨镶,這樣做肯定會有一些不妥之處,那么不妥之處到底在哪里呢健提?在這里就埋下一個疑問琳猫,大家可以先思考一下對于這樣的經(jīng)典的分層架構(gòu)究竟應(yīng)該如何去進(jìn)行拆分。


微服務(wù)的拆分其實要先從DDD開始說起私痹,那么什么是DDD呢脐嫂?DDD其實是一種軟件設(shè)計的指導(dǎo)思想,它可以指導(dǎo)我們設(shè)計一些高質(zhì)量的軟件架構(gòu)紊遵,DDD的核心是想讓技術(shù)人員和業(yè)務(wù)人員使用一種共同的語言并且都把關(guān)注點聚焦在業(yè)務(wù)層面账千,在這樣情況下去討論、發(fā)現(xiàn)和實現(xiàn)業(yè)務(wù)的價值暗膜。DDD中有一些核心的概念匀奏,首先其中有“領(lǐng)域”的概念,所謂“領(lǐng)域”這個概念的意思就是團(tuán)隊所關(guān)注的業(yè)務(wù)学搜。在領(lǐng)域中我們會提煉出一些模型娃善,而這些模型有的是需要口口相傳的;也有的是需要我們寫在開發(fā)文檔上面瑞佩,便于新進(jìn)入團(tuán)隊的同學(xué)學(xué)習(xí)開發(fā)的聚磺;還有的是需要直接寫在給客戶看的文檔上面供客戶去理解的;等等這些我們稱之為為領(lǐng)域模型钉凌。在領(lǐng)域模型確定之后咧最,就需要有一個稱之為“通用語言”的東西,這個通用語言就是用于大家進(jìn)行交流的御雕。大家可能會覺得這個是非常自然的事情矢沿,但是事實上并不是這樣的,這里舉一個例子給大家解釋一下酸纲,比如兩個程序員之間進(jìn)行溝通時捣鲸,描述轉(zhuǎn)賬這個場景可能是這樣的:定義一個變量transformMoney接收這個錢這個值,從第一個賬戶上面把這個錢減掉然后加到另一個賬戶上面去闽坡,然后使用DAO進(jìn)行Save操作就可以了栽惶,這是程序員之間很自然的溝通語言。但是如果這個時候有業(yè)務(wù)人員進(jìn)來了之后疾嗅,他可能并不理解這樣的描述外厂,業(yè)務(wù)人員的描述可能是這樣的:轉(zhuǎn)賬的這筆錢可能會需要分為系統(tǒng)內(nèi)部轉(zhuǎn)賬和系統(tǒng)外部轉(zhuǎn)賬,根據(jù)轉(zhuǎn)賬金額的大小可能會采用不同的審計策略代承,根據(jù)這些策略每一筆資金可能使不同的系統(tǒng)感知到不同的事件汁蝶,而且這些路徑可能需要做沉淀和記錄,可能會有交易的記錄產(chǎn)生等等,這樣描述出來可能技術(shù)人員也能夠聽懂掖棉,業(yè)務(wù)人員也能可以聽懂墓律。


這是什么意思呢?其實大家可以仔細(xì)想想幔亥,上面的這段對話其實是可以直接翻譯成為代碼的耻讽,這就是所謂的通用語言。但是通用語言的產(chǎn)生過程也是不斷地提升的過程帕棉,就像代碼需要不斷地進(jìn)行重構(gòu)和完善针肥。而上面這段對話其實需要在一定的邊界之內(nèi)才會有意義,而邊界又是什么意思呢香伴?還是使用剛才轉(zhuǎn)賬的例子祖驱,轉(zhuǎn)賬時使用的賬戶和登錄時使用的賬戶雖然都叫做賬戶,但是肯定不是同一個東西瞒窒,這時候就產(chǎn)生了限界,也就是BoundedContext 這個概念乡洼。

在介紹完這些基本概念之后崇裁,我們繼續(xù)分享DDD的戰(zhàn)略和戰(zhàn)術(shù)。從一個比較標(biāo)準(zhǔn)的解釋來說束昵,戰(zhàn)略就是用于指導(dǎo)軍隊去打贏某場戰(zhàn)爭的思想拔稳,也就是一種方法和謀略。而DDD的戰(zhàn)略當(dāng)然不是用于打仗的锹雏,而是用于拆分領(lǐng)域等其他方面的巴比。當(dāng)然DDD的戰(zhàn)略和戰(zhàn)爭的戰(zhàn)略有一定相同之處,比方在打仗的時候需要選好一塊什么樣的地盤礁遵,以及在上面用什么樣子的方式如何發(fā)動這場戰(zhàn)爭轻绞,而這塊地盤在微服務(wù)拆分上就是可以理解成選擇一個什么樣子的領(lǐng)域,這個領(lǐng)域可以分為核心域和子域佣耐。對于核心域而言政勃,從我們的業(yè)務(wù)就能顯而易見地看出來它是區(qū)別于其他業(yè)務(wù)的一塊領(lǐng)域,也就是核心業(yè)務(wù)兼砖。如果這塊領(lǐng)域不復(fù)存在的話奸远,那么整個團(tuán)隊或者公司就會出現(xiàn)問題。在核心域周圍則會存在支撐子域讽挟,比如對于電商業(yè)務(wù)而言懒叛,交易就是核心,核心域的旁邊則會有支撐核心域來區(qū)分業(yè)務(wù)的子域耽梅,比如圖中的物流和支付薛窥,這兩部分的支撐子域也是整個業(yè)務(wù)獨有的。當(dāng)然也會有其他的部分褐墅,比如通用子域拆檬,這部分就是其他公司可能會有或者其他業(yè)務(wù)也會存在的領(lǐng)域洪己,這部分的業(yè)務(wù)邏輯可能可以直接從某些開源軟件或者商業(yè)軟件拿過來使用,比如像每個公司都會使用的會員系統(tǒng)以及積分系統(tǒng)等竟贯。除此之外還有一些基礎(chǔ)的技術(shù)服務(wù)答捕,比如像短信服務(wù)這樣的技術(shù)服務(wù)。


當(dāng)上面這樣整個圖構(gòu)建完成之后屑那,我們會發(fā)現(xiàn)每一塊領(lǐng)域之間拱镐,每一塊上下文之間都是存在一定的關(guān)系的。這些關(guān)系可能是比較簡單的上下游的關(guān)系持际,除此之外沃琅,還可能存在客戶關(guān)系或者供應(yīng)商關(guān)系,或者是共享同一塊內(nèi)核蜘欲、模型這樣的關(guān)系益眉,比方說前臺系統(tǒng)和后臺系統(tǒng)往往會共享同一種數(shù)據(jù)模型,還可能存在兩個領(lǐng)域之間需要做很多的適配器等等姥份,這些在DDD中也會有一些推薦架構(gòu)模式去遵循郭脂。


除了上述在架構(gòu)模式上面的東西以外,在一個領(lǐng)域內(nèi)部還會有一些戰(zhàn)術(shù)上的模式讓我們定義一些東西澈歉。還是使用剛剛那么轉(zhuǎn)賬的例子來分析展鸡,每一個賬戶以及每一筆交易的記錄都是需要進(jìn)行唯一性區(qū)分的,這些需要進(jìn)行唯一性區(qū)分存儲的東西可以我們叫做實體埃难,還有說轉(zhuǎn)賬的時候的那筆錢其實也會是一個對象莹弊,因為它可能存在匯率不同、幣種等信息涡尘,它也是以一個對象存在的忍弛,但是可能這個對象是不變的,因為我的三塊錢和你的三塊錢是一樣的考抄,我們將這樣的對象稱為值對象剧罩。在做轉(zhuǎn)賬的時候,這個轉(zhuǎn)賬的過程可能會與某些交易機(jī)構(gòu)或者其他的實體之間發(fā)生關(guān)系座泳,所以需要內(nèi)聚更加合理的地方惠昔,這個時候就出現(xiàn)了領(lǐng)域服務(wù)。然后回到剛才提到的需求之一就是每一筆錢都需要能夠被感知到挑势,要能夠感知到就需要能夠產(chǎn)生或處理一些事件镇防,這樣就會有一些領(lǐng)域事件出來。還有就是人與賬戶是什么關(guān)系呢潮饱?想要拿到賬戶去做轉(zhuǎn)賬之前首先需要先找到人来氧,此時這個人就會與賬戶出現(xiàn)一種聚合的關(guān)系,既然有了這樣聚合的關(guān)系;然后發(fā)現(xiàn)人對賬戶開通的過程啦扬,并不是簡單的new可以實現(xiàn)的中狂,因為可能會需要綁定很多東西,開通很多東西扑毡,所以這時候很可能需要工廠來幫你的忙胃榕。同樣的道理,當(dāng)你去做資源池的交互的時候瞄摊,可能DAO幫不了你勋又,因為DAO僅僅是對于DB的各種動作的轉(zhuǎn)義,它其實是沒有領(lǐng)域含義的换帜,所以這時候就會需要資源庫楔壤。

聊完了DDD這部分之后,我們再來看一下它和我們今天提到的微服務(wù)的拆分到底存在什么樣的關(guān)系惯驼。對于服務(wù)拆分而言蹲嚣,首先可以看到剛才分享的根據(jù)公司內(nèi)部的核心域或者業(yè)務(wù)內(nèi)部的核心域或者業(yè)務(wù)能力,拆分其實很簡單祟牲,首先就是“一縱”端铛,縱向拆分就像阿里巴巴這樣將業(yè)務(wù)拆分成為淘寶、天貓疲眷、聚劃算以及咸魚等。然后再是“一橫”您朽,橫指的就是拆分成剛才介紹的那些領(lǐng)域狂丝,包括核心域、支撐子域以及通用子域等哗总。然后再找一些東西几颜,也就是找其他的一些基礎(chǔ)的通用子域、一些基礎(chǔ)的能力域等讯屈。


當(dāng)我們已經(jīng)將服務(wù)拆分好了蛋哭,那么是不是這時候就可以真正地開始實現(xiàn)功能了呢?其實在真正開始做之前還需要好好思考一些問題涮母,因為微服務(wù)沒有銀彈谆趾。首先第一個需要考慮的問題就是我們的服務(wù)的內(nèi)聚和耦合是不是真的合理,因為內(nèi)聚和耦合難以量化叛本,所以這里所強調(diào)的是合理沪蓬。還有就是團(tuán)隊的構(gòu)成,因為微服務(wù)產(chǎn)生的目的就是為了減少團(tuán)隊成員之間的溝通来候,那么團(tuán)隊構(gòu)成是什么意思呢跷叉?首先第一個要點就是團(tuán)隊本身是需要全棧的,即自主性一定要很高。那么團(tuán)隊規(guī)模究竟應(yīng)該多大呢云挟?有一個參考的方法梆砸,就是“Two PizzaTeam”,也就是正好吃完兩個披薩的團(tuán)隊园欣。第二點的一個關(guān)鍵問題就是問自己準(zhǔn)備好組織架構(gòu)的變化了嗎帖世?這樣的說法來自于康威定律,這個定律說的核心思想可以理解為:一個公司的技術(shù)架構(gòu)可能最終會發(fā)展成為公司的組織架構(gòu)的樣子俊庇,當(dāng)然組織架構(gòu)也有可能發(fā)展成為技術(shù)架構(gòu)的樣子狮暑。第三點就是微服務(wù)在未來肯定會面臨更多的挑戰(zhàn),到底是哪些挑戰(zhàn)呢辉饱?在后續(xù)會為大家揭曉搬男。

二、服務(wù)化案例分享與最佳實踐

接下來為大家分享一些實際的案例彭沼,這些案例是提取自EDAS上云兩年多以來在客戶的環(huán)境中存在的實際問題缔逛。在正式介紹案例之前需要首先介紹幾個簡單的名詞:

HSF:阿里巴巴集團(tuán)所使用的 RPC 框架,全稱為 High Speed Framework姓惑,江湖人稱:“好舒服”褐奴。

EDAS:企業(yè)級分布式應(yīng)用服務(wù),阿里巴巴中間件提供的云上商業(yè)微服務(wù)解決方案于毙。

VPC:Virtual Private Cloud敦冬,虛擬私有云服務(wù)。阿里云上的一個基礎(chǔ)網(wǎng)絡(luò)產(chǎn)品唯沮,為隔離用戶的網(wǎng)絡(luò)環(huán)境而生脖旱。

服務(wù)化:開發(fā)篇

下圖是HSF服務(wù)的簡單介紹。首先第一個要分享的案例就是開發(fā)的時候遇到的問題介蛉,在分享這個案例之前首先簡單地介紹一下HSF萌庆。HSF有一個注冊中心,這個注冊中心用來管理發(fā)布和訂閱服務(wù)币旧。當(dāng)一個生產(chǎn)者啟動起來之后可能會對于自己的服務(wù)進(jìn)行發(fā)布践险,注冊中心監(jiān)聽了這個服務(wù)就會發(fā)送給正在監(jiān)聽的消費者疾党,然后消費者拿到地址之后就可以直接進(jìn)行RPC的調(diào)用了伪货。


那么如何使用HSF服務(wù)呢,在開始一個RPC的使用之前肯定會需要定義一個服務(wù)吆豹,而定義這個服務(wù)是通過一個接口的方式進(jìn)行的鳍刷。消費端可以直接使用這個接口在Spring容器的XML里面聲明這是一個消費端垫言,而生產(chǎn)者除了需要實現(xiàn)這個接口之外,也是需要向容器做聲明倾剿,表示自己是一個生產(chǎn)者筷频。


當(dāng)將服務(wù)部署完成之后蚌成,就可以實現(xiàn)RPC真正的調(diào)用了;下圖是一個客戶真實的案例凛捏,案例中的請求會牽涉到一個非常重的Task担忧,客戶的想法是希望服務(wù)端做完這個 Task 之后異步地通知給進(jìn)程。如果在單進(jìn)程層面下這樣寫代碼一點問題都沒有坯癣,甚至可以說是很優(yōu)雅瓶盛,但是在分布式環(huán)境下這樣寫卻是存在問題的,因為callback是回不來的示罗,所以說我們寫代碼的思維方式需要發(fā)生一定的轉(zhuǎn)變惩猫。


那么除了這樣思維方式的變化還需要有什么東西呢?在下圖中就為大家列舉了開發(fā)過程中的最佳實踐蚜点,這些最佳實踐有些是參考的集團(tuán)規(guī)約轧房、有一部分是自己從客戶的案例中整理的,沒有高深的技術(shù)绍绘,我理解起來完全是平時的一些小的點奶镶,大的點我不講、道行不深也講不出什么感覺陪拘、而且大的點肯定是有一幫人和幫你一起考慮的厂镇,反倒是一些小的點是我們?nèi)菀缀雎缘模驗橹挥心阋粋€人在思考左刽,很容易因為偷懶或者著急上個廁所就忘了捺信。小反而是一門更大的學(xué)問。這些小點就小到一行日志欠痴、一個參數(shù)的校驗迄靠、一個返回值、一個命名等等斋否。具體不多說,可以自己參考拭荤。


服務(wù)化:部署篇

分享完了開發(fā)茵臭,接下來為大家分享關(guān)于部署的問題。曾經(jīng)有客戶提出了一個工單舅世,就是服務(wù)都能夠看到旦委,但是還是會出現(xiàn)時好時壞的情況。我們仔細(xì)地審視了客戶部署的架構(gòu)雏亚,發(fā)現(xiàn)客戶的架構(gòu)是這樣的:他們使用了兩個VPC缨硝,這兩個VPC之間有生產(chǎn)者和消費者,還有一個在另外一個VPC中罢低,這時候就會發(fā)現(xiàn)我們所看到的部署架構(gòu)肯定是調(diào)用不通的查辩,因為他們的網(wǎng)絡(luò)本身就是不通的胖笛。


這里為大家簡單地介紹一下VPC。VPC其實是為了隔離用戶網(wǎng)絡(luò)環(huán)境而生的網(wǎng)絡(luò)產(chǎn)品宜岛,可以簡單地理解成為服務(wù)放入到VPC中去會更加安全长踊。大家可能會想如果只是劃分網(wǎng)絡(luò)的話,通過路由器或者交換機(jī)這些也能夠做到萍倡,那么為什么要使用VPC呢身弊?其實VPC除了劃分網(wǎng)絡(luò)的基礎(chǔ)功能之外,其實還可以實現(xiàn)跨可用區(qū)列敲,可以實現(xiàn)同城容災(zāi)阱佛,另外VPC中還有一些比較基礎(chǔ)的網(wǎng)絡(luò)產(chǎn)品,比方說可以使用SNAT/DNAT做源地址和目的地址的轉(zhuǎn)換戴而,甚至可以做VPC內(nèi)的統(tǒng)一的安全組管理等等凑术。在什么樣的場景下面會使用到VPC呢?關(guān)于這一點在阿里云官網(wǎng)上面有詳細(xì)的介紹填硕,在這里就不再贅述麦萤,大概就是做混合云架構(gòu)或者有NAT需求的時候就可以使用。


接下來介紹HSF路由扁眯,剛才提到當(dāng)消費者啟動的時候就會去做監(jiān)聽壮莹,生產(chǎn)者啟動的時候就會去做發(fā)布,當(dāng)發(fā)布的時候注冊中心知道這個地址之后就會推送給消費者姻檀,這就是一次簡單的服務(wù)發(fā)現(xiàn)過程命满。那么第一次選擇連接的時候,假設(shè)地址列表中有兩個绣版,一個好的一個壞的胶台,這時候應(yīng)該怎么樣呢?首先第一次Round Robin選擇連一個杂抽,與此同時啟動心跳進(jìn)程诈唬,進(jìn)行心跳檢測,如果此時發(fā)現(xiàn)地址有問題就會把這個地址放在一個不可用連接地址的列表中缩麸,但是心跳還會繼續(xù)铸磅,當(dāng)?shù)诙卧龠M(jìn)行連接的時候過程與上述大致相同,但是不會再去啟動一個心跳進(jìn)程了杭朱。


在EDAS中的運維層面可能有一些點需要列出來給用戶看的阅仔,因為經(jīng)常會有用戶遇到這些問題。在這里想要強調(diào)的點是 iptables 弧械,很多用戶非常喜歡設(shè)置iptables八酒,但是卻不建議大家去設(shè)置 iptables,首先它的學(xué)習(xí)成本比較高刃唐,其次它真的非常不好進(jìn)行維護(hù)和管理以及知識的傳遞羞迷,而且?guī)缀醪豢赡苋崿F(xiàn)批量的運維和管理界轩。除此之外,在 iptables 中用到的那些功能基本上可以在云上面使用VPC + NAT的方式進(jìn)行處理闭树,除非需要有一些非常高級的特性耸棒,比如需要根據(jù)數(shù)據(jù)包中的字符串進(jìn)行過濾等這樣的需求。


服務(wù)化:連調(diào)篇

分享完部署我們再聊一聊連調(diào)报辱,在連調(diào)過程中我們遇到了一些非常怪的事情与殃,就是客戶的反饋就是在云上面部署的一個服務(wù),有的人可以連接碍现,但是有的人就是偶爾不可以連接幅疼,非常不穩(wěn)定!我們看到這樣的現(xiàn)象之后就去客戶的服務(wù)器上提取了一些關(guān)鍵的信息昼接,其中的就包括這些:客戶開啟了recycle以及timestamps爽篷,然后主要說有NAT網(wǎng)關(guān),而且辦公網(wǎng)下的開發(fā)機(jī)器上存在時間戳不一致的情況慢睡,說到了這里很多有經(jīng)驗的同學(xué)就已經(jīng)猜出來問題到底是怎么一回事了逐工,原因就如下圖中左邊所列舉的這樣。


說到這里可能有同學(xué)已經(jīng)猜出來了是怎么回事了漂辐,這里我簡單簡述一下造成這個問題的原因泪喊,首先要從服務(wù)器端主動關(guān)閉連接的 TCP TIMEWAIT 狀態(tài)開始說起,顧名思義髓涯,這個狀態(tài)是在等袒啼,等什么呢?確保 Server 的最后一個 ACK 可以到達(dá)客戶端纬纪,因為客戶端在等著這個 ACK 來關(guān)閉她的 TCP 連接蚓再,等多久呢? 2MSL包各,這是一個很長的時間了摘仅,根據(jù)不同的系統(tǒng)不一樣,有的是60s问畅,有的是一百多秒娃属。那么開啟 recyle 會有什么好處?加速回收按声,怎么加速的膳犹?他的原理是基于 RTO 的恬吕,所謂 RTO 就是數(shù)據(jù)包的超時重傳的時間签则,這個時間怎么來的呢?基于一些值算出來的铐料,但是會很短渐裂,最短可以到200 ms豺旬,簡單的說起來就是從幾十秒一下降到零點幾秒級別的時延,這是一個很大的改進(jìn)柒凉,我覺得也很科學(xué)族阅。但是這樣沒有規(guī)避根本問題,畢竟人家一開始等那么長時間是有道理的膝捞,萬一真的有數(shù)據(jù)包隔了那么長時間才到咋辦呢坦刀?所以這里還有一種機(jī)制,叫做 PAWS蔬咬,這兩哥們就會把同一個 host 過來的數(shù)據(jù)包基于時間戳單調(diào)遞增的這么一個假設(shè)鲤遥,會拒絕掉一些 server 認(rèn)為不合理的包,且這個時間錯是一個 Per Host 的紀(jì)錄林艘,因為上一個鏈接都不在了盖奈,肯定要 Per Host 的都行了對吧?


回到我們當(dāng)前的這個案例狐援,當(dāng)兩臺機(jī)器通過 NAT 網(wǎng)關(guān)進(jìn)行訪問的時候钢坦,服務(wù)器端看到的是一個 Host,當(dāng)有時間不一致的時候啥酱,根據(jù)我們剛剛說的這些論斷爹凹,有些數(shù)據(jù)包就自然被 drop 掉了,這個問題我們也引申出來了一些建議的做法懈涛。首先無論什么樣的環(huán)境逛万,服務(wù)器上的時間戳一定要 check 是不是一致,尤其是有 https 和 openapi 調(diào)用的場景批钠。還有生產(chǎn)環(huán)境我們不怎么推薦使用 recycle 的宇植,建議設(shè)置合理的 timewait buckets 代替。同時盡量避免在生產(chǎn)環(huán)境使用 NAT埋心,最好走 SLB 的轉(zhuǎn)發(fā)指郁。


服務(wù)化:壓測

接下來分享一下關(guān)于壓測的內(nèi)容,這里講的壓測可能會與大家通常理解的場景不太一樣拷呆,因為是客戶在做壓測的時候拿著我們的RPC框架和另外一個目前比較流行的Restful的框架進(jìn)行對比闲坎,給回來的反饋是性能不行。在接到這樣的反饋之后茬斧,我們大概看了一下客戶的代碼是什么樣子腰懂,客戶的代碼大概是將一個對象使用JSON序列化之后做RPC,RPC回來之后也是一個String项秉,之后再將這個String反序列化成為一個對象返回給客戶端绣溜,也就是客戶在代碼中做了兩次JSON的序列化。在HSF中大家都知道它是字節(jié)支持序列化的娄蔼,這里的兩次序列化是浪費的怖喻;這種寫法很普遍底哗,希望大家注意。


還有一種典型的問題就是將一個Request直接轉(zhuǎn)發(fā)出去锚沸,這種方式我們知道也是不行的跋选。在HSF中支持的方式是Java的Native以及Hessian等,目前在序列化方面其實是不需要關(guān)注太多的性能的哗蜈,整個框架對于性能而言已經(jīng)優(yōu)化的足夠好了前标,除此之外在做序列化的時候這里也列出了一些大家比較容易遺漏的點,這些點就包括了為什么 HTTP 對象不行距潘,因為它其實一個不可序列化的對象候生。總結(jié)而言绽昼,就是在每一次序列化之前要好好思考一下這個對象是不是可以序列化的唯鸭;其次在序列化之前還需要好好想想序列化之后的字節(jié)大小為多少,是不是一個很大的對象硅确。還有就是需要對于一些特殊的場景多留一些心眼目溉,比如說枚舉、單例和一些范型等菱农。


服務(wù)化:上線運行

下圖的這個案例就是HSF的線程池滿了缭付,這個問題我相信很多同學(xué)都已經(jīng)遇到過,針對于這個問題這里首先列出了一個大概的時序圖循未,也就是可能在自己的業(yè)務(wù)中需要依賴于外部服務(wù)陷猫,可能就會影響到內(nèi)部的情況。


當(dāng)客戶與我們溝通的時候我們首先解釋了為什么連接池會滿的妖,首先簡單介紹一下HSF三種調(diào)用模型绣檬,第一種就是很自然的同步調(diào)用模式,就是一個一個地來嫂粟,調(diào)用完成之后再回去娇未;第二種情況就是異步調(diào)用,就是調(diào)用外部服務(wù)的請求不在乎調(diào)用的請求什么時候返回星虹,調(diào)用之后就繼續(xù)做自己的事情零抬,對下圖中的實例而言,我在發(fā)送驗證碼的之后就可以繼續(xù)執(zhí)行后續(xù)的步驟宽涌,這樣的好處就是用戶的體驗將會得到提升平夜,但是這種方式會帶來一些業(yè)務(wù)的損耗,如果短信真的發(fā)送失敗了則可能無法感知卸亮,系統(tǒng)認(rèn)為用戶拿到驗證碼了忽妒,但是事實上并沒有;所以比較推薦的是第三種方式——Future的方式,這種方式還是基于異步的锰扶,F(xiàn)uture是什么意思呢?其實是可以進(jìn)程可以先去干自己的活寝受,如果想要結(jié)果可以來拿坷牛,當(dāng)自己的任務(wù)完成再回頭取得異步調(diào)用結(jié)果的時候可能結(jié)果也就回來了,如果此時結(jié)果還沒有返回回來很澄,那么在這里等待也不會影響太大的事情京闰。


在介紹完這三種HSF的調(diào)用模型之后,還需要介紹一些線程池的模型甩苛,畢竟這個案例是與線程池相關(guān)的蹂楣。其實HSF中有三種線程池,第一個就是IO線程讯蒲,但是這個線程池中線程比較少痊土,因為其所做的工作也很少,基本上就做兩件事情:序列化和處理協(xié)議墨林;第二個線程池就是和我們這個案例息息相關(guān)的赁酝,在Server端會有一個很大的線程池,這個線程池默認(rèn)的最大值可以達(dá)到600旭等,當(dāng)談到HSF的線程池滿了也就是說這個地方滿了酌呆。還有一個地方是大家比較容易忽略的,就是在Tomcat的入口其實也有一個線程池搔耕,這個線程池其實決定了服務(wù)的并發(fā)數(shù)隙袁,但是這個并發(fā)數(shù)并不是單單由這個線程池決定的,理論上還需要加上另外一個字段Accept Count弃榨。


當(dāng)我們向客戶介紹完了以上兩種的內(nèi)部實現(xiàn)的時候菩收,就開始進(jìn)行優(yōu)化了,優(yōu)化的過程也是根據(jù)剛才的思路進(jìn)行的鲸睛,第一種方式主要是將調(diào)用的方法進(jìn)行了修改坛梁,第二種方式則是將一些線程池的參數(shù)調(diào)高了,把Tomcat線程池入口的并發(fā)數(shù)以及HSF的線程池的值調(diào)高了腊凶,然而這樣的調(diào)整只是緩解了一些問題划咐,但是并沒有解決最根本的問題。然后用戶下意識地采取了在云上進(jìn)行擴(kuò)容的方式钧萍,然后“奇跡”出現(xiàn)了褐缠,整個服務(wù)全掛掉了。


為什么服務(wù)會掛掉呢风瘦?后來經(jīng)過了解發(fā)現(xiàn)客戶的架構(gòu)是這樣的:使用Redis特別容易忽略掉一些東西队魏,這些東西從運維的層面上講會有一些規(guī)格,這些規(guī)格主要分為兩種,包括連接數(shù)和帶寬胡桨。很多運維人員誤以為在云上面的環(huán)境走內(nèi)網(wǎng)沒有帶寬限制官帘,其實完全錯了,所以對于云上規(guī)格模型一定要特別清楚昧谊。還有就是在開發(fā)層面的問題刽虹,在開發(fā)時,大家都喜歡使用common-pool呢诬,并且默認(rèn)喜歡設(shè)置成為一個很大的值涌哲,不管使不使用這些個連接都可能會默認(rèn)起來這么多連接,比如所有的機(jī)器都用50尚镰,機(jī)器規(guī)模擴(kuò)容到百級別的時候就可能會撐死阀圾。還有就是在開發(fā)時很喜歡使用一些List,把這些List序列化成JSON然后存儲為String狗唉,再從List返回僅有的幾個元素初烘,這些也是會引起問題的原因,以上這些就是我們用 Redis 的時候會遇到的一些問題分俯。


三账月、一些微服務(wù)架構(gòu)的常用模式

服務(wù)化:模式

在這里大家可能就會希望有一種東西可以動態(tài)地調(diào)整Redis這部分的連接數(shù),其實這就是微服務(wù)中的一種模式叫做Externalized configuration——外部配置動態(tài)推送澳迫,也就是通過外部的某些配置批量化地更新某些東西局齿。


剛才提到的是因為某些東西不行了導(dǎo)致網(wǎng)站會怎么樣,這時候可以選擇考慮當(dāng)發(fā)生故障的時候可以選擇將這個服務(wù)進(jìn)行限流降級或者甚至將整個鏈路都進(jìn)行降級橄登,這就是微服務(wù)推薦的第二種模式抓歼,Circuit Breaker——限流降級。


之前介紹的兩個應(yīng)用比較簡單拢锹,只有兩個服務(wù)之間的模型谣妻。當(dāng)面對如下圖所示的這樣的情況下就需要使用第三個模式Distributed tracing——分布式追蹤。


當(dāng)然其實微服務(wù)的模式不止上面提到的這三種卒稳,下圖就展現(xiàn)了整個微服務(wù)這部分能夠想到的一些模式蹋半。首先我們需要這樣的一個基礎(chǔ)組件,這個基礎(chǔ)組件包含了一些東西充坑,包括了一些架構(gòu)的思想减江,以及服務(wù)之間的架構(gòu)如何進(jìn)行編排交互,還有采用什么樣的部署模式捻爷,包括應(yīng)該采用單個容器級別的部署還是單個機(jī)器級別的部署辈灼,甚至是單個VM級別的部署。還需要制定某一種服務(wù)發(fā)現(xiàn)策略等也榄;當(dāng)在真正決定好了架構(gòu)之后巡莹,可能需要真正的微服務(wù)的底座來支撐起整個微服務(wù)的架構(gòu),底座規(guī)劃好之后就需要選擇服務(wù)之間的通訊模型。那么通訊模型選擇好之后降宅,就需要開始考慮服務(wù)高可用方面的事情了骂远。當(dāng)這方面規(guī)劃之后就需要考慮到一些日志、審計以及分布式追蹤等等這些數(shù)據(jù)化運營之類的東西腰根。還有一點比較重要的就是當(dāng)要對于服務(wù)進(jìn)行拆分就需要考慮數(shù)據(jù)庫到底是該分還是該合激才。如果需要分的話,那么問題來了唠雕,數(shù)據(jù)的一致性今后應(yīng)該如何保證,當(dāng)然這里也有一些模式可尋的吨述;還有分開之前數(shù)據(jù)可能是從一個地方取岩睁,現(xiàn)在需要從各個地方取了、測試也是一樣揣云,以前可能是測一塊捕儒,現(xiàn)在可能會需要測試一打,這些都是在微服務(wù)拆分完之后需要面對的挑戰(zhàn)邓夕,這也是本次最想傳遞給大家的東西刘莹。


當(dāng)然挑戰(zhàn)之下必有陪伴,EDAS就是陪伴大家的解決方案焚刚。為了鼓勵更多的中小企業(yè)能夠使用EDAS的服務(wù)点弯,現(xiàn)在阿里云上推出了EDAS的“1元計劃”】蠊荆基礎(chǔ)的應(yīng)用發(fā)布抢肛、運維、搭建分布式系統(tǒng)碳柱,低至1元/月捡絮。


出處:http://jm.taobao.org/2017/08/07/20170807/
阿里中間件團(tuán)隊博客**
致力于成為中國第一,世界一流的中間件技術(shù)團(tuán)隊
1莲镣、具有1-5工作經(jīng)驗的福稳,面對目前流行的技術(shù)不知從何下手,需要突破技術(shù)瓶頸的可以加瑞侮。2的圆、在公司待久了,過得很安逸半火,但跳槽時面試碰壁略板。需要在短時間內(nèi)進(jìn)修、跳槽拿高薪的可以加慈缔。3叮称、如果沒有工作經(jīng)驗,但基礎(chǔ)非常扎實,對java工作機(jī)制瓤檐,常用設(shè)計思想赂韵,常用java開發(fā)框架掌握熟練的,可以加挠蛉。4祭示、覺得自己很牛B,一般需求都能搞定谴古。但是所學(xué)的知識點沒有系統(tǒng)化质涛,很難在技術(shù)領(lǐng)域繼續(xù)突破的可以加。5. 群號:高級架構(gòu)群647631030點擊鏈接加入群【JAVA高級開發(fā)】:https://jq.qq.com/?_wv=1027&k=4EnTTxz 備注好信息掰担!6.阿里Java高級大牛直播講解知識點汇陆,分享知識,多年工作經(jīng)驗的梳理和總結(jié)带饱,帶著大家全面毡代、科學(xué)地建立自己的技術(shù)體系和技術(shù)認(rèn)知!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末勺疼,一起剝皮案震驚了整個濱河市教寂,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌执庐,老刑警劉巖酪耕,帶你破解...
    沈念sama閱讀 222,627評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異轨淌,居然都是意外死亡因妇,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評論 3 399
  • 文/潘曉璐 我一進(jìn)店門猿诸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來婚被,“玉大人,你說我怎么就攤上這事梳虽≈沸荆” “怎么了?”我有些...
    開封第一講書人閱讀 169,346評論 0 362
  • 文/不壞的土叔 我叫張陵窜觉,是天一觀的道長谷炸。 經(jīng)常有香客問我,道長禀挫,這世上最難降的妖魔是什么旬陡? 我笑而不...
    開封第一講書人閱讀 60,097評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮语婴,結(jié)果婚禮上描孟,老公的妹妹穿的比我還像新娘驶睦。我一直安慰自己,他們只是感情好匿醒,可當(dāng)我...
    茶點故事閱讀 69,100評論 6 398
  • 文/花漫 我一把揭開白布场航。 她就那樣靜靜地躺著,像睡著了一般廉羔。 火紅的嫁衣襯著肌膚如雪溉痢。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,696評論 1 312
  • 那天憋他,我揣著相機(jī)與錄音孩饼,去河邊找鬼。 笑死竹挡,一個胖子當(dāng)著我的面吹牛镀娶,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播此迅,決...
    沈念sama閱讀 41,165評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼汽畴,長吁一口氣:“原來是場噩夢啊……” “哼旧巾!你這毒婦竟也來了耸序?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,108評論 0 277
  • 序言:老撾萬榮一對情侶失蹤鲁猩,失蹤者是張志新(化名)和其女友劉穎坎怪,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體廓握,經(jīng)...
    沈念sama閱讀 46,646評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡搅窿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,709評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了隙券。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片男应。...
    茶點故事閱讀 40,861評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖娱仔,靈堂內(nèi)的尸體忽然破棺而出沐飘,到底是詐尸還是另有隱情,我是刑警寧澤牲迫,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布耐朴,位于F島的核電站,受9級特大地震影響盹憎,放射性物質(zhì)發(fā)生泄漏筛峭。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,196評論 3 336
  • 文/蒙蒙 一陪每、第九天 我趴在偏房一處隱蔽的房頂上張望影晓。 院中可真熱鬧镰吵,春花似錦、人聲如沸俯艰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽竹握。三九已至画株,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間啦辐,已是汗流浹背谓传。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留芹关,地道東北人续挟。 一個月前我還...
    沈念sama閱讀 49,287評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像侥衬,于是被迫代替她去往敵國和親诗祸。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,860評論 2 361

推薦閱讀更多精彩內(nèi)容