我只是下了個訂單,鬼知道我在微服務裏經歷了什麼

www.icoco.tech/用戶在電商網站中購買成…前端

題目:用戶在電商網站中購買成功了,那麼它在微服務中經歷了什麼?

當我傻啊,用戶在電商網站購買成功,還在微服務中,那確定就是有一套微服務架構的電商系統。java

設計一套電商系統還不簡單mysql

簡單想象一下,既然是一個電商系統,有用戶去購買,就確定得有一個用戶模塊,購買什麼東西總不是西北風吧,購買確定是商品吧,省掉購物車,就得有商品模塊吧,商品總得有庫存吧,庫存就暫時跟商品放一塊兒吧,什麼倉儲物流先別管,就看成是虛擬商品好了,反正題目也沒說不能是虛擬商品^_^,購買成功了,那就必須有訂單吧,加個訂單模塊,下完單總得支付吧,不付錢人家憑什麼把東西給你,那就得有個支付模塊程序員

簡單粗暴,四個模塊

用戶模塊,商品模塊(庫存),訂單模塊,支付模塊redis

image

好,幾個模塊搞定,外加下單流程圖spring

image

  • 等等,貌似題目說是微服務,既然是微服務就涉及到拆分服務的問題

DDD 領域驅動設計

剛剛確實是梳理了一下模塊,既然是微服務,就得進行服務的拆分,服務怎麼進行拆分呢,貌似按照剛次梳理模塊來劃分也是能夠,不過這樣好像顯得我很不是專業,據說如今不少人都要使用DDD(領域驅動設計)來指導微服務的拆分。sql

參考DDD的設計,DDD官方的架構草圖,整體架構分爲四層,Infrastructure(基礎實施層),Domain(領域層),Application(應用層),Interfaces(表示層,也叫用戶界面層或是接口層)docker

微服務結合DDD

不過對於領域設計而言代碼層其實不是最重要,最要的是如何去劃分領域,劃分好邊界。而對於微服務而言,很是適合從業務上去劃分各個Modules,劃分好各個業務板塊,微服務 + DDD,我的以爲首先從微服務的角度考慮去劃分大的業務模塊,每一個微服務都應該是一個能夠獨立部署,各司其職的模塊。簡單的說,在微服務實際的開發中,結合DDD的思想去劃分全部屬於本身的領域。數據庫

實施DDD的關鍵

第一點是使用經過的語言創建全部的聚合,實體,值對象。apache

第二點也就是最關鍵的「建模」

  • 劃分「戰略建模」,從一個種宏觀的角度去審覈整個項目,劃分出「界限上下文」,造成具備上帝視角的「上下文映射圖」

  • 還有一個建模「戰術建模」,在咱們的「戰略建模」劃分出來的「界限上下文」種進行「聚合」,「實體」,「值對象」,並按照模塊分組。

構建咱們電商系統的上下文映射圖

先來肯定咱們的戰略核心的領域是什麼,咱們的目的是什麼,做爲一個電商系統,咱們的核心確定是賣出更多的商品,獲取更多訂單更多的利潤,那麼銷售能夠做爲咱們的一個核心的領域。這個做爲一個明確核心域確立下來。

image
肯定完核心子域後,根據對這個領域的理解劃分出各個上下文,而後根據上下文再肯定其餘的相關領域。

image
初步咱們能夠看出圍繞銷售核心域的包含的幾大塊內容,價格,銷售方式,購買的方式,已經購買。 而後咱們對支撐着核心域的子域也作了劃分,支撐着核心域的有商品域,用戶域,通用域有訂單域,物流域,支付域。

回到咱們的主題,咱們此次沒有購物車,也沒有各個會員銷售價格,把一些上下文拿掉,並創建映射。

image

領域驅動設計看似簡單,其實很難實施,由於在各個環節中都須要對應的領域專家的參加或指導,這樣才能設計出最符合實際的上下文映射圖,並且咱們花費的精力可能相比之後的數據驅動開發模式更多,但在總體對項目的把控性能上說,領域比數據驅動更加抽象,更加的頂層設計,在對應互聯網的多變狀況看得更遠。

咱們將微服務拆分爲5個領域,分別是銷售域,商品域,用戶域,訂單域,支付域。

完美,接下來就能夠開始開發了 ^ _ ^

  • 等等,兵馬未動,糧草先行;代碼未動,圖先行,先把時序圖畫出來

