久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

微服務(wù)化之前需要先無狀態(tài)化和容器化

 太極混元天尊 2018-05-25

作者:劉超,,畢業(yè)于上海交通大學,15年云計算領(lǐng)域研發(fā)及架構(gòu)經(jīng)驗,,先后在EMC,,CCTV證券資訊頻道,,HP,華為,,網(wǎng)易從事云計算和大數(shù)據(jù)架構(gòu)工作,。在工作中積累了大量運營商系統(tǒng),互聯(lián)網(wǎng)金融系統(tǒng),,電商系統(tǒng)等容器化和微服務(wù)化經(jīng)驗,。

一、為什么要做無狀態(tài)化和容器化


很多應(yīng)用拆分成微服務(wù),,是為了承載高并發(fā),,往往一個進程扛不住這么大的量,因而需要拆分成多組進程,,每組進程承載特定的工作,,根據(jù)并發(fā)的壓力用多個副本公共承擔流量。(如果覺得疲累,,可以點擊下面的伴奏音樂,,而且猜對歌名,直接送書?。?/span>

猜對歌曲名字送書 來自架構(gòu)師小秘圈 03:27

將一個進程變成多組進程,,每組進程多個副本,需要程序的修改支撐這種分布式的架構(gòu),,如果架構(gòu)不支持,,僅僅在資源層創(chuàng)建多個副本是解決不了問題的。


很多人說,,支撐雙十一是靠堆機器,,誰不會?真正經(jīng)歷過的會覺得,,能夠靠堆機器堆出來的,,都不是問題,怕的是機器堆上去了,,因為架構(gòu)的問題,,并發(fā)量仍然上不去。


阻礙單體架構(gòu)變?yōu)榉植际郊軜?gòu)的關(guān)鍵點就在于狀態(tài)的處理,。如果狀態(tài)全部保存在本地,,無論是本地的內(nèi)存,還是本地的硬盤,,都會給架構(gòu)的橫向擴展帶來瓶頸,。


狀態(tài)分為分發(fā)、處理,、存儲幾個過程,,如果對于一個用戶的所有的信息都保存在一個進程中,,則從分發(fā)階段,就必須將這個用戶分發(fā)到這個進程,,否則無法對這個用戶進行處理,,然而當一個進程壓力很大的時候,根本無法擴容,,新啟動的進程根本無法處理那些保存在原來進程的用戶的數(shù)據(jù),,不能分擔壓力。


所以要講整個架構(gòu)分成兩個部分,,無狀態(tài)部分和有狀態(tài)部分,,而業(yè)務(wù)邏輯的部分往往作為無狀態(tài)的部分,而將狀態(tài)保存在有狀態(tài)的中間件中,,如緩存,、數(shù)據(jù)庫、對象存儲,、大數(shù)據(jù)平臺、消息隊列等,。


這樣無狀態(tài)的部分可以很容易的橫向擴展,,在用戶分發(fā)的時候,可以很容易分發(fā)到新的進程進行處理,,而狀態(tài)保存到后端,。而后端的中間件是有狀態(tài)的,這些中間件設(shè)計之初,,就考慮了擴容的時候,,狀態(tài)的遷移,復(fù)制,,同步等機制,,不用業(yè)務(wù)層關(guān)心。



如圖所示,,將架構(gòu)分為兩層,,無狀態(tài)和有狀態(tài)。


容器和微服務(wù)是雙胞胎,,因為微服務(wù)會將單體應(yīng)用拆分成很多小的應(yīng)用,,因而運維和持續(xù)集成會工作量變大,而容器技術(shù)能很好的解決這個問題,。然而在微服務(wù)化之前,,建議先進行容器化,在容器化之前,,建議先無狀態(tài)化,,當整個流程容器化了,,以后的微服務(wù)拆分才會水到渠成。



二,、無狀態(tài)化的幾個要點


前面說對于任何狀態(tài),,需要考慮它的分發(fā)、處理,、存儲,。



對于數(shù)據(jù)的存儲,主要包含幾類數(shù)據(jù):


  • 會話數(shù)據(jù)等,,主要保存在內(nèi)存中

  • 結(jié)構(gòu)化數(shù)據(jù),,主要是業(yè)務(wù)邏輯相關(guān)

  • 文件圖片數(shù)據(jù),比較大,,往往通過CDN下發(fā)

  • 非結(jié)構(gòu)化數(shù)據(jù),,例如文本、評論等


