微服務(wù)系統(tǒng)功能總結(jié)_第1頁
微服務(wù)系統(tǒng)功能總結(jié)_第2頁
微服務(wù)系統(tǒng)功能總結(jié)_第3頁
微服務(wù)系統(tǒng)功能總結(jié)_第4頁
微服務(wù)系統(tǒng)功能總結(jié)_第5頁
已閱讀5頁,還剩5頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

微服務(wù)系統(tǒng)功能總結(jié)第1篇微服務(wù)系統(tǒng)功能總結(jié)第1篇微服務(wù),從本質(zhì)意義上看,還是SOA架構(gòu)。但內(nèi)涵有所不同,微服務(wù)并不綁定某種特殊的技術(shù),在一個(gè)微服務(wù)的系統(tǒng)中,可以有Java編寫的服務(wù),也可以有Python編寫的服務(wù),他們是靠Restful架構(gòu)風(fēng)格統(tǒng)一成一個(gè)系統(tǒng)的。

最粗淺的理解就是將微服務(wù)之間的交互看作是各種字符串的傳遞,各種語言都可以很好的處理字符串,所以微服務(wù)本身與具體技術(shù)實(shí)現(xiàn)無關(guān),擴(kuò)展性強(qiáng)。另一個(gè)不同是微服務(wù)架構(gòu)本身很輕,底層也有類似于SOA的總線,不過非常輕薄,現(xiàn)在看到的就兩種方式:MQ和HTTP,而HTTP都不能完全等同于總線,而僅僅是個(gè)信息通道。

所以,基于這種簡單的的協(xié)議規(guī)范,無論是兼容老舊系統(tǒng),還是上線新業(yè)務(wù),都可以隨著時(shí)代的步伐,滾動(dòng)升級(jí)。比如:你去年還在使用.NET技術(shù),今年就可以平滑的過度到Go了,而且系統(tǒng)已有服務(wù)不用改動(dòng)。所以微服務(wù)架構(gòu),既保護(hù)用戶已有投資,又很容易向新技術(shù)演進(jìn)。

微服務(wù)系統(tǒng)功能總結(jié)第2篇老庫和新庫同時(shí)寫入,然后將老數(shù)據(jù)批量遷移到新庫,最后流量切換到新庫并關(guān)閉老庫讀寫。

這種方式適合數(shù)據(jù)結(jié)構(gòu)發(fā)生變化,不允許停機(jī)遷移的場景。一般發(fā)生在系統(tǒng)重構(gòu)時(shí),數(shù)據(jù)結(jié)構(gòu)會(huì)發(fā)生變化,如表結(jié)構(gòu)改變或者分庫分表等場景。有些大型互聯(lián)網(wǎng)系統(tǒng),平常并發(fā)量很高,即便是空閑時(shí)段也有相當(dāng)?shù)脑L問量。幾分鐘的停機(jī)時(shí)間,對(duì)用戶也會(huì)有明顯的影響,甚至導(dǎo)致一定的用戶流失,這對(duì)業(yè)務(wù)方來說是無法接受的。所以我們需要考慮一種用戶無感知的不停機(jī)遷移方案,不停機(jī)遷移不需要保證老數(shù)據(jù)的正確遷移同時(shí)也要保證新數(shù)據(jù)的寫入。

以筆者之前經(jīng)歷的用戶系統(tǒng)重構(gòu)為例,聊一下具體方案。當(dāng)時(shí)的場景是這樣的,用戶表記錄數(shù)達(dá)到3000萬時(shí),系統(tǒng)性能和可維護(hù)性變差,于是我們將用戶中心從單體工程中拆分出來并做了重構(gòu),重新設(shè)計(jì)了表結(jié)構(gòu),而且業(yè)務(wù)方要求不停機(jī)上線!就需要注意下面是我們當(dāng)時(shí)的方案,步驟如下:

代碼準(zhǔn)備。在服務(wù)層對(duì)用戶表進(jìn)行增刪改的地方,要同時(shí)操作新庫和老庫,需要修改相應(yīng)的代碼(同時(shí)寫新庫和老庫)。準(zhǔn)備遷移程序腳本,用于做老數(shù)據(jù)遷移。準(zhǔn)備校驗(yàn)程序腳本,用于校驗(yàn)新庫和老庫的數(shù)據(jù)是否一致。

