來源:北大青鳥總部 2023年02月10日 09:59
在云計算時代有三大利器—容器技術(shù)、devops、微服務(wù),容器技術(shù)如docker、kubernetes幫助我們以最小成本快速部署應(yīng)用程序。devops則是研發(fā)運維一體化思想,從管理和技術(shù)上推進產(chǎn)品的快速迭代。
微服務(wù)則是互聯(lián)網(wǎng)架構(gòu)經(jīng)歷了從單體架構(gòu)—>集群架構(gòu)—>分布式架構(gòu)的產(chǎn)物,每一次的技術(shù)架構(gòu)升級背后是新的設(shè)計理念,用以解決數(shù)據(jù)和業(yè)務(wù)復(fù)雜度增加帶來的技術(shù)問題。
而今天我們要介紹的便是微服務(wù)架構(gòu)的核心技術(shù)的辛酸演變史~
微服務(wù)架構(gòu)的設(shè)計思想包括服務(wù)原子化、獨立進程、輕量級通信、獨立部署、基于業(yè)務(wù)能力,典型的微服務(wù)架構(gòu)如下所示。
將業(yè)務(wù)拆分成了服務(wù)A、服務(wù)B、服務(wù)C,對于服務(wù)的管理使用服務(wù)配置中心,對于服務(wù)與服務(wù)之間的發(fā)現(xiàn)使用服務(wù)注冊中心,對于服務(wù)如何與客戶端通信采用服務(wù)網(wǎng)關(guān)來實現(xiàn)身份認(rèn)證、路由等內(nèi)容,其中微服務(wù)的核心技術(shù)無疑是服務(wù)發(fā)現(xiàn)與負(fù)載均衡。試想我們把原來的單體式架構(gòu)從1個服務(wù)拆分成微服務(wù)(比如10個),這個時候運維人員在系統(tǒng)中配置10個微服務(wù)的名稱,再指定這10個微服務(wù)的上下游關(guān)系(即如何從一個微服務(wù)到另外一個微服務(wù)),這個還是相對容易的。
再試想如果把1個服務(wù)拆分成100個微服務(wù),這時候需要給100個微服務(wù)命名,還要定義好不同的微服務(wù)之間如何找尋到其它的微服務(wù),以后如果是某個微服務(wù)掛掉了或者下線了,還需要去找到這個微服務(wù)以及解除它所帶來的與其它服務(wù)之間的聯(lián)系,這時候就有點挑戰(zhàn)了。
再再試想如果把1個服務(wù)拆分成1000個微服務(wù),要定義這1000個微服務(wù)的名稱,還要定義這1000個微服務(wù)之間的道路,有個微服務(wù)掛掉了還得找到它并且解除與它相關(guān)的服務(wù)聯(lián)系,這時候就是tobe or to die,that’sa question;所以微服務(wù)的核心技術(shù)是服務(wù)發(fā)現(xiàn)與負(fù)載均衡,你服不服?
那么微服務(wù)架構(gòu)是如何來解決服務(wù)之間的配置與發(fā)現(xiàn)問題呢?從服務(wù)演變成微服務(wù)的規(guī)模(1—>10—>100—>1000)以及不同互聯(lián)網(wǎng)公司的現(xiàn)況也有三個階段的解決方案:
這個階段,微服務(wù)的數(shù)量還比較少,不需要關(guān)注微服務(wù)的名稱,采用的解決方案是使用代理proxy—DNS解析&F5硬件負(fù)載均衡&Nginx服務(wù)端負(fù)載均衡。使用DNS建立域名與IP地址之間的映射關(guān)系,使用負(fù)載均衡技術(shù)將客戶端請求根據(jù)配置策略引到不同的微服務(wù)上提供服務(wù)。
這是目前大部分互聯(lián)網(wǎng)公司的做法,將代理(包括服務(wù)發(fā)現(xiàn)和負(fù)載均衡邏輯)以客戶庫的形式嵌入在服務(wù)中,再結(jié)合單獨的服務(wù)注冊中心組件進行配合使用,服務(wù)啟動時自動到注冊中心registry進行注冊,并通過定期的心跳請求與registry保持聯(lián)系,而服務(wù)的調(diào)用方(consumer)通過與registry請求獲取服務(wù)地址并放在負(fù)載均衡軟件中。
當(dāng)下比較流行的Spring cloud框架便是這種設(shè)計模式,使用eureka來做注冊中心,使用ribbon來進行客戶端代理做負(fù)載均衡。
服務(wù)注冊中心的邏輯流轉(zhuǎn)圖如下所示,服務(wù)A與服務(wù)B在啟動時向服務(wù)注冊中心上報自己提供的服務(wù)和IP地址,服務(wù)C告訴服務(wù)注冊中心自己需要的服務(wù),獲取服務(wù)地址后進行服務(wù)A、服務(wù)B的調(diào)用,同理服務(wù)A與服務(wù)B的調(diào)用也按此進行。
服務(wù)配置中心是解決微服務(wù)數(shù)量超過一定程度時候的問題,因為在每個服務(wù)里分別維護一個服務(wù)的配置問題,實在太難了。
通過在配置中心存儲服務(wù)的名字和IP地址,每次發(fā)生服務(wù)調(diào)用時從該配置中心進行獲取,如果服務(wù)的IP地址有所變更,直接更新配置中心即可。
因為方案1是使用負(fù)載均衡來進行代理,如果負(fù)載均衡的服務(wù)器掛掉了,那么整個業(yè)務(wù)就掛掉了,隨著微服務(wù)數(shù)量的增加會產(chǎn)生問題。
方案2則是客戶端負(fù)載,嵌入了服務(wù)負(fù)載均衡的SDK后,比較難以維護整個負(fù)載均衡,加上無法支持多語言,也比較麻煩。這時候產(chǎn)生的service mesh服務(wù)網(wǎng)格方案便可解決如上的問題。
service mesh服務(wù)網(wǎng)格的核心設(shè)計思想是sidecar邊車模式(像下圖戰(zhàn)爭時期摩托車的設(shè)計一般,主位置是戰(zhàn)斗員,附位置是幫助主駕駛提供彈藥等工作),在每個微服務(wù)(主進程)啟動的時候同時再啟動一個進程,為主進程提供支持,并共享生命周期。
在整個業(yè)務(wù)運行的過程中,附進程處理服務(wù)之間的通信、服務(wù)注冊、負(fù)載均衡、認(rèn)證鑒權(quán)、熔斷限流、上報日志、監(jiān)控的任務(wù),把階段2的服務(wù)注冊eureka、服務(wù)網(wǎng)關(guān)zuul、服務(wù)配置中心如etcl的活全干了。目前業(yè)內(nèi)也有些不錯的servicemesh落地方案,如linkerd、istio等。
服務(wù)A和服務(wù)B只負(fù)責(zé)業(yè)務(wù)邏輯的處理,而所有的服務(wù)發(fā)現(xiàn)、負(fù)載均衡等工作全由單獨的進程sidecar來進行。
因為是單獨的進程,所以對于所有的開發(fā)語言都能支持,只需要主進程能與附進程保持通信即可。對于這些sidecar的管理都集中在控制面板controlplane,實現(xiàn)了集中治理,保障了微服務(wù)的高可靠性。
如果從服務(wù)視角來看,整個業(yè)務(wù)服務(wù)劃分成微服務(wù)后就如下圖所示,綠色表示微服務(wù)的業(yè)務(wù)邏輯處理,藍色代表sidecar進程處于微服務(wù)之間的通信與負(fù)載均衡,它們鏈接起來后就像網(wǎng)格一樣,這也是服務(wù)網(wǎng)格servicemesh的由來~
其實在我們的生活中也有類似的場景,在北京地鐵剛開通運行時,每個換乘站都會有售票員,根據(jù)用戶要到達的地方進行對應(yīng)地鐵票的售賣,這時候的售票員就像微服務(wù)第一階段的proxy,將用戶指引到目的地。
但是隨著地鐵出行越來越方便,大家也越來越喜歡地鐵出行了,地鐵的人流量開始增長,這時候售票員逐漸的忙不過來了,此時地鐵站的配置升級為工作人員+自動售票機,自動售票機呈現(xiàn)了整個北京地鐵圖情況,用戶根據(jù)自己的出行情況選擇目的地,這時候的自動售票機就像微服務(wù)第二階段的客戶端嵌入式代理一樣,用戶自己選擇目的地。
而到現(xiàn)在,隨著互聯(lián)網(wǎng)和經(jīng)濟的快速發(fā)展,北京各地鐵口已升級為全自動售票機,再也沒有人工售票窗口了,用戶在自動售票機根據(jù)自己的出行情況選擇目的地即可。
如果站在整個北京市地鐵的宏觀上看,每個地鐵站全配置自動售票機,地鐵站即我們的微服務(wù),售票機即sidecar,整個配合形成了subwaymesh,在微服務(wù)里即servicemesh~
servicemesh無疑是當(dāng)下微服務(wù)技術(shù)的最好詮釋,它屏蔽了分布式系統(tǒng)的復(fù)雜性,解決了服務(wù)之間復(fù)雜的發(fā)現(xiàn)與調(diào)用過程,讓開發(fā)團隊可專注于業(yè)務(wù)邏輯的實現(xiàn),聚焦真正的價值提供。
就像北京地鐵全升級為自動售票機一樣,屏蔽了來自全國各地人群語言不一致的復(fù)雜性,解決了購買地鐵票繁瑣的收錢找零充值過程,讓地鐵服務(wù)真正便捷的方便用戶。