天天看點

建構高性能微服務架構 【摘自劉超】

随着移動網際網路時代的興起,提供高性能、高可用性、高擴充性的服務已經不僅僅是大公司的專利,而逐漸成為所有網際網路+公司的标配需求。本文介紹網易如何利用多年的網際網路架構經驗和網易蜂巢的平台,幫助客戶進行架構改進、微服務化、性能調優。

傳統架構之痛

目前的時代稱為網際網路的時代,網際網路應用的特點往往是,新型的應用迅速出現颠覆舊的商業模式,一旦商業模式稍有起色便會有大量的廠商蜂擁而至,使得藍海變成紅海,經過短時間的殘酷競争,熱度往往持續較短時間後,大量廠商退出市場,僅僅前二名到三名能夠存活下來,最終這一波浪潮被下一波取代。我們回想視訊網站,團購網站,社交網站,微網誌,打車,直播等,全都呈現這種模式。

是以網際網路市場隻有一招,天下武功,唯快不破。

當一種商業模式出現的時候,為了迅速切入市場,占領商業獻祭,快速驗證商業模式,往往軟體的設計會采取傳統的單體架構。

建構高性能微服務架構 【摘自劉超】

傳統的單體架構往往分三層,最下面一層是資料庫,中間是應用程式層,所有的商業邏輯都會在這一層,最上面是頁面。

如果商業模式比較成功,則應用會添加新的功能,一種方式是全部添加到原有的商業邏輯中,另一種方式是開發一個全新的三層結構來支撐新的功能。

建構高性能微服務架構 【摘自劉超】

由于是單體結構,一方面應用層裡面的功能越來越多,如圖中一個功能變為三個功能,将來可能三十個功能,另一方面很多代碼和邏輯都不能複用,如圖中功能2,每個應用都有,這種功能常見的有認證子產品,消息的編碼和解碼子產品等。

這種單體結構會帶來三方面靈活性比較差。

第一,時間靈活性:應用快速疊代,縮短客戶需求到産品上線的時間。

網際網路應用的需求随時改變,因而應用開發的疊代速度要求會比較快,傳統的軟體可能半年或者一年釋出一個功能,而網際網路應用則可能每周都釋出新的功能。而且網際網路産品會時常搞活動,比如雙十一,每次活動不可能提前很長時間策劃,進而給開發充分的産品周期。

然而單體結構的應用如果有了30個子產品,每個子產品由兩到三個人負責,則修改的成本會非常的大,從開發人員看來,整個架構牽一發動全身,每次修改必須要做好良好的前期設計,并且讓整個團隊評審,如果新的需求要改多個子產品,則代碼的管理和合并就成為很大的問題。

建構高性能微服務架構 【摘自劉超】

而且無論測試,聯調,上線,擴充,縮減,更新,復原都需要重新搭建環境,需要配置軟體,需要進行回歸測試,運維人員需要反複的部署環境,而且無法保證環境的一緻性,任何一個環境配置的小問題,都有可能導緻軟體使用有問題。

第二,空間靈活性:應用彈性伸縮,應對業務量突然增長後較短時間恢複。

網際網路應用往往是針對終端使用者的,終端使用者的行為往往不如企業使用者那樣容易預測,終端使用者可能因為促銷,過節等因素導緻通路量的迅速的增長,當通路遭遇峰值的時候,我們希望應用可以快速擴充。

建構高性能微服務架構 【摘自劉超】

然而對于單體架構,應用擴充的過程如萬丈高樓平地起,一層一層慢慢蓋。

建構高性能微服務架構 【摘自劉超】

如果部署在實體機上面,則還需要采購新的實體裝置,如果有虛拟化平台,則需要申請新的虛拟機,并且配置好網絡和存儲。然而僅僅一個空的虛拟機是沒有用的,上面什麼環境都沒有,接下來需要安裝應用環境,比如Tomcat, Apache等,然後就是将應用,頁面配置到應用環境中,還沒有結束,新啟動的是一個獨立的系統,還需要将這個系統加入到目前的系統中,才能一起承擔通路量,例如加入到負載均衡器的配置裡面。這樣每部署一套都需要從頭來一遍,實在是運維人員的噩夢。

第三,管理靈活性:易部署,易遷移,服務發現,依賴管理,自動修複,負載均衡。