對(duì)于第一種微服務(wù)場景,新庫可以是一個(gè)單獨(dú)的數(shù)據(jù)庫,對(duì)于第二種場景新庫就是一個(gè)已經(jīng)搭建好具備分片功能的數(shù)據(jù)庫。

開啟雙寫,老庫和新庫同時(shí)寫入。注意:任何對(duì)數(shù)據(jù)庫的增刪改都要雙寫;對(duì)于更新操作,如果新庫沒有相關(guān)記錄,需要先從老庫查出記錄,將更新后的記錄寫入新庫,如果新庫有記錄則新庫老庫一起更新;對(duì)于刪除操作,如果新庫沒有數(shù)據(jù)則刪除老庫數(shù)據(jù)即可,如果新庫有數(shù)據(jù)則新庫老庫一起刪除。對(duì)于新增操作則保證新庫和老庫都新增成功。為了保證寫入性能,老庫寫完后,可以采用消息隊(duì)列異步寫入新庫。注意:雙寫的操作,需要保證數(shù)據(jù)的id(主鍵也要相同),比如老庫新增老一條id為100的數(shù)據(jù),那么在新庫中這條數(shù)據(jù)的id(主鍵)也是100。

利用腳本程序,將某一時(shí)間戳之前的老數(shù)據(jù)遷移到新庫。注意:1,時(shí)間戳一定要選擇開啟雙寫后的時(shí)間點(diǎn)(比如開啟雙寫后10分鐘的時(shí)間點(diǎn)),避免部分老數(shù)據(jù)被漏掉;2,遷移過程遇到記錄沖突直接忽略,產(chǎn)生沖突的原因可能是遷移遷移之前老庫的數(shù)據(jù)已經(jīng)存在于新庫了(存在主鍵沖突的時(shí)間段就是雙寫開始時(shí)間到遷移老數(shù)據(jù)開始時(shí)間,這段時(shí)間新庫已經(jīng)存在了老庫的一些數(shù)據(jù)),當(dāng)遷移操作開始后在往新庫插入相同數(shù)據(jù)將會(huì)報(bào)主鍵沖突等問題;3,遷移過程一定要記錄日志,尤其是錯(cuò)誤日志,如果有雙寫失敗的情況,我們可以通過日志恢復(fù)數(shù)據(jù),以此來保證新老庫的數(shù)據(jù)一致。4.老表遷移到新表的數(shù)據(jù)的主鍵Id也一定要一致,比如老表的數(shù)據(jù)Id為100,那么這條數(shù)據(jù)遷移到新表的id也應(yīng)該為100

第3步完成后,我們還需要通過腳本程序檢驗(yàn)數(shù)據(jù),看新庫數(shù)據(jù)是否準(zhǔn)確以及有沒有漏掉的數(shù)據(jù)對(duì)比辦法:讀取所有字段,根據(jù)字段名稱+字段值進(jìn)行拼接,拼接MD5是否相同,相同則不追究,不相同用原表進(jìn)行覆蓋

數(shù)據(jù)校驗(yàn)沒問題后,開啟雙讀,起初給新庫放少部分流量,新庫和老庫同時(shí)讀取。由于延時(shí)問題,新庫和老庫可能會(huì)有少量數(shù)據(jù)記錄不一致的情況,所以新庫讀不到時(shí)需要再讀一遍老庫。逐步將讀流量切到新庫,相當(dāng)于灰度上線的過程。遇到問題可以及時(shí)把流量切回老庫

讀流量全部切到新庫后,關(guān)閉老庫寫入(可以在代碼里加上熱配置開關(guān)),只寫新庫

遷移完成,后續(xù)可以去掉雙寫雙讀相關(guān)無用代碼。

切回單寫及數(shù)據(jù)表rename當(dāng)切換的新表和老表屬于同一個(gè)庫時(shí),這里最好進(jìn)行rename操作,也就是新表rename成老表。好處:如果老表的數(shù)據(jù)來自上游寫入,那么我只需要將新表rename為老表即可,上游表對(duì)應(yīng)不需要更新了。壞處:這個(gè)操作需要dba進(jìn)行,且rename期間服務(wù)不可用

目前各云服務(wù)平臺(tái)也提供數(shù)據(jù)遷移解決方案,大家有興趣也可以了解一下!

全鏈路APM監(jiān)控

