2020年無疑是特別的,我們在不平凡的這一年,經(jīng)歷著開局的艱難,以及隨之而來的各種變化和沖擊。好在,我們終于可以跟充滿問號的2020年說“再見”啦。
從云技術發(fā)展來看,2020隨著企業(yè)上云旅程的深入和數(shù)字化轉型的加快,“云原生”這個詞開始頻繁出現(xiàn)在我們耳邊。什么是云原生?如何開發(fā)云原生應用?會涉及哪些云服務?又能給企業(yè)帶來什么價值?值此新年之際,我們一起定個新年新目標:打造自己的首個云原生應用!
云原生系列內容預計分為五個章節(jié),內容涉及云原生應用初識,將Spring Cloud服務升級為Kubernetes,云原生應用的流量治理,微軟云容器服務AKS詳解,基于多種云原生應用的服務區(qū)別和使用場景介紹。
本篇,我們先和大家一起談談云原生應用是什么,以及如何成為合格的云原生應用公民。
作為云方案架構師,我們經(jīng)常遇到一些客戶抱怨:“我們系統(tǒng)上云了,之前的問題感覺并沒減少,并且還遇到新出現(xiàn)的問題,感覺上云就是一個大坑”。
造成這種情況的原因很多,可能無法一一列舉,但成功的案例確有遵守著一些準則。云原生對應用架構最大的影響是服務不應該僅僅止步于云化。如果僅將服務遷移上云,而對服務本身的架構沒有進行云化適配改造,那么服務上云的收益就無法最大化。云原生應用架構的訴求是最大程度利用云基礎設施的優(yōu)勢,且應用自身架構也要升級。希望通過以下分享,能為大家構建成功的云原生應用提供參考,同時對已經(jīng)在云上運行,但遇到問題的童鞋提供明確方向,了解應該在哪方面改進或優(yōu)化。
何為云原生?
“所謂云原生應用,就是完全基于云計算資源而設計的應用,即為云而生,并可在所有云平臺上無縫移植運行的應用?!?/span>
——Pivotal公司的Matt Stine于2013年
云原生化的路線圖中包括如下技術棧:
根據(jù)CNCF對云原生的定義,云原生技術是通過一系列軟件、規(guī)范和標準,幫助企業(yè)和組織在現(xiàn)代化云計算架構體系(公有云、私有云和混合云)中構建和運行敏捷、可擴展應用程序的一整套技術棧。根據(jù)這個定義,對上述十點,在實踐經(jīng)驗進行總結簡化的話,可以歸納為如下四點:
容器及其編排引擎
微服務及其治理
聲明式API等都是極具代表性的云原生技術
DevOps
CNCF同時也提供了一些對應技術棧和供應商的全景圖,主要幫助大家在選擇技術和服務的時候提供一些參考和推薦。如下:
上述全景圖將CNCF定義的云原生生態(tài)圈劃分為“五橫兩縱”。
“五橫”
1)應用定義與開發(fā);
2)編排與治理;
3)運行時;
4)應保障;
5)基礎設施;
“兩縱”
1)PASS平臺;
2)監(jiān)控觀察與分析;
全景圖中包含經(jīng)過CNCF社區(qū)認證的較為成熟或使用范圍較廣、具有最佳實踐的產品和方案,試圖從云原生的層次結構及不同的功能組成上讓用戶了解云原生體系的全貌,并幫助用戶在不同的云原生應用實踐環(huán)節(jié)選擇恰當?shù)能浖凸ぞ邅韺崿F(xiàn)。
微軟云作為其中的一員,對各個部分也提供了自己的組件:
上述內容相信能讓大家對云原生實施步驟和技術棧有更清晰的認識。大家可對照這些步驟和技術,檢查已有應用架構,看自己的應用在哪些方面有所欠缺,做相應的補足和加強,讓自己的應用成為合格的云原生應用。
合理微服務化
大家在日常生活中都會聽到“微服務”這個詞,但它并沒有出現(xiàn)云原生的路線圖十條范圍內。其實微服務是云原生應用的前提和基礎,無論基于成本還是效率等考慮都要先微服務化。缺乏有效的微服務化,云原生的很多能力都是空談。
沒有進行合理微服務化的服務,可以稱為單體應用或巨石應用,在彈性擴展的時候需要消耗更多資源,同時涉及的業(yè)務也可能過于復雜等等。
服務可從三個維度進行擴展:
X軸:一個變成多個(水平擴展,通過負載均衡來實現(xiàn)選擇)
Y軸:根據(jù)業(yè)務模塊來拆分(垂直拆分擴展,實現(xiàn)微服務化)
Z軸:數(shù)據(jù)拆分(通過數(shù)據(jù)分區(qū),分庫分表來實現(xiàn)對熱點數(shù)據(jù)和服務的進一步拆分)
上面提到一個詞,就是合理微服務化。微服務化怎么做到合理呢?
大家都知道,典型的四件套LAMP(Linux、Apache、MySQL、PHP)在項目初期通常就采用這類單體架構。在項目初始階段,這種架構的性價比是非常高的,開發(fā)速度快、成本低,一臺廉價服務器就能跑起來。單體架構也會帶來很多問題,例如項目復雜性高,模塊組件邊界模糊、依賴不清;擴展能力有限,不能按需伸縮,只能以整體方式進行擴展。
受所使用的技術平臺和語言限制,單體架構通常是技術創(chuàng)新的絆腳石,很難在單體架構上進行應用創(chuàng)新;隨著系統(tǒng)功能和開發(fā)人員的增加,單體架構積累的技術債務會越來越多。因此單體架構越來越被詬病,慢慢選擇微服務的方式來開發(fā)和運維。
微服務到底要做到多“微”才算合理,是不是把服務拆得越細越好?
先看看這個光譜圖:
理論上我們在Y軸業(yè)務模塊上,把功能拆成一個個function單元,在Z軸上把數(shù)據(jù)讓沒一條記錄放在一個庫一個表里面,顯然從成本和運維的角度來考量是不現(xiàn)實的。
所以要有一套方法來指導我們拆分,這就是領域驅動設計(Domain Driver Design)。領域驅動設計的核心是設計出一套核心的領域模型(Domain Model)還表達和承載業(yè)務。
領域(Domain):為了執(zhí)行用戶的某項活動,或是滿足用戶的某種需求。這些用戶應用軟件的問題區(qū)域就是軟件的領域。
模型(Model):模型是一種簡化。它是對現(xiàn)實的解釋——把與解決問題密切相關的方面抽象出來,而忽略無關的細節(jié)。
領域模型(Domain Model):為設計人員,開發(fā)人員和用戶使用一種公共語言,使得所有團隊成員可以使用這些術語來討論模型和設計決策。
比如我們討論去哪里的時候,這是一個出行問題,是我們現(xiàn)在的領域。模型在這里可以認為是地圖,如果要建立合適的領域模型,我們可以借助地圖來框定出行的范圍。如果從上海到美國拉斯維加斯,我們可能要引入航空公司、航班以及中轉站等。而如果從上海到南京,可能要引入高鐵、長途汽車等;而如果要從上海公司地址到附近地鐵站的話,就只需要共享單車或步行等方式了。
確定了這些術語之后,我們再結合地圖來闡述出行方式,這樣問路人和指路人就能很好的溝通,而且是一個可行方案。
在實際場景中,就是識別出一個個問題的上下文,基于這個上下文確定模型,然后通過模型來闡述一個個業(yè)務場景。
在微服務的定義里,早期也有個比較形象的理論:一個微服務的開發(fā)負責人,一個披薩就可以吃飽,具體下來就是一個微服務可能只需要三四個人來開發(fā)。通過這種比較小的團隊也可以和業(yè)務和用戶快速溝通。
通過上述方法和介紹,大家可以結合自己的業(yè)務和團隊去思考如何合理拆分服務,最后形成高效的開發(fā)運維方式,輸出更多的業(yè)務價值。
有了云原生和微服務的介紹,相信大家會有一些概念,有想把已有系統(tǒng)改造的念頭和沖動。在動手之前,還有一些重要因素需要注意。
1.服務流量
由于服務拆分后,服務間的調用變得更復雜,同時調用也分成服務集群外來調用(稱為外部流量或南北流量)以及系統(tǒng)內部之間的調用(稱為內部流量或東西流量)。
由于每個服務對業(yè)務重要性可能不同,為了更好地保證穩(wěn)定性和核心功能可用性,在微服務中,一般用限流、熔斷降級和故障模擬三種方式來應對和測試。
限流很好理解,一般就是在南北流量入口,類似網(wǎng)關的地方做流量限制配置,操作一定數(shù)之后,就直接拒絕,保證進入系統(tǒng)的流量是一個預計和可控的。
限流一般有三種算法:
計數(shù)器:單位時間內,累計到達一定數(shù)量,后面的請求全部拒絕。
漏桶:通過隊列保存請求,通過線程池從隊列中獲取請求,一次性獲取多個并發(fā)執(zhí)行。
令牌桶:通過隊列用來保存令牌,通過一個線程池定期生成令牌放到隊列中,每來一個請求,就從隊列中獲取一個令牌,并繼續(xù)執(zhí)行。
服務熔斷:當下游服務因某種原因突然變得不可用或響應過慢,上游服務為保證自己整體服務的可用性,不再繼續(xù)調用目標服務,直接返回,快速釋放資源。如果目標服務情況好轉則恢復調用。熔斷主要做錯誤隔離,防止調用鏈路的服務雪崩。
熔斷分成三個狀態(tài):
Closed:熔斷器關閉狀態(tài),調用失敗次數(shù)積累,到了閾值(或一定比例)則啟動熔斷機制。
Open:熔斷器打開狀態(tài),此時對下游調用都內部直接返回錯誤,不走網(wǎng)絡或降級。
Half-Open:半熔斷狀態(tài),允許定量的服務請求,如果調用都成功(或一定比例)則認為恢復了,關閉熔斷器,否則認為還沒好,又回到熔斷器打開狀態(tài)。
最后就是故障模擬(Chaos Monkey),也叫做混沌測試,通過引入一些已知和未知的問題來考驗系統(tǒng)的穩(wěn)定性,把一些已知的情況確定下來,把一些未知變成已知。
2.服務監(jiān)控
服務監(jiān)控主要是為了達到如下效果:
趨勢分析:長期收集并統(tǒng)計監(jiān)控樣本數(shù)據(jù),對監(jiān)控指標進行趨勢分析。
對照分析:隨時掌握系統(tǒng)不同版本在運行時資源使用情況差異,或在不同容量環(huán)境下系統(tǒng)并發(fā)和負載的區(qū)別。
告警:當系統(tǒng)即將或已出現(xiàn)故障時,監(jiān)控可迅速反應并發(fā)出告警。這樣管理員就可提前預防問題發(fā)生或快速處理已產生的問題,從而保證業(yè)務服務的正常運行。
故障分析與定位:故障發(fā)生時,技術人員需要對故障進行調查和處理。通過分析監(jiān)控系統(tǒng)記錄的各種歷史數(shù)據(jù),可以迅速找到問題的根源并解決問題。
數(shù)據(jù)可視化:通過監(jiān)控系統(tǒng)獲取的數(shù)據(jù),可以生成可視化儀表盤,使運維人員能夠直觀地了解系統(tǒng)運行狀態(tài)、資源使用情況、服務運行狀態(tài)等。
通常情況下,監(jiān)控系統(tǒng)分為端監(jiān)控、業(yè)務層監(jiān)控、應用層監(jiān)控、中間件監(jiān)控、系統(tǒng)層監(jiān)控這5層。對應的開源框架如下圖:
而在Azure上通過Application Insight和Azure Monitor即可實現(xiàn)這五層的所有監(jiān)控能力,并將監(jiān)控數(shù)據(jù)整合在一個業(yè)務中供查詢和使用。
3.性能
一旦遇到性能問題,很多人往往感覺束手無策,不知道從哪里著手。雖然性能問題很難處理,但總結起來主要有如下幾點原因:
涉及技術棧廣
涉及角色眾多:系統(tǒng)管理員、應用開發(fā)者、數(shù)據(jù)庫管理員、網(wǎng)絡管理員、運維人員、測試人……
對應的工具與指標度量眾多
那么性能問題該怎么處理?大致可以分成三個階段:設計階段、開發(fā)結算、測試和運維階段。每個階段處理的方法和工具會有一些不同。
《黃帝內經(jīng)·素問》中提到:“是故圣人不治已病治未病,不治已亂治未亂,此之謂也?!逼鋵嵆绦蛟O計也一樣,要把很多問題在設計階段就規(guī)避掉,如果讓問題發(fā)生到后期,需要的人力和物力會成本增長。所以在設計階段要做好:
通過前面介紹的DDD原則來拆分成一個個無狀態(tài)化服務
識別出系統(tǒng)性能可能瓶頸件,確定系統(tǒng)性能指標
確定硬件和中間件規(guī)格,在相應的資源之上進行BenchMark測試
架構的確定(比如采用前端分離等架構,讓各自模塊最大化優(yōu)化)
對關鍵組件進行POC
而在開發(fā)階段需要注意:
加強核心代碼的Performance review
結合CI/CD把性能測試和代碼改動提交結合起來
建立完整監(jiān)控體系,并加以運用
在測試和運維階段,需要結合前面講的監(jiān)控技術建立靈活的預警系統(tǒng),應對不同場景的需求,比如秒殺等。借此形成有效問的題響應機制,使用統(tǒng)一的性能描述語言來溝通問題,并利用日志和系統(tǒng)工具得到最多的第一現(xiàn)場信息,實現(xiàn)快速鎖定和分析問題所在。
最后,為了更好的用戶體驗,一般可對前端采用如下幾點作為優(yōu)化內容:
前后端分離
單頁面應用
使用最新前端技術比如ReactJs或者VueJs等
使用異步加載和Virtual Model等
通過JavaScript函數(shù)語言特性,使用方法緩存
通過瀏覽器Performance工具和Console得到性能數(shù)據(jù)
通過CDN等加速
以上是本次分享的全部內容,主要從設計和概念角度進行闡述和說明。云原生是個很大的概念,后續(xù)我們還將通過更多文章分別進行介紹,敬請期待。