現在很多網際網路應用都需要多地,多機房部署,有時候會從一個機房遷移到另一個機房,如果每次變動都如上面一樣從底層到頂層都做一遍,成本比較大,時間比較長。

建構高性能微服務架構 【摘自劉超】

當一個應用依賴于另一個應用,被依賴的應該當機之後,修複需要手動進行,從底層到頂層配置一遍,而且修複好的系統往往IP位址也變了,則依賴于此應用的所有應用都需要修改配置。

網易的微服務化之路

要解決上面所述的三個問題,對應的有三個步驟。

第一步,去狀态化,進而實作程式的可擴充。

單體架構的程式往往很多資料是儲存在記憶體裡面的,或者是本地檔案系統的,例如使用者通路的session資料,例如使用者上傳的照片。所謂的去狀态化,就是使得應用程式僅僅運作商業邏輯,而将資料的儲存全部交給外部的存儲服務。記憶體裡面的資料可以放在緩存redis裡面,結構化資料放在統一的資料庫服務裡面,檔案存放在對象存儲裡面。這樣應用程式就變成了一個隻有商業邏輯的應用,可以随時擴充。

建構高性能微服務架構 【摘自劉超】

這裡面有一個問題就是應用程式的狀态外置化了,放在統一的緩存,資料庫,對象存儲裡面了,可是應用程式當機了是沒有問題了,再啟動一個就可以,如果緩存,資料庫,對象存儲當機了,資料不也是沒有了麼?

其實主流的開源的緩存Redis,資料庫mysql,對象存儲swift等,他們設計的時候就是考慮了高可用和容災的情況的,是以資料存儲的工作就應該讓專業的子產品來做這件事情,而應用程式應該關注在商業邏輯的實作,進而加速開發的速度。當然這些存儲子產品的維護則是另外的專業人士在做的,這部分人士是緩存的專家,資料庫的專家,對象存儲的專家,不需要懂商業邏輯。

第二步,容器化,可編排。

與傳統IaaS架構不同,容器提供的不僅僅是基礎資源,而是将作業系統,應用運作環境以及代碼打包成一個不可修改的鏡像進行傳遞,容器的機制可以保證無論在哪裡,什麼時候運作,都能保持環境的一緻性,也就是Docker所宣稱的“Build, Ship, and Run Any App, Anywhere(一次建構,随處運作)”。

容器特别适合部署無狀态的服務,上一步的無狀态化,給容器化奠定了良好的基礎。

一個服務往往會包含多個元件,因而會封裝成為多個容器,容器之間會有互相的依賴,互相的調用,Kubernetes可以實作服務的編排、自發現、自修複,使得複雜服務的部署變成了一次API調用。

建構高性能微服務架構 【摘自劉超】

如圖所示,Kubernetes管理了互相依賴的四個服務,全部部署在容器裡面,分别運作在不同的機器上面。服務之間的調用通過服務名稱進行,而非固定IP進行,而服務名稱Kubernetes會管理起來。

建構高性能微服務架構 【摘自劉超】

當一台伺服器當機的時候,服務B和服務C會被自動排程到另外兩台機器上,由于服務是無狀态的,是以沒有問題。然而服務A和服務D如何再找到服務B和服務C能,這兩個服務的實體主機變了,很可能IP也變了。其實是沒有問題的,Kubernates會自動将服務名和對應的IP位址關聯起來,服務之間隻要配置的是服務名,而非IP位址,就依然能夠互相通路。

有了容器和Kubernates這兩個工具後,解決了管理複雜性的問題,但是需要專門的團隊和技術力量,去玩轉Kubernates.

第三步,DevOps,可疊代。

從前面的一張圖中,Dev和Ops,開發和運維之間隔着長長的流程,導緻疊代速度很慢。DevOps就是可以加快疊代速度的一種方法。

然而如何讓開發直接進入到運維流程中呢?容器的鏡像不可改變性提供了方案。

建構高性能微服務架構 【摘自劉超】

Docker可以保證容器中的運作環境,業務代碼無論在哪個環境都是一緻的,唯一不同的是不同環境的不同配置,可以通過環境變量注入的方式設定。有了這個模式,開發人員可以從很早就使用容器鏡像的方式進行開發,并且以容器鏡像的方式傳遞給測試,測試使用同樣的鏡像得到同樣的環境進行測試用例的執行,當決定釋出的時候,也确定真正到了生産環境的時候,同測試環境是一樣的。這樣避免了環境不斷重複的部署過程。

