微服務(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ù)免費閱讀

下載本文檔

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

文檔簡介

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

全鏈路APM監(jiān)控

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

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

下面我們介紹一下如何利用開源APM工具Pinpoint應對上述問題。

拓撲圖

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

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

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

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

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

為了避免雪崩效應,我們可以從兩個方面考慮:

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

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

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

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

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

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

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

緩存熱點。有些熱點數(shù)據(jù)訪問量會特別大,單個緩存節(jié)點(例如Redis)無法支撐這么大的訪問量。如果是讀請求訪問量大,可以考慮讀寫分離,一主多從的方案,用從節(jié)點分攤讀流量;如果是寫請求訪問量大,可以采用集群分片方案,用分片分攤寫流量。以秒殺扣減庫存為例,假如秒殺庫存是100,可以分成5片,每片存20個庫存。

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

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

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

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

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

我們需要一套完善的監(jiān)控系統(tǒng),系統(tǒng)出問題時能夠快速告警,最好是系統(tǒng)出問題前能提前預警。包括系統(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)(源站)的訪問壓力。同時也減少了網(wǎng)站帶寬壓力。對系統(tǒng)穩(wěn)定性非常有好處。

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

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

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

微服

溫馨提示

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

最新文檔

評論

0/150

提交評論