如果這些數(shù)據(jù)都保存在本地,,和業(yè)務(wù)邏輯耦合在一起,,就需要在數(shù)據(jù)分發(fā)的時候,將同一個用戶分到同一個進程,,這樣就會影響架構(gòu)的橫向擴展,。



對于保存在內(nèi)存里的數(shù)據(jù),例如Session,,可以放在外部統(tǒng)一的緩存中,。



對于業(yè)務(wù)相關(guān)的數(shù)據(jù),則應(yīng)該保存在統(tǒng)一的數(shù)據(jù)庫中,,如果性能扛不住,,可以進行讀寫分離,如文章《微服務(wù)化的數(shù)據(jù)庫設(shè)計與讀寫分離》,。


如果性能還是抗住不,,則可以使用分布式數(shù)據(jù)庫。



對于文件,,照片之類的數(shù)據(jù),,應(yīng)該存放在統(tǒng)一的對象存儲里面,通過CDN進行預(yù)加載,,如文章《微服務(wù)的接入層設(shè)計與動靜資源隔離》,。


對于非結(jié)構(gòu)化數(shù)據(jù),可以存在在統(tǒng)一的搜索引擎里面,,例如ElasticSearch,。

如果所有的數(shù)據(jù)都放在外部的統(tǒng)一存儲上,則應(yīng)用就成了僅僅包含業(yè)務(wù)邏輯的無狀態(tài)應(yīng)用,,可以進行平滑的橫向擴展,。


而所有的外部統(tǒng)一存儲,,無論是緩存、數(shù)據(jù)庫,、對象存儲,、搜索引擎、都有自身的分布式橫向擴展機制,。



在實行了無狀態(tài)化之后,,就可以將有狀態(tài)的集群集中到一起,進行跨機房的部署,,實現(xiàn)跨機房的高可用性,。而無狀態(tài)的部分可以通過Dubbo自動發(fā)現(xiàn),當進程掛掉的時候,,自動重啟,,自動修復(fù),也可以進行多機房的部署,。

三,、冪等的接口設(shè)計


但是還有一個遺留的問題,就是已經(jīng)分發(fā),,正在處理,,但是尚未存儲的數(shù)據(jù),肯定會在內(nèi)存中有一些,,在進程重啟的時候,數(shù)據(jù)還是會丟一些的,,那這部分數(shù)據(jù)怎么辦呢,?


這部分就需要通過重試進行解決,當本次調(diào)用過程中失敗之后,,前序的進程會進行重試,,例如Dubbo就有重試機制。既然重試,,就需要接口是冪等的,,也即同一次交易,調(diào)用兩次轉(zhuǎn)賬1元,,不能最終轉(zhuǎn)走2元,。


接口分為查詢、插入,、更新,、刪除等操作。


對于查詢接口來講,,本身就是冪等的,,不用做特殊的判斷,。


對于插入接口來講,如果每一個數(shù)據(jù)都有唯一的主鍵,,也能保證插入的唯一性,,一旦不唯一,則會報錯,。


對于更新操作來講,,則比較復(fù)雜,分幾種情況,。


一種情況是同一個接口,,前后調(diào)用多次的冪等性。另一種情況是同一個接口,,并發(fā)環(huán)境下調(diào)用多次的正確性,。


為了保持冪等性,往往要有一個冪等表,,通過傳入冪等參數(shù)匹配冪等表中ID的方式,,保證每個操作只被執(zhí)行一次,而且在實行最終一致性的時候,,可以通過不斷重試,,保證最終接口調(diào)用的成功。


對于并發(fā)條件下,,誰先調(diào)用,,誰后調(diào)用,需要通過分布式鎖如Redis,,ZooKeeper等來實現(xiàn)同一個時刻只有一個請求被執(zhí)行,,如何保證多次執(zhí)行結(jié)果仍然一致呢?則往往需要通過狀態(tài)機,,每個狀態(tài)只流轉(zhuǎn)一次,。還有就是樂觀鎖,也即分布式的CAS操作,,將狀態(tài)的判斷,、更新整合在一條語句中,可以保證狀態(tài)流轉(zhuǎn)的原子性,。樂觀鎖并不保證更新一定成功,,需要有對應(yīng)的機制來應(yīng)對更新失敗。


四,、容器的技術(shù)原理



無狀態(tài)化之后,,實行容器化就十分順暢了,容器的不可改變基礎(chǔ)設(shè)施,以及容器基于容器平臺的掛掉自動重啟,,自動修復(fù),,都因為無狀態(tài)順暢無比。