時序圖

一個簡單的下單流程,涵蓋了幾個領域

image

完美,接下來就能夠開發微服務了^ _ ^

  • 等等,微服務的技術棧還未選型

微服務技術棧選型

服務拆分完了,時序圖也畫完了,能夠開始咱們的微服務之旅了,目前主流的微服務有阿里大名鼎鼎的dubbo和Spring-Cloud全家桶,還有新浪的Motan。比較熟悉的仍是dubbo和spring-cloud,也都使用過,究竟應該選用哪個呢?

由於以前都使用過,作點簡單,粗暴的總結。dubbo在很早以前就開始使用,當時的微服務尚未如今這麼火,不少理論體系也未完善,dubbo更像是一套rpc整合框架,spring-cloud則更傾向微服務架構的生態。相比Dubbo,springCloud能夠說是微服務一整套的解決方案,在功能上是dubbo的一個超級。 Dubbo和SpringCloud比喻,Dubbo架構的微服務就像組裝電腦,各個環節自由度很高。springCloud更像品牌機。

基於不折騰,簡單快捷,更傾向選擇spring-cloud,ok,就定下來技術棧使用spring-cloud,愉快的決定。

  • 等等,就這麼草率就決定用spring-cloud作爲微服務,難道不須要把微服務的利弊先弄清楚嗎?

微服務 : 利和弊

既然選擇了微服務,就得知道微服務的利和弊,特別是弊,引入了微服務,就等於引入了一套複雜的體系,一套複雜的體系帶來的各類挑戰必須事先了解清楚。

image

利:

1.強模塊化邊界

咱們知道作軟件架構,軟件設計,模塊化是很是重要的一點,一開始咱們寫程序作軟件,咱們採用類的方式來作模塊化,後面開始採用組件或類庫的方式作模塊化,能夠作到工程上的重用和分享給其餘團隊來使用。微服務在組件的層次上面又高了一層,以服務的方式來作模塊化,每一個團隊獨立開始和維護本身的服務,有明顯的一個邊界,開發完一個服務其餘團隊能夠直接調用這個服務,不須要像組件經過jar或源碼的方式去進行分享,因此微服務的邊界是比較清晰的。

2.可獨立部署
3.技術多樣性

弊(或者說挑戰):

1.分佈式複雜性

在原來單塊應用就是一個應用,一個對單塊應用的架構比較熟悉的人能夠對整個單塊應用有一個很好的把控。可是到了分佈式系統,微服務化了之後可能涉及到的服務有好幾十個,一些大公司可能涉及到的服務上百個,服務與服務之間是經過相互溝通來實現業務,那麼這個時候整個系統就變成很是複雜,通常的開發人員或一個團隊都沒法理解整個系統是如何工做的,這個就是分佈式帶來的複雜性。

2.最終一致性

微服務的數據是分散式治理的,每一個團隊都有本身的數據源和數據拷貝,比方說團隊A有訂單數據,B團隊也有訂單數據,團隊A修改了訂單數據是否應該同步給團隊B的數據呢,這裏就涉及到數據一致性問題,若是沒有很好的解決一致性問題,就可能形成數據的不一致,這個在業務上是不能夠接受的。

3.運維複雜性

以往的運維須要管理的是機器+單塊的應用,分佈式系統和單塊應用不同的是,分佈式系統須要不少的服務,服務與服務之間相互協同,那麼對分佈式系統的資源,容量規劃,對監控,對整個系統的可靠性穩定性都很是具有挑戰的。

只有在清楚瞭解微服務帶來的挑戰,明知道山有虎偏向虎山行,纔可以真正的勝任挑戰,最重要的是,要清楚明瞭裏面有什麼坑,這麼避免踩坑。

完美,已經瞭解微服務帶來的好處和挑戰,接下來就能夠開始開發了 ^ _ ^

  • 等等,微服務尚未作邏輯分層

微服務怎麼作邏輯分層

目前咱們的微服務裏面有幾個服務,分別是訂單,商品,用戶,若是客戶端向查看 「個人訂單」 這麼一個接口, 若是客戶端假定是pc端,就須要請求三次接口,分別對接訂單,商品,用戶三個服務,分別拿完三次調用數據,再將三次調用數據進行整合輸出展現。要知道pc調用後端服務是走外網,這無疑大大增長了網絡的開銷,並且讓pc端變成更爲複雜。假定在中間加多一個層爲聚合服務層,即對網絡開銷進行減小,由於微服務內部是經過內網進行數據傳輸,也讓pc端的業務變得比較簡單。

