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