在體會(huì)到微服務(wù)帶來好處的同時(shí),很多公司也會(huì)明顯感受到微服務(wù)化后那些讓人頭疼的問題。比如,服務(wù)化之后調(diào)用鏈路變長,排查性能問題可能要跨多個(gè)服務(wù),定位問題更加困難;服務(wù)變多,服務(wù)間調(diào)用關(guān)系錯(cuò)綜復(fù)雜,以至于很多工程師不清楚服務(wù)間的依賴和調(diào)用關(guān)系,之后的系統(tǒng)維護(hù)過程也會(huì)更加艱巨。諸如此類的問題還很多!

這時(shí)就迫切需要一個(gè)工具幫我們解決這些問題,于是APM全鏈路監(jiān)控工具就應(yīng)運(yùn)而生了。有開源的Pinpoint、Skywalking等,也有收費(fèi)的Saas服務(wù)聽云、OneAPM等。有些實(shí)力雄厚的公司也會(huì)自研APM。

下面我們介紹一下如何利用開源APM工具Pinpoint應(yīng)對(duì)上述問題。

拓?fù)鋱D

微服務(wù)化后,服務(wù)數(shù)量變多,服務(wù)間調(diào)用關(guān)系也變得更復(fù)雜,以至于很多工程師不清楚服務(wù)間的依賴和調(diào)用關(guān)系,給系統(tǒng)維護(hù)帶來很多困難。通過拓?fù)鋱D我們可以清晰地看到服務(wù)與服務(wù),服務(wù)與數(shù)據(jù)庫,服務(wù)與緩存中間件的調(diào)用和依賴關(guān)系。對(duì)服務(wù)關(guān)系了如指掌之后,也可以避免服務(wù)間循依賴、循環(huán)調(diào)用的問題。

請(qǐng)求調(diào)用棧(CallStack)監(jiān)控

微服務(wù)系統(tǒng)功能總結(jié)第3篇互聯(lián)網(wǎng)系統(tǒng)為大量的C端用戶提供服務(wù),如果隔三差五的出問題宕機(jī),會(huì)嚴(yán)重影響用戶體驗(yàn),甚至導(dǎo)致用戶流失。所以穩(wěn)定性對(duì)互聯(lián)網(wǎng)系統(tǒng)非常重要!接下來筆者根據(jù)自己的實(shí)際經(jīng)驗(yàn)來聊聊基于微服務(wù)的互聯(lián)網(wǎng)系統(tǒng)的穩(wěn)定性。

微服務(wù)化后,服務(wù)變多,調(diào)用鏈路變長,如果一個(gè)調(diào)用鏈上某個(gè)服務(wù)節(jié)點(diǎn)出問題,很可能引發(fā)整個(gè)調(diào)用鏈路崩潰,也就是所謂的雪崩效應(yīng)。

舉個(gè)例子,詳細(xì)理解一下雪崩。如上圖,現(xiàn)在有A,B,C三個(gè)服務(wù),A調(diào)B,B調(diào)C。假如C發(fā)生故障,B方法1調(diào)用C方法1的請(qǐng)求不能及時(shí)返回,B的線程會(huì)發(fā)生阻塞等待。B會(huì)在一定時(shí)間后因?yàn)榫€程阻塞耗盡線程池所有線程,這時(shí)B就會(huì)無法響應(yīng)A的請(qǐng)求。A調(diào)用B的請(qǐng)求不能及時(shí)返回,A的線程池線程資源也會(huì)逐漸被耗盡,最終A也無法對(duì)外提供服務(wù)。這樣就引發(fā)了連鎖故障,發(fā)生了雪崩??v向:C故障引發(fā)B故障,B故障引發(fā)A故障,最終發(fā)生連鎖故障。橫向:方法1出問題,導(dǎo)致線程阻塞,進(jìn)而線程池線程資源耗盡,最終服務(wù)內(nèi)所有方法都無法訪問,這就是“線程池污染”

為了避免雪崩效應(yīng),我們可以從兩個(gè)方面考慮:

常用開源熔斷隔離組件:Hystrix,Resilience4j

