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