容器鏡像可以手動維護和傳遞,但是也可以借助CICD持續內建的工具,來監控代碼庫的更改,當有程式員送出代碼的時候,會觸發一個hook,這個hook會調用CI工具,告知他代碼已經有更新了,可以根據最新的代碼打成最新的鏡像,CI工具根據配置好的Dockerfile,将代碼打包成鏡像,上傳到鏡像庫,每次打鏡像都應該有新的版本,而不應該總使用latest。

鏡像打好了以後,接下來CD的工具會将鏡像部署到測試環境,測試人員可以就這個新的測試環境進行一輪測試,如果測試成功,則可以告知線上管理人員,可以更新新的版本。

線上管理人員在恰當的時間,使用編排工具,将容器鏡像的版本改為最新的版本,進而生産環境也就更新了。如果發現生産環境有問題,新的版本有Bug,沒有問題,隻要将鏡像改為上個版本的鏡像即可,可以保證原來那個能用的版本,所有的配置和原來一樣,進而功能也一樣,實作了更新和復原功能。

當然這套持續內建的工具和流程,需要開發人員和開發流程進行改進,才可以順利使用。

網易蜂巢幫助企業建構高性能微服務架構

前面的三闆斧,去狀态化,容器化,持續內建,分别解決了空間靈活性,管理靈活性,時間靈活性。但是需要招聘一個DBA,Redis的專家,持續內建的專家,容器的專家,Kubernetes的專家,對于一個創業公司來講,這些專家往往比較難招聘到,而且與核心的業務邏輯沒有關系。

下面就介紹一下網易蜂巢幫助企業建構高性能微服務架構背後的黑科技。

第一,高性能的IaaS平台。

蜂巢的容器是基于IaaS平台的,IaaS平台是基礎設施,基礎設施如果搭建不好,會對上層的PaaS和CaaS有性能方面的影響。所謂IaaS層,主要就是計算,網絡,存儲,如果IaaS層不能提供高可靠的,高性能的基礎設施,則容器裡面的網絡和存儲性能也會受影響。

蜂巢做的計算方面的改進主要是針對KVM的,如果我們自己搭建一套OpenStack平台,建立虛拟機的時候,會發現虛拟機的建立時間是分鐘級别的,有時候會幾分鐘甚至十幾分鐘。然而容器是秒級啟動的,毫無疑問,KVM的啟動速度會大大拖累容器的啟動。經過分析KVM的啟動時間,發現cloud-init的配置時間最長,而且預設的KVM鏡像會啟動大量不需要的服務,當然首先做的事情就是對KVM鏡像進行裁剪,并且不使用DHCP的方式配置設定IP,而是采取靜态IP注入的方式進行,這樣KVM的啟動也降到了秒級。

對于網絡方面,基于Neutron的虛拟網絡管理,最底層的技術是基于Openvswitch的,通過vxlan給每一個租戶配置設定一個vxlan id,進而可以實作租戶之間的隔離。為了保證每個租戶的網絡帶寬,需要通過Linux TC和流表對Openvswitch虛拟出來的網卡進行QoS。并且對于大量的網絡小包進行了優化。

對于存儲方面,所有的本地盤和雲盤都是基于SSD盤的,保證了虛拟機的IO性能。對于遠端通路雲盤,支撐iscsi方式和ceph方式,對于ceph叢集,尤其是OSD的部分進行的優化。

第二,MySQL核心開發能力和獨立分支,保證主從切換時資料零丢失。

如果一個MySQL資料可以滿足需求的情況下,主從同步複制的方式,可以保證主從之間資料的一緻性,在使用開源MySQL進行主從複制的時候,雖然主從切換可以配置,但是無法保證資料完全不丢失。這對需要強事務性的業務來講,是個很大的問題。

如果一個MySQL資料庫不足以滿足需求的情況下,就需要分庫分表了,這個蜂巢也是有分布式資料庫NDDB來處理這個事情。

第三,容器的優化。