促銷活動(dòng)或秒殺時(shí),訪問量往往會(huì)猛增數(shù)倍。技術(shù)團(tuán)隊(duì)在活動(dòng)開始前一般都會(huì)根據(jù)預(yù)估訪問量適當(dāng)增加節(jié)點(diǎn),但是假如流量預(yù)估少了(實(shí)際訪問量遠(yuǎn)大于預(yù)估的訪問量),系統(tǒng)就可能會(huì)被壓垮。所以我們可以在網(wǎng)關(guān)層(Zuul,Gateway,Nginx等)做限流,如果訪問量超出系統(tǒng)承載能力,就按照一定策略拋棄超出閾值的訪問請(qǐng)求(也要注意用戶體驗(yàn),可以給用戶返回一個(gè)友好的頁面提示)。

可以從全局,IP,userID等多維度做限流。限流的兩個(gè)主要目的:1,應(yīng)對(duì)突發(fā)流量,避免系統(tǒng)被壓垮(全局限流和IP限流)2,防刷,防止機(jī)器人腳本等頻繁調(diào)用服務(wù)(userID限流和IP限流)

在核心鏈路上,服務(wù)可以冗余它依賴的服務(wù)的數(shù)據(jù),依賴的服務(wù)故障時(shí),服務(wù)盡量做到自保。比如訂單服務(wù)依賴庫存服務(wù)。我們可以在訂單服務(wù)冗余庫存數(shù)據(jù)(注意控制合理的安全庫存,防超賣)。下單減庫存時(shí),如果庫存服務(wù)掛了,我們可以直接從訂單服務(wù)取庫存??梢越Y(jié)合熔斷一起使用,作為熔斷的Fallback(后備)方案。

可能很多人都聽過服務(wù)降級(jí),但是又不知道降級(jí)是怎么回事。實(shí)際上,上面說的熔斷,限流,數(shù)據(jù)冗余,都屬于服務(wù)降級(jí)的范疇。還有手動(dòng)降級(jí)的例子,比如大促期間我們會(huì)關(guān)掉第三方物流接口,頁面上也關(guān)掉物流查詢功能,避免拖垮自己的服務(wù)。這種降級(jí)的例子很多。不管什么降級(jí)方式,目的都是讓系統(tǒng)可用性更高,容錯(cuò)能力更強(qiáng),更穩(wěn)定。關(guān)于服務(wù)降級(jí)詳見本文后面的內(nèi)容。

緩存穿透。對(duì)于數(shù)據(jù)庫中根本不存在的值,請(qǐng)求緩存時(shí)要在緩存記錄一個(gè)空值,避免每次請(qǐng)求都打到數(shù)據(jù)庫

緩存雪崩。在某一時(shí)間緩存數(shù)據(jù)集中失效,導(dǎo)致大量請(qǐng)求穿透到數(shù)據(jù)庫,將數(shù)據(jù)庫壓垮??梢栽诔跏蓟瘮?shù)據(jù)時(shí),差異化各個(gè)key的緩存失效時(shí)間,失效時(shí)間=一個(gè)較大的固定值+較小的隨機(jī)值

緩存熱點(diǎn)。有些熱點(diǎn)數(shù)據(jù)訪問量會(huì)特別大,單個(gè)緩存節(jié)點(diǎn)(例如Redis)無法支撐這么大的訪問量。如果是讀請(qǐng)求訪問量大,可以考慮讀寫分離,一主多從的方案,用從節(jié)點(diǎn)分?jǐn)傋x流量;如果是寫請(qǐng)求訪問量大,可以采用集群分片方案,用分片分?jǐn)倢懥髁俊R悦霘⒖蹨p庫存為例,假如秒殺庫存是100,可以分成5片,每片存20個(gè)庫存。

部署隔離:我們經(jīng)常會(huì)遇到秒殺業(yè)務(wù)和日常業(yè)務(wù)依賴同一個(gè)服務(wù),以及C端服務(wù)和內(nèi)部運(yùn)營系統(tǒng)依賴同一個(gè)服務(wù)的情況,比如說都依賴訂單服務(wù)。而秒殺系統(tǒng)的瞬間訪問量很高,可能會(huì)對(duì)服務(wù)帶來巨大的壓力,甚至壓垮服務(wù)。內(nèi)部運(yùn)營系統(tǒng)也經(jīng)常有批量數(shù)據(jù)導(dǎo)出的操作,同樣會(huì)給服務(wù)帶來一定的壓力。這些都是不穩(wěn)定因素。所以我們可以將這些共同依賴的服務(wù)分組部署,不同的分組服務(wù)于不同的業(yè)務(wù),避免相互干擾。

