新一代的微服務架構 Service Mesh

来源:https://www.cnblogs.com/elfgzp/archive/2020/06/24/13186714.html
-Advertisement-
Play Games

新一代的微服務架構 Service Mesh 博客原文地址 (https://elfgzp.cn/2020/06/21/新一代的微服務架構 Service Mesh 由於最近在工作中在做 Service Mesh 的落地項目,有非常多的感觸,所以想寫一篇文章來分享這個「新一代的微服務架構 Servi ...


新一代的微服務架構 Service Mesh

博客原文地址 (https://elfgzp.cn/2020/06/21/新一代的微服務架構 Service Mesh

由於最近在工作中在做 Service Mesh 的落地項目,有非常多的感觸,所以想寫一篇文章來分享這個「新一代的微服務架構 Service Mesh」。

筆者會從以下順序開始分享:

  • Part 1 從「單體應用架構」到「微服務架構」開始說起
  • Part 2 從「Docker」到 「K8s」
  • Part 3 從「邊車模式」到「服務網格」
  • Part 4 用「Istio Demo」來講一個實際的應用場景

首先會從 「單體應用架構」 演進到 「微服務架構」 產生的問題開始說起,到自己作為開發人員感觸最深的痛點。

然後簡單介紹以下今天的主角 Istio 的服務編排環境 Kubernetes

最後從 Sidecar 這種設計,說到 Service Mesh,最後到我們的主角 Istio

到正式的主角之前的鋪墊會比較多,這是為了讓大多數開發者都能理解。

本文大部分內容都整理自筆者的學習資料加上自己的一些總結和體會,大家最後可以從文末找到他們。

Part 1「單體應用架構」到「微服務架構」開始說起

1.1 單體應用架構與微服務架構對比

「單體」「分散式」演進(也就是微服務化)的原因我相信大家都很瞭解了。

因為業務量越來越大,我們需要多台機器才能應對大規模的應用,所以需要垂直或者水平拆分業務系統,讓其變成一個分散式的架構

從上面的表格我們可以看到,分散式系統雖然有一些優勢,但也存在一些問題。

  • 架構設計變得複雜。
  • 部署單個服務會比較快,但是如果一次部署需要多個服務,流程會變得複雜。
  • 系統的吞吐量會變大,但是響應時間會變長。
  • 運維複雜度會因為服務變多而變得很複雜。
  • 架構複雜導致學習曲線變大。
  • 測試和查錯的複雜度增大。
  • 技術多元化,公司中可能會有多個技術棧,這會帶來維護和運維的複雜度。
  • 管理分散式系統中的服務和調度變得困難和複雜。

作為業務開發人員最直觀的感受

  • 介面為什麼這麼慢,明明只依賴了一個服務。我需要更新我的服務,但是哪些服務依賴了我的服務,這次更新會對哪些服務造成影響。
  • 我需要在代碼框架層編寫客戶端接入監控、日誌、鏈路追蹤、告警、健康檢查等各種各樣非業務相關的代碼
  • 測試很不方便,測試一個服務需要所有依賴的服務,測試環境資源緊張。
  • ...

1.2 微服務架構的痛點和需要解決的問題

總結來說,微服務架構有這些痛點和需要解決的問題:

  • 服務多,服務之間的依賴難以管理。
  • 服務之間的版本管理,不同版本的服務可能會有相容性的問題。
  • 需要對整體架構監控,快速發現問題。
  • 資源調度管理。
  • 需要做流量控制。負載均衡、服務路由、熔斷、降級、限流、灰度發佈等流量相關的控制。

圖片引用自 《左耳聽風 - 分散式系統技術棧》

針對這麼多的需要去解決和處理的問題。

引出了我們今天的主角 Istio

在介紹我們今天的主角 Istio 之前,先簡單介紹一下它的服務編排環境 Kubernetes。通過 Docker 以及其衍生出來的 Kubernetes 之類的軟體或解決方案,大大地降低了做上面很多事情的門檻。

Part 2「Docker」到 「K8s」

2.1 Docker 容器的本質

Docker 相信大家都非常瞭解了,所以這裡我就從 Docker 過度講到 k8s

Docker 容器這個聽起來玄而又玄的概念,實際上是在創建容器進程時,指定了這個進程所需要啟用的一組 Namespace 參數。這樣,容器就只能“看”到當前 Namespace 所限定的資源、文件、設備、狀態,或者配置。而對於宿主機以及其他不相關的程式,它就完全看不到了。

int pid = clone(main_function, stack_size, CLONE_NEWPID | SIGCHLD, NULL);

我們知道,在 Linux 系統中創建線程的系統調用是 clone(),就像這樣。而當我們用 clone() 系統調用創建一個新進程時,就可以在參數中指定 CLONE_NEWPID 參數。這時,新創建的這個進程將會“看到”一個全新的進程空間,在這個進程空間里,它的 PID1。之所以說“看到”,是因為這隻是一個“障眼法”,在宿主機真實的進程空間里,這個進程的 PID 還是真實的數值,比如 100

所以說,容器,其實是一種特殊的進程而已。

感興趣的同學可以閱讀 《自己動手寫 Docker》 和嘗試一下書中的代碼。

2.2 K8s 最小調度單位 Pod

我花了很多精力去學習 Linux 容器的原理、理解了 Docker 容器的本質,終於, Namespace 做隔離, Cgroups 做限制, rootfs 做文件系統” 這樣的“三句箴言”可以朗朗上口了。

為什麼 Kubernetes 又突然搞出一個 Pod 來呢?

這裡提一個概念: Pod, 是 Kubernetes 項目中最小的 API 對象。如果換一個更專業的說法,我們可以這樣描述: PodKubernetes 項目的原子調度單位。

這裡通過一個實際的例子來說明:

我們通過 pstree 查看操作系統中運行的進程,進程並不是“孤苦伶仃”地獨自運行的,而是以進程組的方式,“有原則地”組織在一起。

比如,這裡有一個叫作 rsyslogd 的程式,它負責的是 Linux 操作系統里的日誌處理。可以看到, rsyslogd 的主程式 main, 和它要用到的內核日誌模塊 imklog 等,同屬於 1632 進程組。這些進程相互協作,共同完成 rsyslogd 程式的職責。

如果說 「Docker 容器」的其實就是一個「特殊的進程」。

那麼「K8s」就可以理解成操作系統。

Kubernetes 所做的,其實就是將 “進程組” 的概念映射到了容器技術中,並使其成為了這個雲計算 “操作系統” 里的 “原子調度單位”

不過,相信此時你可能會有第二個疑問:

對於初學者來說,一般都是先學會了用 Docker 這種單容器的工具,才會開始接觸 Pod。而如果 Pod 的設計只是出於調度上的考慮,那麼 Kubernetes 項目似乎完全沒有必要非得把 Pod 作為“原子調度單位”吧?

首先,關於 Pod 最重要的一個事實是:它只是一個邏輯概念

具體的說: Pod 里的所有容器,共用的是同一個 Network Namespace,並且可以聲明共用同一個 Volume

那這麼來看的話,一個有 AB 兩個容器的 Pod,不就是等同於一個容器(容器 A)共用另外一個容器(容器 B)的網路和 Volume ?這好像通過 docker run --net --volumes-from 這樣的命令就能實現,就像這樣。

但是,你有沒有考慮過,如果真這樣做的話,容器 B 就必須比容器 A 先啟動,這樣一個 Pod 里的多個容器就不是對等關係,而是拓撲關係了。

所以,在 Kubernetes 項目里, Pod 的實現需要使用一個中間容器,在這個 Pod 中,中間容器永遠都是第一個被創建的容器,而其他用戶定義的容器,則通過 Join Network Namespace 的方式,與 中間容器關聯在一起。

圖片引用自 《Service Mesh 實戰:用 Istio 軟負載實現服務網格 3.1.3 Pause 容器》

圖片引用自 《深入剖析Kubernetes - 為什麼我們需要 Pod》

如上圖所示,這個 Pod 里有兩個用戶容器 AB,還有一個中間容器容器。很容易理解,在 Kubernetes 項目里,中間容器一定要占用極少的資源,所以它使用的是一個非常特殊的鏡像,叫作: k8s.gcr.io/pause。這個鏡像是一個用彙編語言編寫的、永遠處於“暫停”狀態的容器,解壓後的大小也只有 100~200 KB 左右。

這裡就不再深入說明瞭,感興趣的可以點擊圖片鏈接,或者在文章末尾我列出的參考資料。

其中 Pod 的一個重要的特性,它的所有容器都共用同一個 Network Namespace。這就使得很多與 Pod 網路相關的配置和管理,也都可以交給 Sidecar 完成,而完全無須干涉用戶容器。

這裡最典型的例子莫過於 Istio 這個微服務治理項目了。

接下來就從 SidecarService Mesh 來一步一步介紹 Istio 的設計思想。這裡提到的 Sidecar 到底是什麼呢, Sidecar 在國內翻譯為邊車模式,這個翻譯真的很形象。

Part 3「邊車模式」到「服務網格」

3.1 邊車模式

所謂的邊車模式,對應於我們生活中熟知的邊三輪摩托車。

圖片引用自 《左耳聽風 - 管理設計篇“邊車模式”》

我們可以通過給一個摩托車加上一個邊車的方式來擴展現有的服務和功能。這樣可以很容易地做到 "控制 ""邏輯" 的分離。

也就是說,我們不需要在服務中實現控制面上的東西,如監視、日誌記錄、限流、熔斷、服務註冊、協議適配轉換等這些屬於控制面上的東西,而只需要專註地做好和業務邏輯相關的代碼,然後,由“邊車”來實現這些與業務邏輯沒有關係的控制功能。

圖片引用自 《左耳聽風 - 管理設計篇“邊車模式”》

那最終這個 Sidecar 的效果就會像上圖所示。

那麼在 Istio 中, [Envoy](https://github.com/envoyproxy/envoy) 就是預設的 Sidecar。它與服務容器在同一個 Pod 中,與服務容器共用同一個 Network Namespace,接管所有經過服務容器的流量。

圖片引用自 《Kubernetes Istio Canary Deployment》

3.2 服務網格

然後, Sidecar 集群就成了 Service Mesh。圖中的綠色模塊是真實的業務應用服務藍色模塊則是 Sidecar, 其組成了一個網格。而我們的應用服務完全獨立自包含,只需要和本機的 Sidecar 依賴,剩下的事全交給了 Sidecar

圖片引用自 《左耳聽風 - 管理設計篇之“服務網格”》

Service Mesh 這個服務網路專註於處理服務和服務間的通訊。其主要負責構造一個穩定可靠的服務通訊的基礎設施,並讓整個架構更為的先進和 Cloud Native。在工程中, Service Mesh 基本來說是一組輕量級的服務代理和應用邏輯的服務在一起,並且對於應用服務是透明的

說白了,就是下麵幾個特點。

  • Service Mesh 是一個基礎設施
  • Service Mesh 是一個輕量的服務通訊的網路代理
  • Service Mesh 對於應用服務來說是透明無侵入的。
  • Service Mesh 用於解耦和分離分散式系統架構中控制層面上的東西。

3.3 Istio 與 Service Mesh

我們今天的主角 Istio,它的偉大之處不只是在設計本身,而是在於它是一個相容並包的生態。它為整個行業提供了一種全新的開發及運維的方式。

圖片引用自 zhaohuabing/istio-practice

微服務架構在網路鏈路上還有很多待解決的點,如鏈路跟蹤、分散式日誌、監控報警、壓測演練、故障註入等。若讓 Istio 官方來實現所有的功能,不僅耗時,還會讓整個系統變得非常臃腫。

接下來就用 Istio 的官方 Demo 來講一個實際的應用場景。

Part 4 用「Istio Demo」來講一個實際的應用場景

這部分會用 Istio 官方的 Demo 來演示,所以本文的大部分內容都可以在官方文檔中找到。

如果有感興趣的同學可以跟著這個 Demo 來實踐,但是可能需要一個 K8s 集群,這裡推薦使用 Google Cloud Platform 的免費試用服務 GCP Free Tier - Free Extended Trials and Always Free

當然如果想自己折騰搭建 K8s 集群的同學可以參考筆者的這篇文章 「K8s 學習日記」Kubeadm 部署 kubernetes 集群

但是筆者還是建議使用谷歌的服務,體驗雲原生的方式。

4.1 Istio Demo「Bookinfo 應用」服務架構

Bookinfo 應用分為四個單獨的微服務:

  • productpage. 這個微服務會調用 details 和 reviews 兩個微服務,用來生成頁面。
  • details. 這個微服務中包含了書籍的信息。
  • reviews. 這個微服務中包含了書籍相關的評論。它還會調用 ratings 微服務。
  • ratings. 這個微服務中包含了由書籍評價組成的評級信息。

reviews 微服務有 3 個版本:

  • v1 版本不會調用 ratings 服務。
  • v2 版本會調用 ratings 服務,並使用 1 到 5 個黑色星形圖標來顯示評分信息。
  • v3 版本會調用 ratings 服務,並使用 1 到 5 個紅色星形圖標來顯示評分信息。

下圖展示了這個應用的端到端架構。

圖片引用自 《 ISTIO 文檔示例 BOOKINFO 應用》

對 Reviews-v2、Reviews-v3 服務進行測試

在實際的應用場景中,我們當前發佈了兩個 Reviews 服務的 feature 版本 v2v3 版本。但是如果需要對這些服務進行測試。

為了開發人員在測試自己開發的 Review 服務不受影響,我們可能需要部署多個完整的 Bookinfo 應用Product pageRatingsDetails 的服務都需要部署,如下圖所示 。

官方的 BookInfo 中的微服務數量還是比較少的,在實際的場景中,一個完整的系統可能會有成百上千個微服務共同支撐和運行,如果為了開發測試方便就需要龐大的伺服器資源提供給微服務進行部署,這也是目前筆者公司的一個痛點。

利用 Istio 對流量進行控制

在官方的 demo 中,有這樣一個例子。

將來自名為 Jason 的用戶的所有流量路由到服務 reviews:v2。將請求頭中 end-user 值為 jason

的所有請求指向 reviews:v2

正常來說,這樣的功能應該需要在具體語言的 Web 框架層進行實現,但是由於 IstioSidecar 接管了所有的流量,這個功能就在 Istio 中已經集成了。

對於開發人員來時也就是簡單的一個配置和一行命令:

$ kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml
$ kubectl get virtualservice reviews -o yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
  ...
spec:
  hosts:
  - reviews
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    route:
    - destination:
        host: reviews
        subset: v2
  - route:
    - destination:
        host: reviews
        subset: v1

Istio 的流量控制放到實際的應用場景中時,測試環境就只需要一套完整的服務,和一些需要測試的不同版本的服務了。

當然這隻是其中一個應用場景,流量控制還可以用於 A/B 測試,灰度發佈等。並且這隻是 Istio 的其中一個功能。

筆者也不一一去介紹 Istio 的其他功能了,如:服務安全、鏈路追蹤、網路拓撲、服務註冊等等服務治理相關的功能,感興趣的同學可以閱讀官方文檔。

除了官方給出的 demo , 感興趣的同學還可以在這個網站上找到更多的例子,https://istiobyexample.dev/

結尾

以上就是筆者想分享的全部內容,在這個雲計算時代,筆者相信 Service Mesh 將會成為微服務架構中的一個佼佼者,幫助我們更好治理微服務架構。

參考文獻

本文由博客一文多發平臺 OpenWrite 發佈!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 變數&&語法 函數體內局部變數優先順序高於全局變數 函數內的變數聲明將提升至函數體頂部,同時在原位置完成初始化var聲明 在for迴圈中使用var聲明變數時,該變數的作用域為for迴圈所屬函數。 var a=[]; for(var i = 0;i<10;i++){ var q = i; a[i]=fu ...
  • it行業學歷 只是在闡述一個事實。目前隨便打開-家招聘網站的IT崗位,不管是開發、測試還是運維等等,基本上都是要求至少大專及以上學歷(大型企業都至少是985、211本科畢業),當然還沒達到全部的用人企業都要求那麼誇張 作為你來說,技術自我感覺還可以,至少說明你學習能力還可以,也有進取心,你不比別人差 ...
  • 客戶有個網站要改版,找新來的設計重新做了圖 設計圖紙上是一排5個顯示,字體用的22px。當然,px設計圖是750px寬度的,用iphone6來模擬的話,跟實際顯示存在2倍關係,也就是實際字體是11px,我表示無法實現,改成了12px大小 設計圖長這樣 寫前端的時候我改成了12px,畫風瞬間變得十分局 ...
  • 作者:愛前端不愛戀愛鏈接:https://zhuanlan.zhihu.com/p/143590337來源:知乎著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。 1.郵箱 export const isEmail = (s) => { return /^([a-zA-Z0-9_- ...
  • 如今,隨著物聯網時代的到來和網路營銷的日益發展,前端技術比以往更加火熱。我們可以看到Web應用與新技術趨勢緊密相連,而這直接導致了前端行業廣闊的就業前景。正因如此,學習前端的朋友越來越多了。為了幫助大家可以更高效地學習,本文為大家總結了一些零基礎開始學前端的建議,希望大家可以少走一些不必要的彎路。 ...
  • onload和window.onload的使用時的區別? 1.onload在標簽元素中使用。 2.window.onload在script中直接使用。 3.當出現多個onload,總是最後的覆蓋前面出現的,也就是只使用最後一次出現的onload的內容 註意:在body裡面使用window.onloa ...
  • 在 JavaScript 中, null 用於對象, undefined 用於變數,屬性和方法。 對象只有被定義才有可能為 null,否則為 undefined。 如果我們想測試對象是否存在,在對象還沒定義時將會拋出一個錯誤。 正確的方式是我們需要先使用 typeof 來檢測對象是否已定義: if ...
  • 一、微服務架構設計中經常需要處理的問題羅列: API Gateway 內部服務間互相調用 服務發現 服務容錯、熔斷、降級 服務部署 數據處理 二、設計模式 1、微服務-聚合器設計模式: 聚合器調用多個服務實現應用程式所需的功能。它可以是一個簡單的 WEB 頁面,將檢索到的數據進行處理展示。它也可以是 ...
一周排行
    -Advertisement-
    Play Games
  • Dapr Outbox 是1.12中的功能。 本文只介紹Dapr Outbox 執行流程,Dapr Outbox基本用法請閱讀官方文檔 。本文中appID=order-processor,topic=orders 本文前提知識:熟悉Dapr狀態管理、Dapr發佈訂閱和Outbox 模式。 Outbo ...
  • 引言 在前幾章我們深度講解了單元測試和集成測試的基礎知識,這一章我們來講解一下代碼覆蓋率,代碼覆蓋率是單元測試運行的度量值,覆蓋率通常以百分比表示,用於衡量代碼被測試覆蓋的程度,幫助開發人員評估測試用例的質量和代碼的健壯性。常見的覆蓋率包括語句覆蓋率(Line Coverage)、分支覆蓋率(Bra ...
  • 前言 本文介紹瞭如何使用S7.NET庫實現對西門子PLC DB塊數據的讀寫,記錄了使用電腦模擬,模擬PLC,自至完成測試的詳細流程,並重點介紹了在這個過程中的易錯點,供參考。 用到的軟體: 1.Windows環境下鏈路層網路訪問的行業標準工具(WinPcap_4_1_3.exe)下載鏈接:http ...
  • 從依賴倒置原則(Dependency Inversion Principle, DIP)到控制反轉(Inversion of Control, IoC)再到依賴註入(Dependency Injection, DI)的演進過程,我們可以理解為一種逐步抽象和解耦的設計思想。這種思想在C#等面向對象的編 ...
  • 關於Python中的私有屬性和私有方法 Python對於類的成員沒有嚴格的訪問控制限制,這與其他面相對對象語言有區別。關於私有屬性和私有方法,有如下要點: 1、通常我們約定,兩個下劃線開頭的屬性是私有的(private)。其他為公共的(public); 2、類內部可以訪問私有屬性(方法); 3、類外 ...
  • C++ 訪問說明符 訪問說明符是 C++ 中控制類成員(屬性和方法)可訪問性的關鍵字。它們用於封裝類數據並保護其免受意外修改或濫用。 三種訪問說明符: public:允許從類外部的任何地方訪問成員。 private:僅允許在類內部訪問成員。 protected:允許在類內部及其派生類中訪問成員。 示 ...
  • 寫這個隨筆說一下C++的static_cast和dynamic_cast用在子類與父類的指針轉換時的一些事宜。首先,【static_cast,dynamic_cast】【父類指針,子類指針】,兩兩一組,共有4種組合:用 static_cast 父類轉子類、用 static_cast 子類轉父類、使用 ...
  • /******************************************************************************************************** * * * 設計雙向鏈表的介面 * * * * Copyright (c) 2023-2 ...
  • 相信接觸過spring做開發的小伙伴們一定使用過@ComponentScan註解 @ComponentScan("com.wangm.lifecycle") public class AppConfig { } @ComponentScan指定basePackage,將包下的類按照一定規則註冊成Be ...
  • 操作系統 :CentOS 7.6_x64 opensips版本: 2.4.9 python版本:2.7.5 python作為腳本語言,使用起來很方便,查了下opensips的文檔,支持使用python腳本寫邏輯代碼。今天整理下CentOS7環境下opensips2.4.9的python模塊筆記及使用 ...