本課時(shí)會(huì)講解分布式系統(tǒng)架構(gòu)以及面試中做項(xiàng)目介紹的技巧,重點(diǎn)有如下三部分。
介紹系統(tǒng)架構(gòu)的演進(jìn):包括微服務(wù)架構(gòu)、云原生以及業(yè)界最新趨勢(shì) ServiceMesh。
講解微服務(wù)的基礎(chǔ)知識(shí)點(diǎn):Docker 和 K8s。
面試技巧,教你如何更有效地做項(xiàng)目介紹。
首先以演進(jìn)的方式來(lái)了解不同的系統(tǒng)架構(gòu)。
最簡(jiǎn)單的系統(tǒng)架構(gòu)是單體服務(wù),如下圖所示。
一個(gè)項(xiàng)目中的多個(gè)服務(wù),混合部署在一個(gè)進(jìn)程內(nèi),服務(wù)之間的交互都是通過(guò)進(jìn)程內(nèi)調(diào)用完成的,正如圖中 Service 之間的紅色箭頭所示。這樣做的好處是可以快速開(kāi)發(fā)、部署服務(wù),服務(wù)之間調(diào)用的性能也最好。
當(dāng)然,這種架構(gòu)缺點(diǎn)也非常多,比如:
隨著業(yè)務(wù)的增長(zhǎng),項(xiàng)目越來(lái)越臃腫;
服務(wù)之間因?yàn)?JAR 包引用導(dǎo)致頻繁的依賴(lài)沖突;
服務(wù)資源變更困難,因?yàn)橐粋€(gè)服務(wù)可能被多個(gè)不同的業(yè)務(wù)引用,升級(jí)資源需要多個(gè)業(yè)務(wù)方同時(shí)升級(jí);
因?yàn)椴煌瑯I(yè)務(wù)方都可以直連服務(wù)的數(shù)據(jù)資源,這個(gè)架構(gòu)也存在明顯的數(shù)據(jù)安全風(fēng)險(xiǎn);
修改代碼后回歸困難、架構(gòu)難以調(diào)整等等。
以上所有問(wèn)題都是因?yàn)榉?wù)耦合在一起導(dǎo)致的。在服務(wù)規(guī)模不大的情況下,比較適合采用單體架構(gòu),方便快速迭代。但是當(dāng)服務(wù)規(guī)模變大時(shí),單體架構(gòu)就不是一個(gè)好的選擇。
當(dāng)服務(wù)的規(guī)模變大時(shí),為了解決服務(wù)耦合的問(wèn)題,出現(xiàn)了 SOA 就是面向服務(wù)架構(gòu),它的起源是為了解決企業(yè)應(yīng)用問(wèn)題,隨著不斷演進(jìn),發(fā)展到目前業(yè)界普遍采用的微服務(wù)架構(gòu),微服務(wù)架構(gòu)如下所示。
微服務(wù)架構(gòu)的思想就是讓服務(wù)盡可能做到高內(nèi)聚、低耦合,不同的服務(wù)單獨(dú)開(kāi)發(fā)、單獨(dú)測(cè)試、單獨(dú)部署。服務(wù)之間通過(guò) RPC 或者 HTTP 進(jìn)行遠(yuǎn)程交互,如圖中的藍(lán)色加粗箭頭所示。
微服務(wù)架構(gòu)解決了單體架構(gòu)的耦合問(wèn)題,但同時(shí)也帶來(lái)了新的問(wèn)題。因?yàn)榉?wù)部署在不同的進(jìn)程或服務(wù)器中,要使用服務(wù)前需要先找到服務(wù),即所謂的服務(wù)發(fā)現(xiàn)。
一般微服務(wù)使用兩種發(fā)現(xiàn)方式,一種是前面課程介紹過(guò)的 RPC 方式,通過(guò)注冊(cè)中心進(jìn)行服務(wù)的注冊(cè)和訂閱,來(lái)完成服務(wù)發(fā)現(xiàn),比如圖中間灰色的 Registry 模塊。這種方式由服務(wù)的調(diào)用端獲得到全部可用服務(wù)節(jié)點(diǎn),由 Client 側(cè)進(jìn)行負(fù)載均衡,調(diào)用服務(wù)。另外一種是通過(guò) HTTP 協(xié)議調(diào)用服務(wù)端提供的 RESTful 接口,這種方式不需要 Client 側(cè)做服務(wù)發(fā)現(xiàn),而是在 Server 端通過(guò) Nignx 這樣的反向代理來(lái)提供 Server 側(cè)的負(fù)載均衡。
不論哪種方式,服務(wù)的交互都從進(jìn)程內(nèi)通信變成了遠(yuǎn)程通信,所以性能必然會(huì)受到一些影響。此外由于很多不確定性的因素,例如網(wǎng)絡(luò)擁塞、Server 端服務(wù)器宕機(jī)、挖掘機(jī)鏟斷機(jī)房光纖等等,需要許多額外的功能和措施才能保證微服務(wù)流暢穩(wěn)定的工作。前面在 Spring Cloud 內(nèi)容中提到的 Hystrix 熔斷器、Ribbon客戶端負(fù)載均衡器、Eureka注冊(cè)中心等等都是用來(lái)解決這些問(wèn)題的微服務(wù)組件。
在微服務(wù)架構(gòu)中,有必要了解一下分布式系統(tǒng)中的 CAP 原則與 BASE 理論。如下圖所示,CAP 原則指的是在一個(gè)分布式系統(tǒng)中,Consistency 一致性、 Availability 可用性、Partition tolerance 分區(qū)容錯(cuò)性,這三個(gè)特性最多只能同時(shí)滿足兩個(gè),三者不可兼得。
其中一致性指所有節(jié)點(diǎn)在同一時(shí)間的數(shù)據(jù)完全一致;可用性指任何時(shí)候?qū)Ψ植际较到y(tǒng)總是可以成功讀和寫(xiě);分區(qū)容錯(cuò)性是指當(dāng)某些節(jié)點(diǎn)或網(wǎng)絡(luò)分區(qū)故障的時(shí)候,仍然能夠提供滿足一致性和可用性的服務(wù)。
既然無(wú)法同時(shí)滿足三個(gè)特征,那就會(huì)有三種取舍。
第一個(gè)選擇是 CA,就是放棄分區(qū)容錯(cuò),這也就等同于放棄了分布式系統(tǒng),所以 CA 只存在于單機(jī)系統(tǒng)。
第二個(gè)選擇是 CP,也就是選擇強(qiáng)一致和分區(qū)容錯(cuò),允許極端情況下出現(xiàn)短時(shí)的服務(wù)不可用。采用 CP 原則實(shí)現(xiàn)的分布式系統(tǒng)比如 ZooKeeper。ZooKeeper是一個(gè)分布式協(xié)調(diào)系統(tǒng),強(qiáng)一致性是 ZK 的主要目標(biāo),允許出現(xiàn)短時(shí)的系統(tǒng)不可用。也正是因?yàn)檫@個(gè)原因,ZK 其實(shí)并不適合用來(lái)做微服務(wù)的注冊(cè)中心。其他選擇 CP 實(shí)現(xiàn)的系統(tǒng)還有 Consul、etcd 等。
第三個(gè)選擇是 AP,也就是選擇分區(qū)容錯(cuò)和高可用,允許數(shù)據(jù)出現(xiàn)短時(shí)間不一致。采用 AP 原則的分布式系統(tǒng)有 Eureka、Nacos。在服務(wù)注冊(cè)的場(chǎng)景,短期的不一致一般不會(huì)對(duì)服務(wù)交互產(chǎn)生影響,因此采用 AP 原則的注冊(cè)中心才是微服務(wù)比較適合的選擇。
然后,介紹一下 BASE 理論,如上圖底部的詞匯所示,BASE 是指 Basically Available 基本可用,Soft-state 軟狀態(tài),Eventual Consistency 最終一致性,它是對(duì) CAP 中一致性和可用性權(quán)衡的結(jié)果。BASE 的核心思想是即使無(wú)法做到強(qiáng)一致性,也可以根據(jù)系統(tǒng)特點(diǎn),采用適當(dāng)?shù)姆绞竭_(dá)到最終一致性。
繼續(xù)講解系統(tǒng)架構(gòu)的演進(jìn)。微服務(wù)架構(gòu)的思路是服務(wù)解耦合,這會(huì)導(dǎo)致一個(gè)大的業(yè)務(wù)拆分成眾多小的服務(wù),每個(gè)服務(wù)的部署需要考慮單點(diǎn)問(wèn)題,需要多機(jī)房多節(jié)點(diǎn)部署,會(huì)造成系統(tǒng)資源的浪費(fèi)。
另外在服務(wù)擴(kuò)容時(shí)需要重新整理服務(wù)運(yùn)行依賴(lài)的環(huán)境,對(duì)微服務(wù)的普及有一定阻礙。容器化技術(shù)把服務(wù)的運(yùn)行環(huán)境進(jìn)行打包管理,解決了服務(wù)擴(kuò)縮容時(shí)對(duì)運(yùn)行環(huán)境的管理問(wèn)題以及服務(wù)器的利用率問(wèn)題。因此隨著容器技術(shù)逐漸成熟,微服務(wù)架構(gòu)也快速普及。
云原生架構(gòu)由微服務(wù)組成,它不是一種業(yè)務(wù)系統(tǒng)架構(gòu),而是一種能夠快速、持續(xù)、可靠、規(guī)?;亟桓稑I(yè)務(wù)服務(wù)的模式。
如下圖所示,圖上部列出了云原生的三個(gè)特征:
容器化的微服務(wù),這是云原生的主體;
Devops,是對(duì)微服務(wù)的動(dòng)態(tài)管理;
持續(xù)交付能力,這是云原生的目的。
云原生服務(wù)需要底層的云服務(wù)提供 IaaS 基礎(chǔ)設(shè)施或者 PaaS 平臺(tái)設(shè)施來(lái)運(yùn)行,IaaS 可以理解為提供了服務(wù)器資源,PaaS 平臺(tái)可以理解為提供了運(yùn)行環(huán)境。
常見(jiàn)的實(shí)現(xiàn)方式有兩種:自建的私有云和云廠商提供的公有云。公有云比如阿里云、AWS、騰訊云等等,像新浪微博內(nèi)部使用的是私有云與公有云結(jié)合的混合云模式。
接下來(lái)看云原生應(yīng)用開(kāi)發(fā)的最佳實(shí)踐原則:12 要素,如下圖所示。
12 要素定義了設(shè)計(jì) SaaS 應(yīng)用時(shí)需要遵循的一些基本原則,SaaS 是軟件即服務(wù)的縮寫(xiě),通過(guò)云原生應(yīng)用來(lái)提供服務(wù)。
第 1 個(gè)要素是基準(zhǔn)代碼,是指代碼由版本管理工具來(lái)管理,一個(gè)應(yīng)用只有一份基準(zhǔn)代碼,運(yùn)行時(shí)有多個(gè)的部署實(shí)例。
第 2 個(gè)要素依賴(lài),是指要在應(yīng)用中顯示的聲明依賴(lài),方便服務(wù)進(jìn)行構(gòu)建。
第 3 個(gè)要素配置,指要在環(huán)境中存儲(chǔ)配置,而不是寫(xiě)在代碼配置文件中。也就是說(shuō),配置與代碼要分開(kāi)管理,從代碼外部進(jìn)行加載,例如測(cè)試環(huán)境的配置、仿真環(huán)境的配置以及生產(chǎn)環(huán)境的配置都應(yīng)該從對(duì)應(yīng)的環(huán)境中進(jìn)行加載。
第 4 個(gè)要素后端服務(wù),是指要把依賴(lài)的后端服務(wù)統(tǒng)一看作資源來(lái)對(duì)待。不論是 DB、緩存還是 HTTP 服務(wù)。
第 5 個(gè)要素是構(gòu)建、發(fā)布、運(yùn)行,是指要嚴(yán)格區(qū)分應(yīng)用的構(gòu)建、發(fā)布、運(yùn)行這三個(gè)步驟,并且必須按順序進(jìn)行。
第 6 個(gè)要素進(jìn)程,是指應(yīng)用以一個(gè)或多個(gè)進(jìn)程運(yùn)行,要保證應(yīng)用的無(wú)狀態(tài)性。
第 7 個(gè)要素端口綁定,是指不同的應(yīng)用使用不同的端口提供服務(wù)。應(yīng)用與端口是綁定的,不是指具體的某個(gè)端口號(hào),而是指一旦服務(wù)啟動(dòng)確定了端口,那么這個(gè)端口就能夠提供對(duì)應(yīng)的服務(wù),直到應(yīng)用進(jìn)程停止。
第 8 個(gè)要素并發(fā),是指應(yīng)用進(jìn)程之間可以并發(fā)處理,因此可以通過(guò)多進(jìn)程方式進(jìn)行水平擴(kuò)展。
第 9 個(gè)要素易處理,是指應(yīng)用應(yīng)該容易被管理,可以通過(guò)優(yōu)雅停機(jī)和快速啟動(dòng),構(gòu)建最健壯的服務(wù)。
第 10 個(gè)要素開(kāi)發(fā)/生產(chǎn)等價(jià),是指要保證在開(kāi)發(fā)、預(yù)覽、生產(chǎn)等不同環(huán)境下的應(yīng)用,盡可能一致。
第 11 個(gè)要素日志,是指要合理記錄應(yīng)用的運(yùn)行日志,并把日志當(dāng)作一種事件流來(lái)對(duì)待,方便對(duì)日志的收集和處理。
第 12 個(gè)要素管理進(jìn)程,是指要把后臺(tái)管理任務(wù)當(dāng)作一次性進(jìn)程來(lái)運(yùn)行,而不是常駐后臺(tái)進(jìn)程的方式。
以上 12 要素是對(duì)設(shè)計(jì)云原生服務(wù)的指導(dǎo)原則,在實(shí)際項(xiàng)目中可以結(jié)合實(shí)際業(yè)務(wù)場(chǎng)景進(jìn)行架構(gòu)設(shè)計(jì),不一定完全照搬。
云原生應(yīng)用是目前大部分互聯(lián)網(wǎng)公司的服務(wù)架構(gòu)推進(jìn)方向,那么下一代的服務(wù)架構(gòu)是什么樣呢?這里介紹一個(gè)最新的服務(wù)化趨勢(shì),它離實(shí)際應(yīng)用可能還有些遙遠(yuǎn),我們可以靜待它的發(fā)展。
Service Mesh 是 2017 年逐漸在國(guó)內(nèi)進(jìn)入大家視野的一種架構(gòu)方式,被譽(yù)為下一代的微服務(wù)。Service Mesh 在微服務(wù)的基礎(chǔ)上引入了一個(gè) Sidecar 邊車(chē)的概念,如圖中左下方的放大圖所示,每個(gè)服務(wù)會(huì)伴生著部署一個(gè) Sidecar,服務(wù)之間的交互不再由服務(wù)自身來(lái)完成,服務(wù)所有的出、入請(qǐng)求都交由這個(gè) Sidecar 來(lái)進(jìn)行處理,通過(guò)管理平面對(duì)所有的 Sidecar 進(jìn)行統(tǒng)一管理,由 Sidecar 來(lái)實(shí)現(xiàn)服務(wù)發(fā)現(xiàn)、負(fù)載均衡、流量調(diào)度等能力。
目前最有代表性的 Service Mesh 開(kāi)源實(shí)現(xiàn),是由 Google、IBM、Lyft 三家一起維護(hù)的 Istio,有興趣的話可以持續(xù)關(guān)注,這里就不詳細(xì)展開(kāi)了。
那么 Service Mesh 與微服務(wù)的區(qū)別是什么呢?Service Mesh 又可以解決哪些問(wèn)題呢?如下圖所示。
微服務(wù)的出現(xiàn)是為了解決多個(gè)服務(wù)之間耦合的問(wèn)題,如圖中綠色的豎線,就是微服務(wù)架構(gòu)做的事情,把 Service A、B、C 進(jìn)行了解耦,服務(wù)單獨(dú)部署、單獨(dú)管理。這時(shí)每個(gè)服務(wù)都需要實(shí)現(xiàn)例如服務(wù)發(fā)現(xiàn)、服務(wù)的遠(yuǎn)程交互、交互過(guò)程中的負(fù)載均衡、高可用策略、服務(wù)熔斷等等一系列的功能,這些功能與服務(wù)自身的業(yè)務(wù)邏輯沒(méi)有任何關(guān)系。
Service Mesh 的思路是把業(yè)務(wù)邏輯與業(yè)務(wù)無(wú)關(guān)的功能進(jìn)行解耦,如圖中紅色的線,對(duì)服務(wù)進(jìn)行橫切,把與服務(wù)交互相關(guān)的功能從服務(wù)中剝離出來(lái),統(tǒng)一交給 Sidecar 去實(shí)現(xiàn),讓服務(wù)更聚焦于業(yè)務(wù)邏輯,提高研發(fā)效率。同時(shí)由于功能相對(duì)獨(dú)立,Sidecar 可以更專(zhuān)注于服務(wù)的交互與管理,更方便實(shí)現(xiàn)極致的功能與性能。
所以,Service Mesh 不是一個(gè)全新的技術(shù),它對(duì)業(yè)務(wù)與服務(wù)交互、管理進(jìn)行了拆分,提供統(tǒng)一、強(qiáng)大的服務(wù)管理能力,是在微服務(wù)基礎(chǔ)上的演進(jìn)。
另外,Service Mesh 由于使用獨(dú)立的 Sidecar 進(jìn)程,天然適合為不同語(yǔ)言的服務(wù)提供統(tǒng)一的服務(wù)治理能力,因此跨語(yǔ)言服務(wù)治理也是 Service Mesh 的一個(gè)重要特點(diǎn),像微博基于 Motan 研發(fā)的 Weibo Mesh,初衷就是為了解決內(nèi)部不同語(yǔ)言之間服務(wù)化的問(wèn)題。
由于引入了額外的 Sidecar,Service Mesh 的架構(gòu)復(fù)雜度更高,也會(huì)帶來(lái)額外的可用性和性能問(wèn)題,這也是 Service Mesh 架構(gòu)需要努力解決的問(wèn)題。
通過(guò)了解系統(tǒng)架構(gòu)的演進(jìn),我們發(fā)現(xiàn),從單體架構(gòu)到微服務(wù)架構(gòu),實(shí)現(xiàn)了服務(wù)之間解耦,但帶來(lái)了額外的服務(wù)發(fā)現(xiàn)與交互問(wèn)題;從微服務(wù)到 Service Mesh,實(shí)現(xiàn)了業(yè)務(wù)與服務(wù)治理功能的解耦,但是引入了額外的可用性和性能問(wèn)題,架構(gòu)復(fù)雜度也隨之提高。那么這樣做的意義在哪里?
系統(tǒng)架構(gòu)的設(shè)計(jì)從來(lái)就是一個(gè)權(quán)衡的藝術(shù),很多情況下,我們只是讓問(wèn)題進(jìn)行了轉(zhuǎn)移,方便對(duì)問(wèn)題進(jìn)行集中整治和處理,讓服務(wù)更聚焦業(yè)務(wù)研發(fā),不同的功能就交給專(zhuān)門(mén)的組件來(lái)處理,正所謂術(shù)業(yè)有專(zhuān)攻。通過(guò)架構(gòu)的演進(jìn),雖然當(dāng)下沒(méi)有消滅復(fù)雜度,但可以成功的讓問(wèn)題變的透明化,變的業(yè)務(wù)無(wú)感知,提升服務(wù)整體的開(kāi)發(fā)效率與擴(kuò)展能力,拓寬服務(wù)能力的上限。
微服務(wù)之所以能夠快速發(fā)展,很重要的一個(gè)原因就是:容器化技術(shù)的發(fā)展和容器管理系統(tǒng)的成熟。所以接下來(lái)學(xué)習(xí)微服務(wù)架構(gòu)的基礎(chǔ),容器化技術(shù) Docker 和容器集群管理系統(tǒng) Kubernetes。
Docker 的作用主要是快速的構(gòu)建、部署、運(yùn)行服務(wù),通過(guò)服務(wù)鏡像能夠?yàn)榉?wù)提供版本管理。
通過(guò)容器化技術(shù)可以屏蔽不同運(yùn)行環(huán)境的差異,讓服務(wù)在任何 Docker 環(huán)境中運(yùn)行,就像 Java 的一次編譯到處運(yùn)行。
Docker 是輕量虛擬化技術(shù),可以在一臺(tái)宿主機(jī)上運(yùn)行多個(gè)服務(wù),對(duì)運(yùn)行的服務(wù)之間進(jìn)行了有效的隔離,提高宿主機(jī)的資源利用率。
Docker 特點(diǎn)
開(kāi)源,意味著可以免費(fèi)使用 Docker 容器技術(shù)。
基于 LXC 實(shí)現(xiàn)的輕量虛擬化,Docker 容器直接運(yùn)行進(jìn)程,不需要模擬,運(yùn)行效率非常高。
能夠支持大規(guī)模構(gòu)建。
Docker 的架構(gòu)十分靈活,可擴(kuò)展不同的實(shí)現(xiàn),例如支持不同存儲(chǔ)驅(qū)動(dòng)實(shí)現(xiàn)。
Docker 提供可視化 UI,管理非常簡(jiǎn)單。
鏡像,就是服務(wù)代碼和運(yùn)行環(huán)境的封裝,服務(wù)的版本管理就是通過(guò)鏡像來(lái)實(shí)現(xiàn)的,鏡像是部署的基礎(chǔ)。
容器,就是 Container,容器是基于鏡像的服務(wù)運(yùn)行狀態(tài),可以基于一個(gè)鏡像運(yùn)行多個(gè)容器。
守護(hù)進(jìn)程是運(yùn)行在宿主機(jī)上的管理進(jìn)程,用戶通過(guò) Client 與守護(hù)進(jìn)程進(jìn)行交互。
客戶端是用來(lái)和守護(hù)進(jìn)程交互的命令行工具,也可以通過(guò) Socket 或者 RESTful API 訪問(wèn)遠(yuǎn)程的 Docker 守護(hù)進(jìn)程。
鏡像倉(cāng)庫(kù),類(lèi)似我們的 Git 代碼倉(cāng)庫(kù),鏡像倉(cāng)庫(kù)用來(lái)保存、管理不同服務(wù)不同版本的鏡像。服務(wù)部署時(shí)會(huì)從鏡像倉(cāng)庫(kù)拉取對(duì)應(yīng)版本的鏡像進(jìn)行部署。
Docker 是通過(guò)對(duì)不同運(yùn)行進(jìn)程進(jìn)行隔離來(lái)實(shí)現(xiàn)虛擬化,主要利用三種方式來(lái)實(shí)現(xiàn)服務(wù)的隔離,如下圖所示。
首先是利用 Linux 的 Namespace 命名空間,來(lái)隔離進(jìn)程之間的可見(jiàn)性,不同的服務(wù)進(jìn)程彼此屬于不同的 Namespace,互相無(wú)法感知對(duì)方的存在。
Docker 實(shí)現(xiàn)了 Host、Container、None 和 Bridge 四種網(wǎng)絡(luò)模式,默認(rèn)使用 Bridge 橋接模式。每一個(gè)容器在創(chuàng)建時(shí)都會(huì)創(chuàng)建一對(duì)虛擬網(wǎng)卡,兩個(gè)虛擬網(wǎng)卡組成了數(shù)據(jù)的通道,其中一個(gè)會(huì)放在容器中,另一個(gè)會(huì)加入到 Docker0 的網(wǎng)橋中。Docker0 網(wǎng)橋通過(guò) iptables 中的配置與宿主機(jī)上的網(wǎng)卡相連,所有符合條件的請(qǐng)求都會(huì)通過(guò) iptables 轉(zhuǎn)發(fā)到 Docker0 并由網(wǎng)橋分發(fā)給對(duì)應(yīng)的容器網(wǎng)卡。為了防止容器進(jìn)程修改宿主機(jī)的文件目錄,Docker 通過(guò)改變進(jìn)程訪問(wèn)文件目錄的根節(jié)點(diǎn),結(jié)合 Namespace 來(lái)隔離不同容器進(jìn)程可以訪問(wèn)的文件目錄。
然后,通過(guò) Namespace,Docker 隔離了進(jìn)程、網(wǎng)絡(luò)和文件目錄,但是在進(jìn)程運(yùn)行中的 CPU 和內(nèi)存等還是共享狀態(tài)。Docker 通過(guò) Control Groups 也就是 Cgroups 來(lái)對(duì)進(jìn)程使用的資源進(jìn)行限制,包括 CPU、內(nèi)存和網(wǎng)絡(luò)帶寬等。
那么,Docker 是如何把鏡像運(yùn)行起來(lái)的呢?Docker 的鏡像是分層結(jié)構(gòu),例如一個(gè)服務(wù)鏡像可以由操作系統(tǒng)層、基礎(chǔ)環(huán)境層、Web 容器層、服務(wù)代碼層,層層依賴(lài)構(gòu)成。通過(guò) UnionFS 就是聯(lián)合文件系統(tǒng)把 Image 中的不同分層作為不同的只讀目錄,而 Container 是在只讀的鏡像目錄上創(chuàng)建的可讀可寫(xiě)的目錄,通過(guò)這種方式來(lái)把鏡像運(yùn)行起來(lái)的。Docker 提供了 AUFS、Overlay、Devicemapper、ZFS 等多種不同存儲(chǔ)驅(qū)動(dòng)實(shí)現(xiàn)。
Kubernetes 也叫 K8s,因?yàn)?K 與 s 之間一共有 8 個(gè)字母。K8s 是一個(gè)容器集群管理系統(tǒng),不是一個(gè) PaaS 平臺(tái),PaaS 平臺(tái)是可以運(yùn)行在 K8s 之上的。
K8s 的作用是進(jìn)行容器集群管理,它只針對(duì)容器管理,不部署源碼不編譯應(yīng)用。它能夠?qū)崿F(xiàn)服務(wù)容器的自動(dòng)部署與按指定條件進(jìn)行自動(dòng)擴(kuò)縮容服務(wù),來(lái)實(shí)現(xiàn)對(duì)應(yīng)用的管理,支持應(yīng)用的負(fù)載均衡、滾動(dòng)更新、資源監(jiān)控等等。
可移植,支持在公有云,私有云,混合云中運(yùn)行;
可擴(kuò)展,K8s 采用模塊化實(shí)現(xiàn)方式,插件化的架構(gòu),可掛載,可組合;
自動(dòng)化,支持服務(wù)的自動(dòng)部署,自動(dòng)重啟,自動(dòng)復(fù)制,自動(dòng)伸縮。
K8s 中的概念非常的多,這里列出了比較重要的幾個(gè)。
K8s 是容器集群管理系統(tǒng),容器首先需要運(yùn)行在宿主機(jī)上,因此,K8s 首先要管理宿主機(jī)集群,K8s 分為 Master 節(jié)點(diǎn)和 Node 節(jié)點(diǎn),也叫 Worker Node。
Master 負(fù)責(zé)管理節(jié)點(diǎn),管理 K8s 集群。Master 協(xié)調(diào)集群中的所有行為/活動(dòng),例如應(yīng)用的運(yùn)行、修改、更新等。
Node 節(jié)點(diǎn)用來(lái)運(yùn)行容器。Node 上可以運(yùn)行多個(gè) Pod,Pod 是 K8s 創(chuàng)建或部署的基本單位,Pod 中可以運(yùn)行多個(gè) Container,一個(gè) Container 就是一個(gè)運(yùn)行中的服務(wù)鏡像。
Pod 中的 Container 共享網(wǎng)絡(luò)與存儲(chǔ)。
Service 是 K8s 中的一個(gè)邏輯概念,通過(guò)對(duì)不同的 Pod 添加標(biāo)簽,來(lái)劃分為不同的 Service。
Deployment 表示用戶對(duì) K8s 集群的一次更新操作,可以是創(chuàng)建一個(gè)新的服務(wù),更新一個(gè)新的服務(wù),也可以是滾動(dòng)升級(jí)一個(gè)服務(wù)。
下圖是 K8s 架構(gòu)圖,圖左側(cè)綠色的模塊代表 Master 節(jié)點(diǎn),右側(cè)藍(lán)色的模塊代表運(yùn)行容器的Worker Node 節(jié)點(diǎn)。
先來(lái)看 Master 節(jié)點(diǎn)中的架構(gòu),灰色的部分是 Master 中的模塊,其中 API Server 是用戶對(duì) K8s 中資源操作的唯一入口,創(chuàng)建應(yīng)用部署、管理部署狀態(tài)等都需要通過(guò) api server 進(jìn)行。API Server 提供了認(rèn)證、授權(quán)、訪問(wèn)控制、API 注冊(cè)和發(fā)現(xiàn)等機(jī)制。
Controller Manager 負(fù)責(zé)維護(hù)集群的狀態(tài),比如故障檢測(cè)、自動(dòng)擴(kuò)展、滾動(dòng)更新等,Controller Manager 包含多個(gè)可以擴(kuò)展 Controller,例如 Node Controller 負(fù)責(zé)初始化 Node 節(jié)點(diǎn),獲取運(yùn)行中的 Node 信息、Route Controller 負(fù)責(zé)配置集群間通信的路由信息、Service Controller 負(fù)責(zé)監(jiān)聽(tīng)服務(wù)創(chuàng)建、更新、刪除等事件來(lái)調(diào)整負(fù)載均衡信息等等。
Scheduler 負(fù)責(zé)資源的調(diào)度,按照預(yù)定的調(diào)度策略選擇哪個(gè) Pod 運(yùn)行在哪個(gè)節(jié)點(diǎn)上。
另外圖下方的綠色模塊是用來(lái)保存整個(gè)集群的狀態(tài)的 etcd。
圖最左側(cè)的 kubectl 是用于運(yùn)行 K8s 命令的管理工具,kubectl 與 API Server 進(jìn)行交互,通過(guò) API Server 下發(fā)對(duì) K8s 集群的指令。
再來(lái)看圖右側(cè)的 Worker Node。剛才介紹概念時(shí)提過(guò),Node 用來(lái)運(yùn)行應(yīng)用容器,所以 Node 中必須要有一個(gè)容器運(yùn)行時(shí),可以是 Docker,也可以是其他的容器技術(shù),例如 Rkt。
Node 中部署應(yīng)用時(shí),每個(gè)應(yīng)用都由一個(gè) Pod 組成,可以把 Pod 看作一個(gè)虛擬服務(wù)器,上面可以運(yùn)行一個(gè)或多個(gè) Container 容器。當(dāng)應(yīng)用服務(wù)需要多個(gè)進(jìn)程共同協(xié)作時(shí),可以把這些協(xié)作的鏡像打包放在一個(gè) Pod 中,共享 Pod 的存儲(chǔ)和網(wǎng)絡(luò)。比如 istio 中的 Sidecar 代理模式,就是通過(guò)在服務(wù)的 Pod 中注入一個(gè) Sidecar 鏡像來(lái)實(shí)現(xiàn)與服務(wù) IP 綁定,進(jìn)行流量控制的。
看到右面圖中灰色的兩個(gè) Node 模塊,kubelet 負(fù)責(zé)與 Master 通信,它周期性地訪問(wèn) APIcontroller 進(jìn)行檢查和報(bào)告、執(zhí)行容器的操作,維護(hù)容器的生命周期,也負(fù)責(zé) Volume(CVI)和網(wǎng)絡(luò)(CNI)的管理。
kube-proxy 處理網(wǎng)絡(luò)代理和每個(gè)容器的負(fù)載均衡,它通過(guò)改變 iptables 規(guī)則來(lái)控制在容器上的 TCP 和 UDP 包。
K8s 把所有被管理的資源看作對(duì)象,對(duì)資源的管理就變成了對(duì)對(duì)象屬性的設(shè)置。K8s 對(duì)對(duì)象的配置采用 YAML 格式進(jìn)行描述。K8s 中的對(duì)象概念非常多,大致可以分為四類(lèi):
資源對(duì)象,例如 Pod、Job;
配置對(duì)象,例如 Node、Namespace、Service;
存儲(chǔ)對(duì)象,例如 Volume、PresidentVolume;
策略對(duì)象,例如 SecurityContext、ResourceQuota、LimitRange 等等。
如果感興趣,可以在課后練習(xí)。比如最簡(jiǎn)單的,可以在單機(jī)環(huán)境中,使用 Minikube 來(lái)部署 K8s 進(jìn)行練習(xí)。
系統(tǒng)架構(gòu)主要看一個(gè)人的綜合能力和發(fā)展?jié)摿υ趺礃樱疾禳c(diǎn)有這幾個(gè)方面:
第一,要對(duì)分布式架構(gòu)有自己的理解。比如系統(tǒng)可用性、擴(kuò)展性,比如故障的應(yīng)對(duì)方法,包括熔斷、容災(zāi)、流量遷移、多機(jī)房多活;再比如架構(gòu)設(shè)計(jì)中的解耦合等等。
第二,要了解系統(tǒng)架構(gòu)優(yōu)化的常用方法。比如:并行、異步、水平擴(kuò)展和垂直擴(kuò)展、預(yù)處理、緩存、分區(qū)(Sharding)等等。
第三,會(huì)考察對(duì)負(fù)責(zé)的工作了解程度、是否有責(zé)任?。如果連自己負(fù)責(zé)的服務(wù)的部署規(guī)模,調(diào)用量級(jí)都不清楚,怎么能有很強(qiáng)的責(zé)任心呢?
最后一個(gè)是解決問(wèn)題能力,是否能靈活運(yùn)用各種知識(shí)。
加分點(diǎn)主要在于表現(xiàn)出面試者的學(xué)習(xí)能力和思考能力。
第一個(gè),了解業(yè)界最新趨勢(shì),比如 Service Mesh 的思路和要解決的問(wèn)題。
第二個(gè),在介紹項(xiàng)目時(shí),如果有不同方案的選型或?qū)Ρ葧?huì)更好。比如在介紹項(xiàng)目架構(gòu)時(shí),有兩個(gè)方案,一個(gè)是同步方案,一個(gè)是異步方案,這兩個(gè)方案各有什么優(yōu)缺點(diǎn),最后結(jié)合業(yè)務(wù)場(chǎng)景、實(shí)際需求、請(qǐng)求量級(jí) 選擇了某一種。
面試時(shí),一定會(huì)遇到介紹項(xiàng)目這個(gè)問(wèn)題。我見(jiàn)過(guò)的大多數(shù)人在里表現(xiàn)的并不好:要么講不清楚項(xiàng)目的結(jié)構(gòu)與交互流程;要么不能理解項(xiàng)目架構(gòu)為什么要這樣設(shè)計(jì);要么沒(méi)有思考過(guò)項(xiàng)目存在哪些問(wèn)題,有哪些可以改進(jìn)的地方。不僅是針對(duì)面試,在工作中我們更應(yīng)該搞清楚這些問(wèn)題,尤其是工作 1~3 年的工程師們。
那么,在面試中如何更好地介紹自己負(fù)責(zé)的項(xiàng)目?如下所示,圖中這些方法是根據(jù)面試考察點(diǎn)總結(jié)的,并且會(huì)提示每個(gè)方法要重點(diǎn)體現(xiàn)哪些能力。
第一步,要簡(jiǎn)單交代項(xiàng)目背景,讓面試官可以快速進(jìn)入到項(xiàng)目上下文,更容易理解項(xiàng)目架構(gòu)。一般采用 STAR 法則來(lái)進(jìn)行介紹:
Situation 介紹項(xiàng)目背景,比如這個(gè)項(xiàng)目是研發(fā)一個(gè)短視頻 APP,配合公司主客戶端來(lái)交叉提高用戶量與活躍度;
Task 介紹自己的任務(wù),比如我在這個(gè)項(xiàng)目中負(fù)責(zé)后端服務(wù)的架構(gòu)設(shè)計(jì)與研發(fā);
Action 介紹自己做了哪些工作,比如當(dāng)時(shí)用了 2 周時(shí)間做架構(gòu)設(shè)計(jì),4 周時(shí)間做研發(fā),2 周時(shí)間測(cè)試上線;
Result 介紹結(jié)果,這個(gè)也是大部分人容易忽視的部分,比如項(xiàng)目上線后 2 個(gè)月用戶數(shù) 100w,后端服務(wù)接口總量峰值 50000qps,主要接口服務(wù) SLA p99 小于 50ms。
注意背景介紹是為后面詳細(xì)介紹做鋪墊,簡(jiǎn)潔明了即可。這一步主要體現(xiàn)你的表達(dá)能力。
第二步,重點(diǎn)介紹項(xiàng)目的架構(gòu),這也是面試官最想了解的部分。
務(wù)必要結(jié)合架構(gòu)圖、交互流程圖來(lái)介紹,避免對(duì)一些關(guān)鍵問(wèn)題理解歧義。架構(gòu)圖要注意邊界清晰,就是你的服務(wù)與其他依賴(lài)的外部服務(wù)之間的邊界,以及你服務(wù)內(nèi)部模塊之間的邊界都要描述清晰。這有利于你下一步介紹自己做了哪些內(nèi)容。這一步要體現(xiàn)出你對(duì)項(xiàng)目架構(gòu)的理解。
第三步,介紹你在這個(gè)項(xiàng)目中具體做了哪些內(nèi)容,例如我設(shè)計(jì)了整個(gè)架構(gòu),或者我實(shí)現(xiàn)了架構(gòu)圖中的某幾個(gè)模塊。注意這一步是你面試的絕對(duì)加分點(diǎn),必須要把握住。
這里要突出你在項(xiàng)目中做的最有挑戰(zhàn)的點(diǎn)、優(yōu)雅的架構(gòu)設(shè)計(jì)、或者獨(dú)特有效的解決方案。比如在數(shù)據(jù)量非常大的場(chǎng)景下,通過(guò)優(yōu)化 Redis 存儲(chǔ)結(jié)構(gòu),減少了 70% 的 Redis 使用容量;比如對(duì)查詢(xún)接口應(yīng)用雙發(fā)功能使 p999 降低了 60%;再比如使用了 Trace 功能來(lái)快速定位問(wèn)題,等等。這一步要體現(xiàn)出你的實(shí)現(xiàn)能力與亮點(diǎn)。
第四步,要為第三步介紹的優(yōu)秀架構(gòu)或解決方案提供證明,比如前面介紹了系統(tǒng)架構(gòu)中使用模塊化來(lái)提高擴(kuò)展性,那這里就可以說(shuō)系統(tǒng)上線后,通過(guò)模塊化方式支持了 7 個(gè)新業(yè)務(wù)的接入來(lái)體現(xiàn)你設(shè)計(jì)的架構(gòu)的優(yōu)點(diǎn)。
這里要注意,所有的結(jié)果必須是可以量化的,不要用性能大幅提升,極大提高靈活性這類(lèi)很虛的描述。好一點(diǎn)的表述可以是這樣:通過(guò)增加二級(jí)緩存,對(duì)后端服務(wù)的調(diào)用請(qǐng)求從 7000qps 降低到 600qps。這一步要體現(xiàn)出你對(duì)項(xiàng)目的掌握能力和了解程度。
第五步,思考項(xiàng)目存在哪些問(wèn)題,或者還有哪些可以進(jìn)行優(yōu)化的點(diǎn)。
例如,現(xiàn)在項(xiàng)目 QPS 不高,某些任務(wù)是同步處理的,會(huì)有一定效率問(wèn)題,這些處理步驟是可以異步執(zhí)行的,如果請(qǐng)求量級(jí)增加,可以考慮使用 kafka 進(jìn)行異步處理。處理時(shí)還應(yīng)該考慮消息重復(fù)的問(wèn)題,可以把處理邏輯設(shè)計(jì)成冪等性的。這一步要體現(xiàn)你對(duì)項(xiàng)目的思考以及總結(jié)反思能力。
如果我作為面試官,遇到一位按照上面 5 個(gè)方向來(lái)交流的候選人,一定會(huì)非??春盟?。
再來(lái)介紹幾個(gè)備戰(zhàn)面試的小技巧。
第一點(diǎn),肯定要提前思考、提前準(zhǔn)備。
像項(xiàng)目架構(gòu)圖怎么畫(huà)更容易理解,項(xiàng)目中到底哪個(gè)設(shè)計(jì)最有亮點(diǎn),項(xiàng)目還存在哪些可以改進(jìn)的地方等等問(wèn)題,可能要花很多時(shí)間才能找到比較理想的答案,在面試現(xiàn)場(chǎng)臨時(shí)回答難度非常大。一定要根據(jù)我前面的方法,提前準(zhǔn)備。
第二點(diǎn),要記住項(xiàng)目在精不在多。
有的人在介紹項(xiàng)目時(shí),會(huì)拋出好幾個(gè)項(xiàng)目,但每個(gè)項(xiàng)目介紹的都很潦草。在面試中,面試官是想通過(guò)項(xiàng)目介紹來(lái)考察你的各方面能力,一個(gè)重點(diǎn)的項(xiàng)目就足夠了。一定要選你最了解、最能代表你能力的來(lái)介紹。
第三點(diǎn),我了解的,就是我的。
有的同學(xué)可能因?yàn)闄C(jī)遇的原因,沒(méi)有負(fù)責(zé)過(guò)重點(diǎn)的項(xiàng)目,不過(guò)項(xiàng)目介紹這么重要的考察點(diǎn),也不能白白在這里丟分。你可以多了解一下其他同事或團(tuán)隊(duì)負(fù)責(zé)的項(xiàng)目,只要你能把細(xì)節(jié)搞明白,把架構(gòu)理解透,那么知識(shí)就是你的,依然可以拿來(lái)進(jìn)行介紹。
第四點(diǎn),要重點(diǎn)體現(xiàn)對(duì)架構(gòu)的理解,對(duì)設(shè)計(jì)的思考。
這會(huì)讓面試官覺(jué)得你會(huì)很有潛力。你可以在介紹項(xiàng)目設(shè)計(jì)思路時(shí)做適當(dāng)?shù)难由?。例如你可以說(shuō):在我的業(yè)務(wù)場(chǎng)景下,可以容忍低概率的消息丟失,所以基于性能優(yōu)先考慮,去掉了 Kafka 的 ACK 應(yīng)答。如果是嚴(yán)格要求不丟消息的場(chǎng)景,我會(huì)使用同步應(yīng)答,并且使用最高消息可靠性等級(jí)。
至此,《32個(gè)Java面試必考點(diǎn)》的所有內(nèi)容結(jié)束,感謝支持。
聯(lián)系客服