數(shù)據(jù)隔離:極端情況下還需要緩存隔離,數(shù)據(jù)庫隔離。以秒殺為例,庫存和訂單的緩存(Redis)和數(shù)據(jù)庫需要單獨(dú)部署!數(shù)據(jù)隔離后,秒殺訂單和日常訂單不在相同的數(shù)據(jù)庫,之后的訂單查詢?cè)趺凑故??可以采用相?yīng)的數(shù)據(jù)同步策略。比如,在創(chuàng)建秒殺訂單后發(fā)消息到消息隊(duì)列,日常訂單服務(wù)收到消息后將訂單寫入日常訂單庫。注意,要考慮數(shù)據(jù)的一致性,可以使用事務(wù)型消息。

業(yè)務(wù)隔離:還是以秒殺為例。從業(yè)務(wù)上把秒殺和日常的售賣區(qū)分開來,把秒殺做為營銷活動(dòng),要參與秒殺的商品需要提前報(bào)名參加活動(dòng),這樣我們就能提前知道哪些商家哪些商品要參與秒殺,可以根據(jù)提報(bào)的商品提前生成商品詳情靜態(tài)頁面并上傳到CDN預(yù)熱,提報(bào)的商品庫存也需要提前預(yù)熱,可以將商品庫存在活動(dòng)開始前預(yù)熱到Redis,避免秒殺開始后大量訪問穿透到數(shù)據(jù)庫。

CI測(cè)試,持續(xù)集成測(cè)試,在我們每次提交代碼到發(fā)布分支前自動(dòng)構(gòu)建項(xiàng)目并執(zhí)行所有測(cè)試用例,如果有測(cè)試用例執(zhí)行失敗,拒絕將代碼合并到發(fā)布分支,本次集成失敗。CI測(cè)試可以保證上線質(zhì)量,適用于用例不會(huì)經(jīng)常變化的穩(wěn)定業(yè)務(wù)。

性能測(cè)試,為了保證上線性能,所有用戶側(cè)功能需要進(jìn)行性能測(cè)試。上線前要保證性能測(cè)試通過。而且要定期做全鏈路壓測(cè),有性能問題可以及時(shí)發(fā)現(xiàn)。

我們需要一套完善的監(jiān)控系統(tǒng),系統(tǒng)出問題時(shí)能夠快速告警,最好是系統(tǒng)出問題前能提前預(yù)警。包括系統(tǒng)監(jiān)控(CPU,內(nèi)存,網(wǎng)絡(luò)IO,帶寬等監(jiān)控),數(shù)據(jù)庫監(jiān)控(QPS,TPS,慢查詢,大結(jié)果集等監(jiān)控),緩存中間件監(jiān)控(如Redis),JVM監(jiān)控(堆內(nèi)存,GC,線程等監(jiān)控),全鏈路監(jiān)控(pinpoint,skywaking,cat等),各種接口監(jiān)控(QPS,TPS等)

可以充分利用CDN。除了提高用戶訪問速度之外,頁面靜態(tài)化之后存放到CDN,用CDN扛流量,可以大幅減少系統(tǒng)(源站)的訪問壓力。同時(shí)也減少了網(wǎng)站帶寬壓力。對(duì)系統(tǒng)穩(wěn)定性非常有好處。

除了服務(wù)要多點(diǎn)部署外,網(wǎng)關(guān),數(shù)據(jù)庫,緩存也要避免單點(diǎn)問題,至少要有一個(gè)Backup,而且要可以自動(dòng)發(fā)現(xiàn)上線節(jié)點(diǎn)和自動(dòng)摘除下線和故障節(jié)點(diǎn)。

避免帶寬成為瓶頸,促銷和秒殺開始前提前申請(qǐng)帶寬。不光要考慮外網(wǎng)帶寬,還要考慮內(nèi)網(wǎng)帶寬,有些舊服務(wù)器網(wǎng)口是千兆網(wǎng)口,訪問量高時(shí)很可能會(huì)打滿。

此外,一套完善的灰度發(fā)布系統(tǒng),可以讓上線更加平滑,避免上線大面積故障。DevOps工具,CI,CD對(duì)系統(tǒng)穩(wěn)定性也有很大意義。

微服

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論