image

圖中的 「pc聚合服務」 也是一個微服務,只不過它是屬於聚合服務中間層,咱們將爲微服務進行邏輯劃分,分爲2個層:

image

微服務基礎服務層

基礎服務通常屬於互聯網平臺基礎性的支撐服務,比方說,電商網站的基礎服務有訂單服務,商品服務,用戶服務等,這些都屬於比較基礎和原子性,下沉一個公司的基礎設施的低層,向下承接存儲,向上提供業務能力,有些公司叫(基礎服務,中間層服務,公共服務),netflix成爲中間層服務。咱們暫且統稱爲基礎服務。

微服務聚合服務層

已經有了基礎服務能提供業務能力,爲何還須要聚合服務,由於咱們有不一樣的接入端,如app和H5,pc等等,它們看似調用大體相同的數據,但其實存在不少差別,例如PC須要展現更多信息,APP須要作信息裁剪等等。通常低層服務都是比較通用的,基礎服務應該對外輸出相對統一的服務,在抽象上作得比較好。可是對不一樣的外界app和pc的接入,咱們須要做出不一樣的適配,這個時候須要有一個層去作出聚合裁剪的工做。例如一個商品詳情在pc端展現和app端的展現,pc可能會展現更多的信息,而app則須要對信息做出一些裁剪,若是基礎服務直接開放接口給到pc和app,那麼基礎服務也須要去作成各類設配,這個很不利於基礎服務的抽象,因此咱們在基礎層之上加入聚合服務層,這個層能夠針對pc和app作成適當的設配進行相應的裁剪。

那麼咱們的微服務中,又增長了一個服務,屬於聚合服務

image

好了,接下來能夠愉快的coding...

image

  • 等等,貌似不對,若是是單塊應用加上事務應該沒問題,這裏是分佈式,恐怕得考慮加分佈式事務

分佈式事務

咱們來理一理建立訂單和扣件庫存模塊之間的關係

image

能夠發現,由於微服務的緣由,咱們把服務進行了分佈式,隨着各個數據庫也隨着變成分佈式每一個數據庫不必定存在相同的物理機中,那麼這個時候單個數據庫的ACID已經不能適應這種狀況,而在這種集羣中想去保證集羣的ACID幾乎很難達到,或者即便能達到那麼效率和性能會大幅降低,最爲關鍵的是再很難擴展新的分區了,這個時候若是再追求集羣的ACID會致使咱們的系統變得不好,這時咱們就須要引入一個新的理論原則來適應這種集羣的狀況,就是 CAP

CAP定理

CAP 必須知足一下的3個屬性:

  • 一致性(C):在分佈式系統中的全部數據備份,在同一時刻是否一樣的值。(等同於全部節點訪問同一份最新的數據副本)
  • 可用性(A):在集羣中一部分節點故障後,集羣總體是否還能響應客戶端的讀寫請求。(對數據更新具有高可用性)
  • 分區容錯性(P):以實際效果而言,分區至關於對通訊的時限要求。系統若是不能在時限內達成數據一致性,就意味着發生了分區的狀況,必須就當前操做在C和A之間作出選擇。

簡單的來講,在一個分佈式系統中,最多能支持上面的兩種屬性。但顯然既然是分佈式註定咱們是必然要進行分區,既然分區,咱們就沒法百分百避免分區的錯誤。所以,咱們只能在一致性和可用性去做出選擇。

在分佈式系統中,咱們每每追求的是可用性,它的重要性比一致性要高,那麼如何實現高可用,這裏又有一個理論,就是BASE理論,它給CAP理論作了進一步的擴充。

BASE理論

BASE指出:

  • Basically Available(基本可用)
  • Soft state(軟狀態)
  • Eventually consistent(最終一致性)

BASE理論是對CAP中的一致性和可用性進行一個權衡的結果,理論的核心思想就是:咱們沒法作到強一致,但每一個應用均可以根據自身的業務特色,採用適當的方式來使系統達到最終一致性

