做者 | 於雨 來源|阿里巴巴雲原生公衆號git
本文源自 2020 年 12 月 20 日做者在雲原生社區 meetup 第二期北京站演講 《Apache Dubbo-go 在雲原生時代的實踐與探索》的部份內容,若是對演講完整內容感興趣請訪問: https://www.bilibili.com/video/av245840877程序員
自從以 2013 年開源的 docker 爲表明的的容器技術和以 2014 年開源的 K8s 爲表明的容器編排技術登上舞臺以後,相關技術從業人員從認知和體感上接受,雲原生時代真的到來了。github
固然也有不少資深技術人員認爲,雲原生時代要從 2010s 時以 OpenStack 爲表明的虛機編排時代開始。固然,也有人說其實雲原生技術誕生很早,能夠從巨型機時代在巨型機上虛擬出若干小型機開始追溯。docker
在雲原生時代,不變鏡像做爲核心技術的 docker 定義了不可變的單服務部署形態,統一了容器編排形態的 k8s 則定義了不變的 service 接口,兩者結合定義了服務可依賴的不可變的基礎設施。有了這種完備的不變的基礎設置,就能夠定義不可變的中間件新形態 -- 雲原生中間件。apache
雲原生時代的中間件,包含了不可變的緩存、通訊、消息、事件(event) 等基礎通訊設施,應用只需經過本地代理便可調用所需的服務,無需關心服務能力來源。編程
微服務框架
從最先的單體應用時代到分佈式技術時代,流行的是微服務技術。微服務時代各大公司都沉澱出了具備表明性的一些服務通訊框架,如 Google 的 gRPC,阿里的 Dubbo 和 HSF,百度的 bRPC 等等。多個服務通訊框架之間的競爭,基本上是在大公司之間進行角力。緩存
站在使用者的角度,固然期待一個網絡框架在進化過程當中可以保持向前兼容性,多個框架之間保持互通性。安全
1. 服務框架的向後兼容性
通訊框架的基礎是通訊協議和序列化協議,其中很重要的問題就是新版本協議對舊版本的向後兼容性。在一個組織中通常都使用統一的通訊框架,但現實中可能由於各類緣由,同一個框架的序列化協議或者通訊協議的向後兼容能力差,會致使使用不一樣版本通訊框架的各個服務之間的異構化。如採用了 pb v2 和 pb v3 的通訊框架不兼容,不遑多讓的 Thrift 0.8.x 與 Thrift 0.9.x 之間也不兼容。網絡
不過 Protobuf v3 或者 Protobuf v2 的各個子版本之間的向前和前後兼容性仍是不錯的,但仍是有一些弱雞公司的內部序列化協議不管是否採用 TLV 形式,其協議各個版本的之間仍是沒法兼容,進而致使各個子版本的服務框架相互異構,最終致使使用了不一樣版本的服務框架的業務背上大量包袱沒法快速演進,有些新版本的業務中存在各類神邏輯可能不是爲了兼容舊版本的業務邏輯,而是爲了兼容舊版本框架的通訊協議。架構
2. 多框架之間的互通性
一個常識是,組織規模膨脹到足夠大的程度後,不可能有一個通用的框架適用於全部的場景,一些大經濟實體隨着業務體量變大,業務類型變得龐雜,不可避免地存在一些重複的輪子,這些龐大規模的組織由於其規模效應,任何一個適用於特定場景的框架只要能在內部找到若干落地應用場景就足以讓其開發維護成本變得可負擔且收益甚大。
公司內部各個分公司之間可能存在不一樣服務框架致使各個服務之間通訊異構化愈來愈嚴重,如阿里內部早前存在異構的 Dubbo 和 HSF(目前阿里內部 HSF 和 Dubbo 已經開始融合, HSF 已經採用 Dubbo 做爲內核以 Dubbo 插件的形式存在),如當下的阿里的 HSF 和各個收來的新公司之間的網絡通訊,其間通訊可能不得不借助於 Proxy 形式的通訊網關。
每一個服務框架各個子版本之間須要保持向後兼容,各個服務框架之間的兼容可能須要網關代理。
3. 多語言框架之間的互聯
除了序列化協議、通訊框架的異構外,還廣泛存在着由於各個不一樣語言技術棧之間差別致使的異構:每種語言都有個各自的序列化協議和通訊框架。如 Java 世界就存在着 Spring Cloud 和 Dubbo 兩大服務治理框架,Spring Cloud 尚無多語言版本實現,相比之下 Dubbo 的多語言工做稍好一些。
4. 打通打平不一樣的技術體系
同一實體內部不一樣公司之間有兩三個不一樣服務框架的狀況已經算是很好了,大公司組織內部能夠容忍適量的重複造輪子,但大量的重複造輪子就過猶不及了。聽說有巨頭內部不一樣部門之間存在各自的 RPC 服務框架 ,其整體服務框架超 100+!
隨着國內互聯網行業發展因爲頭部效應趨向性明顯,在大魚吃小魚的時代背景下,大公司與收購來的公司之間的技術體系異構也是雲原生時代中間件面臨的一個問題,兩者之間由於業務規模不一樣帶來的服務註冊中心、配置中心、語言技術棧、服務鑑權、緩存和存儲等諸多技術不統一。有的剛收來的公司甚至使用了大公司的競爭對手的雲平臺,這就又帶來了平臺級的差別,諸如此類的異構問題不一而足。
藉助網絡代理技術,能夠初步快速打通不一樣技術體系之間的異構差別。
5. 通訊代理的必要性
除了南北向通訊的網絡接入層代理外,微服務時代使用同一通訊框架的各個服務實體之間直接進行通訊,不多據說各個服務實體之間經過代理 Proxy 進行通訊,其根由是各個通訊實體之間通訊框架同構。
或者說,網絡通訊代理被各個強悍的通訊框架給消化掉,以 Proxyless SDK 的形式存在,如服務發現、服務路由、容災限流、負載均衡等功能都存在於各個服務框架的 SDK 中。
但隨着多協議多語言等各類因素致使的各個框架之間的各類異化,你們廣泛相信:沒有什麼差別不是一層 Proxy 解決不了的。
6. Service Mesh
2016 年以後興起的 Service Mesh 技術區分爲 Proxy Service Mesh 和 Proxyless Service Mesh,至於兩者之間的差別可參見本文 2019 年的一篇文章 Service Mesh 形態芻議。目前比較流行的 Service Mesh 技術形式是 Proxy Service Mesh,其比較有表明性的組件有數據面的 envoy 和控制面的 Istio。
一些 Service Mesh 技術文檔宣稱,將服務框架的序列化協議、通訊能力、服務治理能力沉澱到服務網格的代理(如 envoy 這類數據面 sidecar)中,可有以下收益:
- 服務框架 SDK 會變的很是輕量,甚至徹底沉澱到 sidecar 中。
- 多語言、多協議和多種通訊方式之間的差別將被磨平。
- 統一流量控制,提高系統的彈性。
- 統一監控設施,提升可觀測性。
- 統一安全可信認證,提高安全性。
- 升級過程業務無感,作到平滑升級,提高可靠性。
- 提高業務版本迭代速度。
- 快速打通不一樣技術治理體系之間的差別。
- 在 Mesh 和 非 Mesh 模式之間快速切換。
有人可能據此誤覺得 Service Mesh 技術可將業務和服務框架的複雜性消滅於無形,將 Istio + sidecar 形式爲表明的服務網格能夠定義爲 Service Mesh 的終極形態。
Sidecar 與中間件
Proxy Service Mesh 的數據面的 sidecar 僅具有通訊能力,業務應用和 sidecar 之間仍然存在一個 gap:微服務時代應用所使用的中間件系統的能力須要沉澱到 sidecar 中。
1. Sidecar 的能力
Proxy Service Mesh 中 sidecar 的一個典型表明是 envoy,其本質是一個具有通訊能力的 local proxy,具有以下數據面能力:
- 流量控制
- 序列化協議轉換
- 通訊協議轉換
- 數據路由控制
實際上, envoy 僅僅是提供了這些能力的接口,至於具體的序列化協議轉換、通訊協議轉換插件等工做仍是須要相關的基礎設施開發人員去作的。
除了序列化協議和通訊協議轉換,中間件的其餘能力向 Proxy 下沉的過程當中,都須要作大量的 envoy filter 層面的工做。相對於 Proxyless 形式的 Service Mesh,Proxy Service Mesh 成本沒有任何變化,其對業務的侵入性也沒有減輕更多。
2. 協議下沉
若是說 Proxyless Service Mesh 形態下的 SDK 升級須要業務層面作不少改造,Proxy Service Mesh 形態下的業務從 Proxyless 向 Proxy 形態升級過程當中改形成本也不可謂不小。若是通訊協議採用了 Protobuf V3,Proxy Serivce Mesh 形態下的業務升級協議時可能作到平滑升級:只升級 Proxy 不用升級業務服務實體。但現實是一些公司內部的私有協議根本作不到向後兼容,其成本就是升級協議時服務網格的 Proxy 和業務實體一塊兒升級,至於指望的平滑升級就很難作到了。
諸般問題的核心是 Local Proxy 沒有統一通訊協議和序列化協議,僅僅注重於流量劫持。
3. 有狀態的應用
Service Mesh 技術的一些愛好者假設服務實體是一個無狀態的服務,其代理也固然是一個無狀態的 sidecar,而後宣傳 Service Mesh 時代的各類紅利。
至於那些有狀態的應用,大公司有人有錢耗費巨量人日成本後,把狀態轉移到 Proxy 中去,讓應用無狀態,但業務無感知的平滑升級是就難作到了。這個成本對大經濟實體來講固然是可負擔且收益甚大的,但不是一些中小廠家所能承受的,他們在踩完各類坑後,可能神奇的發現他們根本沒有實力實現有狀態的 sidecar。
4. 複雜性守恆
總結一番,基於 sidecar 搭建一個 Proxy Service Mesh 可能存在以下工做:
- 不一樣序列化協議轉換
- 不一樣通訊協議之間的轉換
- 同一序列化協議多版本之間的轉換
- 私有和公開通用的序列化協議之間的轉換
- 對單體時代或者微服務時代的業務進行改造升級
- 業務應用和 sidecar 同時升級帶來的額外運營維護
- 有狀態的 Sidecar 的開發測試與維護
- 應用和代理的優雅退出和平滑升級
- 不一樣技術體系之間的互通
- Mesh 模式和非 Mesh 模式之間的切換
面對這些難度層層遞進的工做,中小廠家頗有可能就會退縮到微服務技術體系。其最根本的緣由是:同等級別的業務形態下,技術複雜性守恆,總成本守恆。一如微服務技術至於單體技術:各個單一服務都被拆分的足夠簡單,但單體技術的複雜性轉換爲了巨量服務之間的複雜性。
另外一種 Mesh
以 Service Mesh 技術爲表明的的雲原生技術體系根植於以 K8s 爲表明的的雲原生基礎設施之上。
1. 協議標準化
雲原生中間件 Proxy 的下一站除了被動地去兼容各類協議,更應該主動的去統一序列化協議,如自身直接支持 Protobuf v3 協議,業務也採用這種可保證向後兼容的協議便可。
除了被動地去兼容各類通訊框架作互聯互通,能夠更主動地向事實上的通訊框架 gRPC 或者通訊協議 HTTP 靠攏。gRPC 有各類語言的 SDK 庫。各類語言自身會主動提供 HTTP 通訊協議庫,且 HTTP2.0 向後兼容 HTTP 1.1。例如微軟的 Dapr,就直接提供 gRPC 和 HTTP 兩種通訊協議的 API,上層業務須要作的是選擇其中一種通訊協議的 API 進行開發。
2. Service Proxy
一些的雲原生時代的事實上的標準通訊設施有:2008 年開源的 protobuf v2 和 2014 年開源的 protobuf v3 統一了序列化協議;2016 年 gRPC 發佈 v1 以後逐漸成了跨語言首選的通訊庫。
除了序列化協議和通訊協議,微服務時代的中間件體系大概有以下技術棧:
- RPC,其表明是 Dubbo/Spring Cloud/gRPC 等。
- 限流熔斷等流控,如 hystrix/sentinel 等。
- Cache,其表明是 Redis。
- MQ,其表明有 kafka/rocketmq 等。
- 服務跟蹤,如兼容 Opentracing 標準的各類框架。
- 日誌收集,如 Flume/Logtail 等。
- 指標收集,如 prometheus。
- 事務框架,如阿里的 seata。
- 配置下發,如 apollo/nacos。
- 服務註冊,如 zookeeper/etcd 等。
- 流量控制,如 hystrix/sentinel 等。
- 搜索,如 ElasticSearch。
- 流式計算,如 spark/flink。
把各類技術棧統一到一種事實上的技術標準,才能反推定義出不可變的中間件設施的終態。把上面這些事實上的中間件梳理一番後,總體工做便是:
- 統必定義各服務的標準模型
- 定義這些標準模型的可適配多種語言的 API
- 一個具有通訊和中間件標準模型 API 的 Proxy
- 適配這些 API 的業務
上圖定義一種不一樣於 istio + Envoy 的另外一種可能的 Proxy Service Mesh 進化路徑。該 Service Mesh 模型下的 sidecar 不只僅是一個 Local Proxy,更應該是一個提供各個中間件技術棧標準能力的 Service Proxy。
Service Proxy 多是一個集狀態管理、event 傳遞、消息收發、分佈式追蹤、搜索、配置管理、緩存數據、旁路日誌傳輸等諸多功能於一體的 Proxy, 也多是分別提供部分服務的多個 Proxy 的集合,但對上提供的各個服務的 API 是不變的。
3. Application Mesh
或者更進一步,能夠把 Service Proxy 拆分爲兩個 Proxy:
- 仍然以現有的以劫持網絡流量的 sidecar 形式存在的 Local Proxy。
- 另外一個專門提供各個 Service API 的 Application Proxy。
Application Proxy 能夠是一個獨立存在的進程或者容器,也能夠是一個可被應用調用嵌入式的 SDK 庫。不管是 Proxy 形式仍是 Proxyless 形式,這都是一種新形態的 Service Mesh,可被稱之爲 Application Mesh。 Application Proxy 能夠依賴於 Local Proxy,亦可不依賴。如人們常說的三級緩存其實也是一種 Application Mesh 形態,從進程內的 local cache 到本機(容器、虛擬機 or 物理機)cache proxy 一直回溯到 cache cluster, 應用只須要從 local cache 處獲取數據便可。
固然,Application Mesh 亦可不依賴於特定的基礎設施平臺,包括 k8s,本文就不展開討論了。
除了 Service Mesh 技術帶來的收益,Application Mesh 具備以下更多的收益:
- 更好的擴展性與向後兼容性
基於標準的 API,其服務的不變性獲得極大改善,不變性能夠確保中間件的向後兼容與更好的擴展能力。基於標準 API,第三方服務商能夠在雲廠商提供的基礎設施之上擴展出更多形態的中間件設施。
- 與語言無關
統一序列化協議和通訊協議後,無特定語言依賴是很天然的事情。主流語言都會支持 HTTP 協議,gRPC 庫自身可以提供主流語言的支持。無特定語言綁定帶來的另外一個間接好處是更好的可移植性。
- 與雲平臺無關
經過標準的服務讓應用作到無雲平臺依賴,統一了中間件技術棧的平臺提供的技術能力相同的,雲平臺使用者沒有被雲服務提供商綁架的危險。
- 應用與中間件更完全地解耦
經過標準協議和標準 API 讓應用與中間件完全解耦,讓開發者在開發階段對新類型 Proxy 的有感,作到業務上線後業務對 Proxy 及其底層系統的升級過程無感知,即更好地平滑升級。
- 應用開發更簡單
基於標準 API,應用開發者甚至能夠用單體時代的服務框架開發分佈式應用,提高應用版本迭代速度。
- 更快的啓動速度
狀態從應用轉移到代理後,能夠經過提早預熱代理,讓應用瞬時批量啓動。
將來的收益
任何技術都不是沒有代價的。誠如微服務技術帶來了服務數量的劇增,Service Mesh 技術帶來了吞吐的下降和延時的增長,但下一站的雲原生中間件形態會帶來的是另外一種新的價值形態,相比而言這個代價是能夠接受的。
1. 業務價值
就其淺顯的技術價值而言,作到基礎中間件技術的統一後,便可作到無關語言,無關各個具體的中間件實體。減輕業務開發人員負擔,使其專一於業務邏輯,作到真正的快速迭代與平滑升級,提高研發效率的同時下降各類成本。
2. 雲平臺無關
新形態帶來的商業價值就是無雲平臺依賴,各平臺間相互之間的競爭就不會停留在某種獨有的核心技術優點上,而是在同一技術體系下不斷下降服務成本,提供更好的用戶體驗、更強的服務能力與更親民的價格。 可以且願意實現這種終態 proxy 的組織固然不是各中小型業務廠家,因此統一了這些標準服務 API 的 Proxy 之下的應該是提供這些標準服務的各大雲廠商。越早向統一服務模型靠攏的雲廠商越快得利,越相信本身私有服務能力的雲廠商越孤立。
3. 初創公司的機會
基於大廠提供的基礎設施,能夠孕育出一個獨立的 service proxy 生態:一些第三方的初創廠家專職提供雲原生中間件解決方案。
基於新形態的中間件方案,Low Code 或者 No Code 技術才能更好落地。單體時代的 IDE 才能更進一步 -- 分佈式時代的 IDE,基於各類形態中間件的標準 API 之對這些中間件的能力進行組合,以 WYSIWYG 方式開發出分佈式應用。
4. 打破大廠內部藩籬
對一些大廠組織內部而言,可藉助真正形態的 Service Mesh 技術棧能夠統一大經濟實體內部技術棧,打破人爲的各類異構隔離,提高研發運維效率和物理資源利用效率,下降總體人力與資源的交付運維成本。
5. 走向新時代
以統一技術形態的 Service Mesh 爲基礎的雲原生中間件技術體系真正發起起來,在其之上的 Serverless 纔有更多的落地場景,廣大中小企業才能分享雲原生時代的技術紅利,業務開發人員的編碼工做就會愈來愈少,編程技術也會愈來愈智能--從手工做坊走向大規模機器自動生產時代。
歡迎對 apache/dubbo-go 項目有興趣的同窗歡迎釘釘搜索羣號:31363295,加入交流羣。
做者簡介
於雨(github @AlexStocks),dubbogo 社區負責人,一個有十多年服務端作着基礎架構和中間件研發一線工做經驗的程序員,陸續參與和改進過 Redis/Pika/Muduo/dubbo-go/Sentinel-go 等知名項目,目前在螞蟻金服可信原生部從事容器編排和 service mesh 工做。