關(guān)鍵技術(shù)一:Dockerfile


例如下面的Dockerfile,。



為什么一定要用Dockerfile,,而不建議通過保存鏡像的方式來生成鏡像呢?


這樣才能實現(xiàn)環(huán)境配置和環(huán)境部署代碼化 ,,將Dockerfile維護在Git里面,,有版本控制,并且通過自動化的build的過程來生成鏡像,,而鏡像中就是環(huán)境的配置和環(huán)境的部署,,要修改環(huán)境應(yīng)先通過Git上面修改Dockerfile的方式進行,這就是IaC,。


關(guān)鍵技術(shù)二:容器鏡像


通過Dockerfile可以生成容器鏡像,,容器的鏡像是分層保存,對于Dockerfile中的每一個語句,,生成一層容器鏡像,,如此疊加,每一層都有UUID,。


容器鏡像可以打一個版本號,,放入統(tǒng)一的鏡像倉庫。



關(guān)鍵技術(shù)三:容器運行時



容器運行時,,是將容器鏡像之上加一層可寫入層,,為容器運行時所看到的文件系統(tǒng)。


容器運行時使用了兩種隔離的技術(shù),。


一種是看起來是隔離的技術(shù),,稱為namespace,也即每個namespace中的應(yīng)用看到的是不同的IP地址,、用戶空間、程號等,。



另一種是用起來是隔離的技術(shù),,稱為CGroup,也即明明整臺機器有很多的CPU,、內(nèi)存,,而一個應(yīng)用只能用其中的一部分。


CGroup



五,、容器化的本質(zhì)和容器化最佳實踐


很多人會將容器當成虛擬機來用,,這是非常不正確的,而且容器所做的事情虛擬機都能做到。


如果部署的是一個傳統(tǒng)的應(yīng)用,,這個應(yīng)用啟動速度慢,,進程數(shù)量少,基本不更新,,那么虛擬機完全能夠滿足需求,。


  • 應(yīng)用啟動慢:應(yīng)用啟動15分鐘,容器本身秒級,,虛擬機很多平臺能優(yōu)化到十幾秒,,兩者幾乎看不出差別。

  • 內(nèi)存占用大:動不動32G,,64G內(nèi)存,,一臺機器跑不了幾個。

  • 基本不更新:半年更新一次,,虛擬機鏡像照樣能夠升級和回滾,。

  • 應(yīng)用有狀態(tài):停機會丟數(shù)據(jù),如果不知道丟了啥,,就算秒級啟動有啥用,,照樣恢復(fù)不了,而且還有可能因為丟數(shù)據(jù),,在沒有修復(fù)的情況下,,盲目重啟帶來數(shù)據(jù)混亂。

  • 進程數(shù)量少:兩三個進程相互配置一下,,不用服務(wù)發(fā)現(xiàn),,配置不麻煩。


如果是一個傳統(tǒng)應(yīng)用,,根本沒有必要花費精去容器化,,因為白花了力氣,享受不到好處,。



什么情況下,,才應(yīng)該考慮做一些改變呢?


傳統(tǒng)業(yè)務(wù)突然被互聯(lián)網(wǎng)業(yè)務(wù)沖擊了,,應(yīng)用老是變,,三天兩頭要更新,而且流量增大了,,原來支付系統(tǒng)是取錢刷卡的,,現(xiàn)在要互聯(lián)網(wǎng)支付了,流量擴大了N倍,。


沒辦法,,一個字:拆,!


拆開了,每個子模塊獨自變化,,少相互影響,。


拆開了,原來一個進程扛流量,,現(xiàn)在多個進程一起扛,。


所以稱為微服務(wù)。


微服務(wù)場景下,,進程多,,更新快,于是出現(xiàn)100個進程,,每天一個鏡像,。


容器樂了,每個容器鏡像小,,沒啥問題,,虛擬機哭了,因為虛擬機每個鏡像太大了,。


所以微服務(wù)場景下,,可以開始考慮用容器了。



虛擬機怒了,,老子不用容器了,,微服務(wù)拆分之后,用Ansible自動部署是一樣的,。


這樣說從技術(shù)角度來講沒有任何問題,。


然而問題是從組織角度出現(xiàn)的。


一般的公司,,開發(fā)會比運維多的多,,開發(fā)寫完代碼就不用管了,環(huán)境的部署完全是運維負責,,運維為了自動化,,寫Ansible腳本來解決問題。