好了,說了一大頓理論,程序員們都等急了,趕快來看看分佈式事務的解決方案有哪些,能夠進行接下去的coding...

來吧,討論技術方案:

image

幾個方案拿出來了,由於咱們不是專門來說解分佈式事務的機制和原理,主要仍是來作分佈式事務的技術選型。

先排除掉咱們應該不會選擇的方案,一個是XA兩階段提交,這個在不少傳統型公司會被使用,但不適合互聯網微服務的分佈式系統,鎖定資源時間長,性能影響大,排除。

另外一個是ali的GTS並無開源,目前已經開源了fescar,不過目前善缺乏調研,可能在下個階段研究後會使用,目前先排除。

剩下的是TCC和MQ消息事務兩種

MQ消息事務-RocketMQ

先說說MQ的分佈式事務,RocketMq在4.3版本已經正式宣佈支持分佈式事務,在選擇Rokcetmq作分佈式事務請務必選擇4.3以上的版本。

事務消息做爲一種異步確保型事務, 將兩個事務分支經過 MQ 進行異步解耦,RocketMQ 事務消息的設計流程一樣借鑑了兩階段提交理論,總體交互流程以下圖所示:

image

這個時候咱們基本能夠認爲,只有MQ發送方本身的本地事務執行完畢,那麼MQ的訂閱方一定百分百可以接收到消息,咱們再對下單減庫存的步驟進行改造:

這裏涉及到一個異步化的改造,咱們理一下若是是同步流程中的各個步驟

  1. 查看商品詳情(或購物車)
  2. 計算商品價格和目前商品存在庫存(生成訂單詳情)
  3. 商品扣庫存(調用商品庫存服務)
  4. 訂單確認(生成有效訂單)

訂單建立完成後,發佈一個事件「orderCreate」 到消息隊列中,而後由MQ轉發給訂閱該消息的服務,由於是基於消息事務,咱們能夠認爲訂閱該消息的商品模塊是百分百能收到這個消息的。

image

image

商品服務接受到orderCreate消息後就執行扣減庫存的操做,注意⚠️,這裏可能會有一些不可抗的因素致使扣減庫存失敗,不管成功或失敗,商品服務都將發送一個扣減庫存結果的消息「stroeReduce」到消息隊列中,訂單服務會訂閱扣減庫存的結果。

訂單服務收到消息後有兩種可能:

  1. 若是扣減庫存成功,將訂單狀態改成 「確認訂單」 ,下單成功
  2. 若是扣減庫存失敗,將訂單狀態改成 「失效訂單」 ,下單失敗

image

這種模式將確認訂單的流程變成異步化,很是適合在高併發的使用,可是,切記了,這個須要前端用戶體驗的一些改變,要配合產品來涉及流程。

  • 完美,使用MQ分佈式事務就能夠解決調一致性問題
  • 等等,MQ消息事務方案的風險瞭解一下

上面使用MQ的方式確實是能夠完成A和B操做,可是A和B並非嚴格一致性,而是最終一致性,咱們犧牲掉嚴格一致性,換來性能的提高,這種很適合在大促高併發場景總使用,可是若是B一直執行不成功,那麼一致性也會被破壞,後續應該考慮到更多的兜底方案,方案越細系統就將越複雜。

TCC方案

TCC是服務化的二階段變成模型,每一個業務服務都必須實現 try,confirm,calcel三個方法,這三個方式能夠對應到SQL事務中Lock,Commit,Rollback。

1). try階段 try只是一個初步的操做,進行初步的確認,它的主要職責是完成全部業務的檢查,預留業務資源

2). confirm階段 confirm是在try階段檢查執行完畢後,繼續執行的確認操做,必須知足冪等性操做,若是confirm中執行失敗,會有事務協調器觸發不斷的執行,直到知足爲止

3). cancel是取消執行,在try沒經過並釋放掉try階段預留的資源,也必須知足冪等性,跟confirm同樣有可能被不斷執行

接下來看看,咱們的下單扣減庫存的流程怎麼加入TCC

image

在try的時候,會讓庫存服務預留n個庫存給這個訂單使用,讓訂單服務產生一個「未確認」訂單,同時產生這兩個預留的資源, 在confirm的時候,會使用在try預留的資源,在TCC事務機制中認爲,若是在try階段能正常預留的資源,那麼在confirm必定能完整的提交

image

