Service Mesh 在华为公有云的实践
我們在構建微服務而構建微服務是困難的
微服務是一個很大的概念,從團隊組織到最佳實踐似乎都有實施微服務的一些指導。我們這里只提構建微服務的架構模式,也就是關乎到你用什么樣的方式來構建你以微服務架構來組織的應用系統。
近些年隨著微服務的火熱,越來越多的團隊開始進行實踐,將微服務紛紛落地,也許你是從0開始,一步步地完成了單體應用向微服務的轉型,讓我們來看看,你解決了多少問題。
我相信最難的部分之一就是調用你的服務。
微服務將原本內存中函數的調用轉換為網絡中的調用后,就牽扯到這些問題,而任何一個分支展開,都會涉及一系列的問題。業務開發者也許真的有精力去學習架構相關的復雜問題,然而對于公司來說,真正有價值的是業務本身,讓業務開發者解決這些問題需要花費浪費大量的時間精力,導致業務上線受到影響。那我們來看看是否有便捷的方式來解決業務開發者的痛點。
Chassis模式
一句話來概括:一種語言開發框架來作為微服務開發的底座,封裝掉復雜性,幫助你解決跨網絡帶來的問題,讓用戶聚焦在上層業務邏輯的開發。通常情況下會實現以下功能:
日志、Metrics、分布式追蹤數據上報
健康檢查
對接統一的配置中心實現動態配置
對接注冊中心
實現負載均衡、熔斷降級、容錯、限流等保證高可靠運行的功能
現在我們來看看業界有哪些可用的Chassis框架:
Spring Cloud
ServiceComb
Dubbo
Go-Micro
Go-Kit
先不細去糾結微服務的嚴格定義,也先暫且擱置諸如“某些老舊框架是否是真的微服務框架”這類爭議,從實現方式來看,上述服務化框架都是將分布式系統開發的復雜性進行了一定程度的封裝然后提供了簡便的開發接口供使用者調用。
但是,用這種方式構建微服務還有一些問題:
多語言SDK支持:微服務提倡不同組件使用最適合它的語言開發,但是這需要每種語言都有開發框架,不斷實現相同的功能。上面可以看到只有go語言和Java語言出現了微服務開發框架,其他語言呢?
不論代碼侵入程度,都需要開發者思考如何與SDK結合,并從代碼層面做出改變,對于大部分開發者來說都是一個高曲線的學習過程。
綁定了特定技術棧,不容易改造。
老舊單體應用由于無人維護,耦合程度高等問題無法進行改造,在進行微服務拆分的過程中重用遺留代碼變得無比困難。而且微服務的拆分難以分步進行,需要一個相對較長的周期將系統整體拆分后才能上線。
我們知道技術演進來自于在實踐中不斷地將功能抽象,解耦,封裝,服務化。
云計算技術出現前是數據中心虛擬化,不斷地實踐使技術發展形成理論和新的實踐。IaaS是一種封裝,如今開發者與大部分技術團隊不需要再學習虛擬化等技術以及如何維護數據中心。
沒有TCP/IP的時代,開發人員需要自己考慮網絡間數據包的傳輸,以及網絡傳輸代碼與業務代碼完全耦合的問題,如今,開發者已經不需要關心,操作系統和開發語言已經封裝好網絡傳輸過程。
是否也可以把語言框架提供的能力抽象,成為服務?很多問題是開放性的解法,上學時大家體會很深一道難題會有很多解法。
在引入后面內容前,我先介紹下SideCar模式。
SideCar模式
在近些年受到Kubernetes對容器調度方式的啟示而日漸受到關注的一種功能部署模式,也是一種微服務的設計模式。
主要利用了容器可以共享存儲與網絡的能力,或者說在一個Host中,這個模式也同樣適用。
一般分為應用容器和工具容器,工具容器可以重用。
一個典型的場景如下:
應用容器與日志同步工具在同一個Pod下,共享存儲卷,應用程序生成的日志文件會由日志同步工具收集并發送到類似kafka,elasticsearch這樣服務中。
在這樣的架構下我們獲得了什么呢?
以容器作為基礎打包單元,那么就可以分給不同的團隊進行開發測試
Sidecar容器可重用,可以與不同的容器結合
以容器作為錯誤邊界,使服務能夠獨立開發和測試,比如應用服務在沒有日志保存功能的情況下也可以獨立運行
獨立回滾與更新,但需要考慮復雜的版本組合,建議使用語義版本管理對版本進行控制
我們知道侵入式框架是在L7去解決微服務調用,管理,監控的問題,那么是否我們可以將這部分抽象出來,在L5層解決呢。
在這個模式的基礎和思路之下,我們引入了Service mesh。
Service Mesh
什么是Service Mesh。
Service mesh最早是由Linkerd給出的定義,我們來看看英文版。
A service mesh is a dedicated infrastructure layer for handling service-to-service communication. It’s responsible for the reliable delivery of requests through the complex topology of services that comprise a modern, cloud native application. In practice, the service mesh is typically implemented as an array of lightweight network proxies that are deployed alongside application code, without the application needing to be aware. (But there are variations to this idea, as we’ll see.) The concept of the service mesh as a separate layer is tied to the rise of the cloud native application. In the cloud native model, a single application might consist of hundreds of services; each service might have thousands of instances; and each of those instances might be in a constantly-changing state as they are dynamically scheduled by an orchestrator like Kubernetes. Not only is service communication in this world incredibly complex, it’s a pervasive and fundamental part of runtime behavior. Managing it is vital to ensuring end-to-end performance and reliability.
大致的意思如下:
一種基礎設施層,服務間的通信通過service mesh進行
可靠地傳輸復雜拓撲中服務的請求,將它們變成現代的云原生服務
一種網絡代理的實現,通常與業務服務部署在一起,業務服務不感知
一種網絡模型,在TCP/IP之上的抽象層,TCP/IP負責將字節碼可靠地在網絡節點間傳遞,Service mesh則復雜將服務間的協議請求可靠地在服務間進行傳輸。它們不關心傳輸的內容
TCP/IP僅僅負責傳輸,但Service mesh可對運行時進行控制,使服務變得可監控,可管理。
為什么使用Service Mesh
無需考慮每種語言都要解決的問題
對業務代碼0侵入,開發者無需關心分布式架構帶來的復雜性以及引入的技術問題
對于不適合改造的老舊單體應用,提供了一種接入分布式環境的方式
微服務化的進程通常不是一蹴而就的,很多應用選擇了演進的方式,就是將單體應用一部分一部分地進行拆分。而在這個過程中,使用Service Mesh就可以很好地保證未拆分的應用與已經拆分出來的微服務之間的互通和統一治理
開發出的應用既是云原生的又具有獨立性,不將業務代碼與任何框架,平臺或者服務綁定
依然沒有銀彈,我們來看看Service mesh解決不了的問題:
Service Mesh組件代理請求轉發,會在一定程度上降低系統通信性能
侵入式框架以源碼和業務代碼結合,有較強定制和擴展能力,Service mesh相對不易定制擴展
在運行時,依賴單獨的Service Mesh代理,多了一個故障點。整個系統的運行和運維也強依賴于Service Mesh組件的能力
Service Mesh的實踐歷程和設計思路
Service Mesh在華為公司內部的發展歷程
第一代: 基于NGINX的微服務代理
該平臺是華為公司內部使用的微服務開發部署運行平臺,開發于2013年,用于公司內部某電信業務。在這個業務系統中有大概400多個左右的微服務,實例數量根據局點大小不一樣,一個典型的部署為800多個左右實例的規模。
整體架構如下:
其中的Internal Router組件用來給開發者解決分布式架構中的可靠傳輸問題:
使用高性能nginx及其相應的lua擴展作為Internal Router,將Http服務接入
使用RouteAgent負責注冊/注銷實例,更新IR的實例信息
使用zookeeper作為注冊中心
以Per-Host的方式部署在微服務所運行的環境中
用這種方式構建的微服務環境已經在超過200個局點的生產環境下得到使用,整體運行情況良好。但是隨著時間的推移,當業務對敏捷的要求越來越大,而且容器的使用也越來越廣泛,這種方式帶來了一些問題:
使用lua腳本擴展注冊發現,負載均衡,熔斷,降級,容錯,限流,但lua的擴展性有一定的局限
用RouteAgent負責服務的注冊以及每個NGINX上服務實例路由的刷新,RA需清楚地感知本節點上的微服務都有哪些,但是使用Kubernetes做容器調度后微服務和實例的分布信息在K8S里面集中記錄
容器的IP更多,變化更頻繁,使用RouteAgent刷新NGINX路由的方式會導致NGINX服務受到影響,頻繁的路由刷新導致業務運行收到影響
當IR服務失敗后,整個Host中的服務都會丟失,無法與外界建立聯系
為了解決這些問題,出現了第二代的解決方案: HSA Sidecar。
HSA是華為內部的一套微服務開發框架,它提供了注冊中心,配置中心,java開發框架,以及SideCar等組件。
基于Java 微服務框架開發,非侵入式通信方式,支持RPC與Http,提供SOAP協議轉換,但會導致性能下降
與微服務部署在一個Pod中即Sidecar模式
作為代理服務,使微服務自動獲得注冊發現,負載均衡,熔斷,降級,容錯限流等功能
占用資源很高,一個應用實例一個Sidecar實例的部署方式,會占用過高資源
雖然第一代的問題解決了,但是第二代的Sidecar在性能和資源占用上有很大的問題,在少量的技術項目中試用后,因為資源占用過高的問題無法在大規模環境中推廣使用。
閱讀全文請掃描
下方二維碼,
還可以加入讀者圈與作者聊天~:
總結
以上是生活随笔為你收集整理的Service Mesh 在华为公有云的实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 顺序写磁盘比随机写内存_深入理解 lin
- 下一篇: 光大银行信用卡额度是多少