然而這么多進程,,又拆又合并的,,更新這么快,配置總是變,,Ansible腳本也要常改,每天都上線,,不得累死運維,。


所以這如此大的工作量情況下,運維很容易出錯,哪怕通過自動化腳本,。


這個時候,,容器就可以作為一個非常好的工具運用起來。


除了容器從技術(shù)角度,,能夠使得大部分的內(nèi)部配置可以放在鏡像里面之外,,更重要的是從流程角度,將環(huán)境配置這件事情,,往前推了,,推到了開發(fā)這里,要求開發(fā)完畢之后,,就需要考慮環(huán)境部署的問題,,而不能當甩手掌柜。

這樣做的好處就是,,雖然進程多,,配置變化多,更新頻繁,,但是對于某個模塊的開發(fā)團隊來講,,這個量是很小的,因為5-10個人專門維護這個模塊的配置和更新,,不容易出錯,。


如果這些工作量全交給少數(shù)的運維團隊,不但信息傳遞會使得環(huán)境配置不一致,,部署量會大非常多,。


容器是一個非常好的工具,就是讓每個開發(fā)僅僅多做5%的工作,,就能夠節(jié)約運維200%的工作,,并且不容易出錯。


然而本來原來運維該做的事情開發(fā)做了,,開發(fā)的老大愿意么,?開發(fā)的老大會投訴運維的老大么?


這就不是技術(shù)問題了,,其實這就是DevOps,,DevOps不是不區(qū)分開發(fā)和運維,而是公司從組織到流程,,能夠打通,,看如何合作,邊界如何劃分,,對系統(tǒng)的穩(wěn)定性更有好處,。


所以微服務(wù),,DevOps,容器是相輔相成,,不可分割的,。


不是微服務(wù),根本不需要容器,,虛擬機就能搞定,,不需要DevOps,一年部署一次,,開發(fā)和運維溝通再慢都能搞定,。


所以,容器的本質(zhì)是基于鏡像的跨環(huán)境遷移,。


鏡像是容器的根本性發(fā)明,,是封裝和運行的標準,其他什么Namespace,、CGroup,,早就有了。這是技術(shù)方面,。


在流程方面,,鏡像是DevOps的良好工具。


容器是為了跨環(huán)境遷移的,,第一種遷移的場景是開發(fā),,測試,生產(chǎn)環(huán)境之間的遷移,。如果不需要遷移,,或者遷移不頻繁,虛擬機鏡像也行,,但是總是要遷移,,帶著幾百G的虛擬機鏡像,太大了,。


第二種遷移的場景是跨云遷移,,跨公有云,跨Region,,跨兩個OpenStack的虛擬機遷移都是非常麻煩,,甚至不可能的,因為公有云不提供虛擬機鏡像的下載和上傳功能,,而且虛擬機鏡像太大了,,一傳傳一天。



所以如圖為將容器融入持續(xù)集成的過程中,,形成DevOps的流程,。


通過這一章,,再加上第一章《微服務(wù)化的基石——持續(xù)集成》就構(gòu)成了微服務(wù),DevOps,,容器化三位一體的統(tǒng)一。



對于容器鏡像,,我們應(yīng)該充分利用容器鏡像分層的優(yōu)勢,,將容器鏡像分層構(gòu)建,在最里面的OS和系統(tǒng)工具層,,由運維來構(gòu)建,,中間層的JDK和運行環(huán)境,由核心開發(fā)人員構(gòu)建,,而最外層的Dockerfile就會非常簡單,,只要將jar或者war放到指定位置就可以了。


這樣可以降低Dockerfile和容器化的門檻,,促進DevOps的進度,。


六、容器平臺的最佳實踐


容器化好了,,應(yīng)該交給容器平臺進行管理,,從而實現(xiàn)對于容器的自動化管理和編排。