在try的時候,有任務一方爲執行失敗,則會執行cancel的接口操做,將在try階段預留的資源進行釋放。

完美,能夠把咱們的系統引入TCC ^ _ ^

  • 等等,有同窗提問

  • 有同窗可能會問了,若是在confirm或cancel中,有一方的操做失敗了,可能出現異常等狀況該怎麼解決,這個就涉及TCC的事務協調器了,事務協調器就confirm或cancel沒有獲得返回的時候,會啓用定時器不斷的進行confirm或cancel的重試,這個也就是咱們強調,confirm,cancel接口必須是冪等性的一個緣由了

  • 還有同窗會問了,爲何事務協調器知道confirm,或cancel沒有完成,這個就涉及到了TCC也作了一張本地消息表,會記錄一次事務,包括主事務,子事務,事務的完成狀況都會記錄在這種表中(固然未必是表,多是zk,redis等等介質),而後啓用一個定時器去檢查這種表。

  • 還有同窗會問,事務怎麼傳遞,這個就涉及使用的TCC的框架了,通常來講用的都是隱式傳參的方式。在主事務建立的時候用隱式傳參調用子事務,子事務包含try,confirm,cancel都會記錄到事務表裏面。

這裏推薦TCC的開源框架使用mengyun的TCC,而後也能夠其餘的,無所謂。

完美,下單的流程開發完畢了,可讓QA接入 ^ _ ^

  • 等等,微服務的保護措施作了嗎

熔斷限流隔離降級

微服務分佈式依賴關係錯綜複雜,比方說前端的一個請求,這來到後端會被轉爲爲不少個請求,個時候後臺的服務出現不穩定或者延遲,若是沒有好的限流熔斷措施,可能會形成用戶體驗的降低,嚴重的時候會出現雪崩效應,把整個網站給搞垮,若是向阿里巴巴在雙11等活動中,若是沒有一套好的限流熔斷措施,這是不可想象的,多是根本沒法支撐那麼大的併發容量。

netflix在2012年前也沒有設計好的限流容錯,當時也是飽受着系統穩定性的困擾,好幾回網站由於沒有好的熔斷措施把網站搞垮,在2012年netflix啓動了彈性工程項目,其中有一個產品叫hystrix,這個產品主要用來解決微服務的可靠性,有了這個系統以後,netflix在系統穩定性上上了一個大的臺階,在此以後就沒有出現過大規模的雪崩事故

下面使用hystrix也例子來說解一下限流熔斷

幾個概念:

熔斷,隔離,限流,降級,這幾個概念是分佈式容錯最重要的概念和模式。

熔斷

若是說房子裏面安裝了電路熔斷器,當你使用超大功率的電路時,有熔斷設配幫你保護不至於出問題的時候把問題擴大化。

隔離

咱們知道計算資源都是有限的,cpu,內存,隊列,線程池都是資源,他們都是限定的資源數,若是不進行隔離,一個服務的調用可能要消耗不少的線程資源,把其餘服務的資源都給佔用了,那麼可能出現應爲一個服務的問題連帶效應形成其餘服務不能進行訪問。

限流

讓大流量的訪問衝進去咱們的服務時,咱們須要必定的限流措施,比方說咱們規則必定時間內只容許必定的訪問數從咱們的資源過,若是再大的化系統會出現問題,那麼就須要限流保護。

降級

若是說系統後題沒法提供足夠的支撐能力,那麼須要一個降級能力,保護系統不會被進一步惡化,並且能夠對用戶提供比較友好的柔性方案,例如告知用戶暫時沒法訪問,請在一段時候後重試等等。

hystrix

hystrix就把上面說的 熔斷,隔離,限流,降級封裝在這麼一個組件裏面 下圖是hystrix內部設計和調用流程

image

  • 大體的工做流以下:
  1. 構建一個HystrixCommand對象,用於封裝請求,並在構造方法配置請求被執行須要的參數
  2. 執行命令,Hystrix提供了幾種執行命令的方法,比較經常使用到的是synchrous和asynchrous
  3. 判斷電路是否被打開,若是被打開,直接進入fallback方法
  4. 判斷線程池/隊列/信號量是否已經滿,若是滿了,直接進入fallback方法
  5. 執行run方法,通常是HystrixCommand.run(),進入實際的業務調用,執行超時或者執行失敗拋出未提早預計的異常時,直接進入fallback方法
  6. 不管中間走到哪一步都會進行上報metrics,統計出熔斷器的監控指標
  7. fallback方法也分實現和備用的環節
  8. 最後是返回請求響應