在容器使用的過程中,容器的網絡問題,尤其是跨主機互通路的問題是比較大的問題,Docker雖然本身提供了Overlay的網絡,但是在性能方面表現一般。在能夠實作互通路的基礎上,還需要能夠和租戶管理結合起來,保證不同的租戶的網絡之間是完全隔離的。另外,容器的網絡除了互聯的問題,還需虛拟防火牆,虛拟VPN,虛拟負載均衡器。最後,很多已經使用網易雲IaaS的業務,也需要IaaS層和容器層互通。在這些方面,其他的容器網絡解決方案例如Flannel,Calico都不能滿足要求。

既然IaaS層使用Neutron和Openvswitch的方案,并且經過性能調優和安全增強,自然容器的網絡也可以使用Openvswitch的方案,滿足上述的要求。

除了網絡問題,容器的存儲也是一個問題。容器是比較适合部署無狀态的服務的,對于有狀态的服務,我們還是希望将使用者資料放置在外置的遠端雲盤中,這樣容器當機和跨主機遷移,都不影響外部的資料,而且資料盤還可以打快照,做備份和恢複。

第四,編排層Kubernetes的優化。

之是以選擇Kubernetes作為服務編排的架構,主要考慮到以下幾點。

  1. Kubernetes功能完善,産品理念成熟。資源排程、服務發現、運作監控、擴容縮容、負載均衡、灰階更新、失敗備援、容災恢複、DevOps都有對應的方案。
  1. 定義了建構分布式業務系統的标準化架構層,即Cluster、Node、Pod、Label等一系列的抽象都是定義好的,為服務編排提供了一個簡單、輕量級的方式。
  1. 社群活躍度高,被大量的雲計算技術提供商和使用者采用。在容器的編排領域有廣泛的群衆基礎

當然Kubernetes作為一個開源軟體,也不會是完美的。

首先遇到的問題是Kubernetes支援多租戶的問題,預設情況下NameSpace 隻隔離 replication controller、pod 等資源,node 與存儲、網絡等是共享狀态,實作真正的多租戶隔離需要将所有資源隔離。不同租戶不共享 node,每個租戶的認證與授權獨立。這樣就避免了在公有雲場景下,使用者使用容器的安全性問題。

第二個問題,就是當叢集規模擴大到一定的規模,任務的排程就遭遇了瓶頸,預設情況下,任務隊列中所有操作都是串行執行,通過改進為多優先級隊列、deadline機制,可有效解決這一問題。

還有一個問題,當叢集規模大了之後,一個etcd叢集不能滿足要求,根據Pod/Node/RC等資源到拆分不同的etcd叢集。現在1.3已經支援将不同資源分布在不同的etcd叢集,而我們其實在1.0的版本上就已經做了相應的實踐。

從上面的叙述可以看出,要建構高性能的微服務架構,既需要基礎架構層面的性能調優,也需要服務編排層面的排程優化,也不能缺少應用層面的微服務化,是一個端到端的工作。

建構高性能微服務架構 【摘自劉超】

如圖所示,綠色的部分是網易蜂巢基于多年的網際網路經驗,在各個層面進行了優化後,推出的元件,作為一個創業公司,不需要招聘一個IaaS平台管理的團隊,資料庫DBA的團隊,分布式存儲的團隊,容器和服務編排的團隊,網絡調優的團隊,而僅僅隻需要聚焦企業核心的業務層面就可以了,如圖中紅色的部分。這樣才能将主要的力量集中在産品快速上線,搶占新一輪網際網路+風口。

企業隻需要逐漸做到以下三步,就可以實作微服務和快速傳遞。

  1. 去狀态化:将記憶體資料寫入緩存,将持久化資料寫入資料庫,将檔案寫入對象存儲。
  2. 容器化:可彈性伸縮,自我修複,動态遷移。
  3. 微服務化:可快速疊代,持續內建。

網易在所有元件的選型的時候,都是采取了業界最主流的開源平台和方案,并且完全相容開源軟體的API,使得平台做到足夠的開放、标準、穩定和不綁定。

作者簡介

劉超,網易雲計算解決方案總架構師。10年雲計算領域研發及架構經驗,Open DC/OS貢獻者。長期專注于Kubernetes、OpenStack、Hadoop、Docker、Lucene、Mesos等開源軟體的企業級應用及産品化。曾出版《Lucene應用開發揭秘》。

轉載于:https://www.cnblogs.com/c3gen/p/6244821.html