例如一個應(yīng)用包含四個服務(wù)A,、B,、C、D,,她們相互引用,,相互依賴,如果使用了容器平臺,,則服務(wù)之間的服務(wù)發(fā)現(xiàn)就可以通過服務(wù)名進行了,。例如A服務(wù)調(diào)用B服務(wù),不需要知道B服務(wù)的IP地址,,只需要在配置文件里面寫入B服務(wù)服務(wù)名就可以了,。如果中間的節(jié)點宕機了,容器平臺會自動將上面的服務(wù)在另外的機器上啟動起來,。容器啟動之后,,容器的IP地址就變了,但是不用擔心,,容器平臺會自動將服務(wù)名B和新的IP地址映射好,,A服務(wù)并無感知。這個過程叫做自修復(fù)和自發(fā)現(xiàn),。如果服務(wù)B遭遇了性能瓶頸,,三個B服務(wù)才能支撐一個A服務(wù),,也不需要特殊配置,只需要將服務(wù)B的數(shù)量設(shè)置為3,,A還是只需要訪問服務(wù)B,,容器平臺會自動選擇其中一個進行訪問,這個過程稱為彈性擴展和負載均衡,。


當容器平臺規(guī)模不是很大的時候,,Docker Swarm Mode還是比較好用的:


  • 集群的維護不需要ZooKeeper,不需要Etcd,,自己內(nèi)置

  • 命令行和Docker一樣的,,用起來順手

  • 服務(wù)發(fā)現(xiàn)和DNS是內(nèi)置的

  • Docker Overlay網(wǎng)絡(luò)是內(nèi)置的


總之Docker幫你料理好了一切,你不用太關(guān)心細節(jié),,很容易就能夠?qū)⒓哼\行起來,。


而且可以通過Docker命令,像在一臺機器上使用容器一樣使用集群上的容器,,可以隨時將容器當虛擬機來使用,,這樣對于中等規(guī)模集群,以及運維人員還是比較友好的,。


當然內(nèi)置的太多了也有缺點,,就是不好定制化,不好Debug,,不好干預(yù),。當你發(fā)現(xiàn)有一部分性能不行的時候,你需要改整個代碼,,全部重新編譯,,當社區(qū)更新了,合并分支是很頭疼的事情,。當出現(xiàn)了問題的時候,,由于Manager大包大攬干了很多活,不知道哪一步出錯了,,反正就是沒有返回,,停在那里,如果重啟整個Manager,,影響面又很大,。



當規(guī)模比較大,應(yīng)用比較復(fù)雜的時候,,則推薦Kubernetes,。


Kubernetes模塊劃分得更細,模塊比較多,而且模塊之間完全的松耦合,,可以非常方便地進行定制化,。



而且Kubernetes的數(shù)據(jù)結(jié)構(gòu)的設(shè)計層次比較細,非常符合微服務(wù)的設(shè)計思想,。例如從容器->Pods->Deployment->Service,,本來簡單運行一個容器,被封裝為這么多的層次,,每次層有自己的作用,,每一層都可以拆分和組合,這樣帶來一個很大的缺點,,就是學習門檻高,為了簡單運行一個容器,,需要先學習一大堆的概念和編排規(guī)則,。


但是當需要部署的業(yè)務(wù)越來越復(fù)雜時,場景越來越多時,,你會發(fā)現(xiàn)Kubernetes這種細粒度設(shè)計的優(yōu)雅,,使得你能夠根據(jù)自己的需要靈活的組合,而不會因為某個組件被封裝好了,,從而導致很難定制,。例如對于Service來講,除了提供內(nèi)部服務(wù)之間的發(fā)現(xiàn)和相互訪問外,,還靈活設(shè)計了headless service,,這使得很多游戲需要有狀態(tài)的保持長連接有了很好的方式,另外訪問外部服務(wù)時,,例如數(shù)據(jù)庫,、緩存、headless service相當于一個DNS,,使得配置外部服務(wù)簡單很多,。很多配置復(fù)雜的大型應(yīng)用,更復(fù)雜的不在于服務(wù)之間的相互配置,,可以有Spring Cloud或者Dubbo去解決,,復(fù)雜的反而是外部服務(wù)的配置,不同的環(huán)境依賴不同的外部應(yīng)用,,External Name這個提供和很好的機制,。


包括統(tǒng)一的監(jiān)控cAdvisor,統(tǒng)一的配置ConfigMap,,都是構(gòu)建一個微服務(wù)所必須的,。


然而Kubernetes當前也有一個瓶頸——集群規(guī)模還不是多么大,官方說法是幾千個節(jié)點,,所以超大規(guī)模的集群,,還是需要有很強的IT能力進行定制化,。但是對于中等規(guī)模的集群也足夠了。


而且Kubernetes社區(qū)的熱度,,可以使得使用開源Kubernetes的公司能夠很快地找到幫助,,等待到新功能的開發(fā)和Bug的解決。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導購買等信息,,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多