完美,把hystrix加入咱們系統吧,這樣忽然有洪峯流量也不至於咱們的系統一下就沖垮 ^ _ ^

  • 等等,hystrix的限流數值,錯誤數熔斷,超時熔斷,嘗試恢復比率這些須要咱們配置的數值應該怎麼定呢?

這個就取決你的系統壓測的指標和你部署的規模了,這裏還涉及到一個容量設計的問題,一會咱們將系統部署上線的時候再來詳細說道。

剛剛提到一個問題,就是這些限流數值,錯誤數熔斷這些數字,咱們如今都寫在配置文件裏面,例如說寫在properties,yml裏面,當有一天忽然須要把限流數下調(多是系統遭受到什麼壓力打擊),那咱們只能把代碼拉下來,巴拉巴拉改了,而後從新上傳打包,發佈重啓,一個流程下來,不說個把小時吧,十來分鐘總少不了吧。

想辦法咱們把這些配置項放到一個集中式配置中心

集中式配置中心

本身寫配種中心還挺麻煩的,去菜市場逛逛吧,菜市場裏面有,springcloud-Config,百度的disconf,阿里的diamond,還有攜程的apollo

基本上他們的原理都差很少,配置中心能夠簡單的理解爲一個服務模塊,開發人員或運維人員能夠經過界面對配種中心進行配置,下面相關的微服務鏈接到配置中心上面就能夠實時鏈接獲取到配置中心上面修改的參數。更新的方式通常有兩種

  • pull模式,服務定時去拉取配置中心的數據
  • push模式,服務一直鏈接到配置中心上,一旦配置有變成,配種中心將把變動的參數推送到對應的微服務上

image

pull 和 push 兩種模式其實各有優缺點。

  • pull通常使用定時器拉取,就算某一個網絡抖動沒有pull成功,在下一次定時器的時候,終將能保證獲取最新的配置。

  • push能夠避免pull定時器存在的延時,基本能夠作到實時獲取數據,但也有問題就是網絡抖動的時候可能會丟失更新。

攜程的apollo

image

攜程的apollo比較有特點的是融合了pull和push兩種模式,把二者的優勢進行告終合,開發或運維人員在配置中心進行修改,配置中心服務將實時將修改推送push到apollo的客戶端,但考慮到可能因爲某些網絡抖動沒有推送成功,客戶端還具有了定時向apollo服務端拉取pull數據的功能,就算推送沒成功,可是隻要必定時間週期,客戶端仍是會主動去拉取同步數據,保證能把最終配置同步到服務中。這個也是apollo在高可用方面上很是有特點的設計。

apollp在高可用上也作了保證,客戶端獲取到數據會把數據緩存在內存,還會sync到本地磁盤,就算apollo服務器掛掉了,就算客戶端服務重啓了,也能夠從本地磁盤中拉取回來數據,繼續提供對外服務,從這點來看apollo的配置中心在高可用上考慮仍是比較周到的。

把配置中心配置上去後,咱們就能夠把hystrix還有mysql的用戶密碼,還有一些業務開關等等的配置參數放上去了。

完美,開發基本完工了,其實就幾個模塊,一個簡單的下單購物流程,當咱們把系統交付給運維,運維喊道,日誌呢,作微服務怎麼能夠沒有調用鏈日誌呢?

調用鏈監控&日誌

確實,微服務是一個分佈式很是複雜系統,若是沒有一套調用鏈監控,若是服務之間依賴出現問題就很難進行定位。

下圖是ali在鷹眼系統給出的微服務之「熵」

image

目前個大主流互聯網公司中,ali有很是出現的鷹眼系統,點評也有一套很出名的調用鏈監控系統CAT。調用鏈監控其實最先是google提出來的,2010年google發表了一篇調用鏈的論文,論文以它內部的調用鏈系統dapper命名,這個論文中講解調用鏈在google使用的經驗和原理,大體的原理以下圖:

image

這裏能夠採用ELK的方式去記錄和展現調用鏈監控日誌,當咱們一條調用爲一行記錄存儲下來

image

經過traceId 和 parentSpanId 就能夠串聯起來爲一個總體的鏈路,並能夠從這個鏈路去分析錯誤或者調用延時和調用次數等等

image

目前市面主流的調用鏈選型有 zipkin,pinpoint,cat,skywalking,他們之間各有一些偏重點,值得一說的是skywalking國人出品的一款新的調用鏈工具,採用開源的基於字節碼注入的調用鏈分析,接入段無代碼入侵,並且開源支持多種插件,UI在幾款工具來講比較功能比較強大,並且ui也比較賞心悅目,目前已經加入了apache孵化器。

採用了skywalking做爲調用鏈工具

爲什麼會採用skywaling,在低層原理的實現,這幾款產品都差很少,但在實現和使用的細節相別仍是很大。

  • 首先在實現方式上,skywalking基本對於代碼作到了無入侵,採用java探針和字節碼加強的方式,而在cat還採用了代碼埋點,而zipkin採用了攔截請求,pinpoint也是使用java探針和字節碼加強。
  • 其次在分析的顆粒度上,skywaling是方法級,而zipkin是接口級,其餘兩款也是方法級。
  • 在數據存儲上,skywalking能夠採用日誌體系中比較出名的ES,其餘幾款,zipkin也可使用ES,pinpoint使用Hbase,cat使用mysql或HDFS,相對複雜,因爲目前公司對ES熟悉的人才比較有保證,選擇熟悉存儲方案也是考慮技術選型的重點。
  • 還有就是性能影響,根據網上的一些性能報告,雖然未必百分百準備,但也具有參考價值,skywalking的探針對吞吐量的影響在4者中間是最效的,通過對skywalking的一些壓測也大體證實。

完美,把微服務的包打好,上傳到服務器就能夠運行了 ^ _ ^

  • 等等,微服務包都打好了,剩下就是jar包或war包一個一個上傳到服務器上,而後用個腳本start,在之前單塊應用還好,如今微服務幾十幾百個應用,請問,運營人員怕不怕?

據說,docker + kubernetes和微服務更配喔

docker + kubernetes

就幾個服務,先不用容器化部署了...乍一看,沒玩沒了,還有CICD,灰度發佈...容器編排...

下次再講把,先把服務部署上去吧

部署到生產,預估容量

該把服務部署上線了,一個服務上線確定得評估下或者預估下訪問量有多少用戶,有多少訪問,這個涉及到該配置多少的機器資源,這應該怎麼去估算呢,反正程序員在家裏怎麼算都算不出來。

評估訪問量
  1. 問運營,若是是一個已經上線的產品,確定存在已有的用戶數和訪問數據,就算存在誤差,也是可控的範圍。
  2. 問產品,肯定一個什麼樣形態的產品,例如是拼團,例如是秒殺,各類處理方式都不一樣
評估平均訪問量qps

一天86400秒,通常認爲請求大部分發生在白天,就按照40000計算,日平均訪問量=日總訪問量/40000

評估高峯qps

能夠把以前每日的訪問曲線圖拉出來看看,峯值是根據業務不一樣而定的,例如,有些業務是白天早上10點的流量偏多,有些業務是晚上人家休閒類的流量偏多,總之,根據業務去估算出日均的峯值,相似於電商類的服務,通常峯值是日均流量的5倍左右。還有例如一些大促活動可能會更高,這個都要跟運營人員提早溝通好的,還有一些活動例如,秒殺,這個就不是靠預估出來,秒殺是另外一種的考慮狀況,採起的應對策略跟普通訂單是徹底不一樣。

評估系統,單機極限qps

在上線以前須要跟測試人員一塊兒作壓力測試,針對每一個服務每臺機器去作,通常來講,會把一個服務一臺機器壓到極限,在逐步的進行優化。 思考一個問題,假定單臺機器最大的qps是1000,咱們峯值是5000,那須要用多少臺機器去抗?答案是大於等於6臺,最少的容錯不得少於1臺。


貌似一個很是簡單的微服務就差很少,不過貌似仍是差了不少,數一下:

  1. 監控系統哪去了:(基礎設施監控,系統監控,應用監控,業務監控)
  2. 網關哪裏去了
  3. 統一的異常處理哪裏去了
  4. API文檔哪裏去了
  5. 容器化哪裏去了
  6. 服務編排哪裏去了
  7. ...
相關文章
相關標籤/搜索