摘要:在近日於上海召開的第六屆Gopher China大會上,華爲雲微服務首席架構師田曉亮分享了《華爲雲的Go語言云原生實戰經驗》,講述如何構建韌性、高可靠、安全的雲原生應用系統,並孵化雲原生應用開發框架Go chassis,以提高團隊開發效能。
Gopher China做爲國內最權威和最實力乾貨的Go大會,致力於爲廣大的Gopher提供一線分享交流機會,也爲衆多一線互聯網公司大咖深刻探討Go語言的應用發展提供契機。html
在近日於上海召開的第六屆Gopher China大會上,華爲雲微服務首席架構師田曉亮就受邀分享了《華爲雲的Go語言云原生實戰經驗》,講述如何構建韌性、高可靠、安全的雲原生應用系統,並孵化雲原生應用開發框架Go chassis,以提高團隊開發效能。git
自華爲在2016年成立Cloud BU以來,就引入了Go語言編寫的Kubernetes,Prometheus等CNCF項目,華爲雲的研發團隊也開始用Go語言來構建雲服務。不過,當時Go的生態並不完善,因此要本身從頭至尾編寫基礎能力模塊。github
那麼,如何用Go構建雲服務並將基礎能力慢慢創建起來,且聽咱們慢慢道來。算法
從一個簡單雲應用看咱們如何構築一個雲服務
和Eureka同樣,一個簡單的註冊發現服務Service Center能夠經過多種手段來加強。apache
一、靜態與動態信息定義
減小數據信息量,抽出公共部分統一管理,經過靜態信息來劃分實例組。這樣微服務與微服務實例爲1對n的映射,將微服務名、版本、數據中心等信息都抽到了公共部分,經過下降冗餘度,來減小網絡的開銷,同時也規範化了微服務模型。編程
二、契約化微服務
上一張圖咱們看到微服務靜態信息裏面包含了多個Schemas,裏面關聯了微服務所關聯的契約文檔,一樣是1對n的映射關係。經過手動上傳或者代碼自動生成文檔上傳,能夠在註冊中心中查看微服務文檔,且文檔與微服務版本綁定,不容許更改。後端
對比客戶端開發團隊等待後端的服務編寫完成後,纔開始進行集成開發的方式。高效方式是以文檔爲基準,客戶端與服務端同時開發,客戶端經過Mock去除對服務端的依賴。緩存
爲什麼要保證文檔先行?若是文檔不及時審視,那麼將會出現很是糟糕的狀況。好比不一致的命名規範,定義類似的API,擴展能力差,任何一點都會大大增長研發成本。及早審視並規避十分重要,這就是爲什麼註冊中心加入文檔上傳與查詢能力。安全
三、服務間依賴管理
調用層級太高將引發定位困難、性能降低的問題,合理的層級是3個服務:a->b->c的調用就能夠完成一次調用。彼此互相依賴的兩個服務在功能升級或者變動時要花費更多時間來分析影響,好比ab互相依賴,一個新功能涉及2個都要更改,那怎麼一塊兒上線?restful
簡單的依賴有助於系統測試和分析,這給架構師一個很好的審視方式,能夠及時看到微服務間的依賴關係,以及時對架構調整。
四、緩存機制
因爲Service Center內部自己是不存數據的,一旦etcd出現網絡故障的時候,就會致使Service Center不可用。因此Service Center引入了異步緩存機制,啓動之初,Service Center會與etcd創建一個長鏈接,也就是watch。爲了防止創建watch時間窗發生變化,又作了一層保護,在watch以前作全量的查詢。運行過程當中查詢所獲得的資源變化會緩存到Service Center本地,而後進行異步的循環。
總的來講,咱們經過了多種手段來提高微服務研發效率,減小網絡開銷,並經過異步緩存提高性能。這是華爲雲積累的能力,但交付一個雲服務遠遠不止交付業務功能這麼簡單,還要考慮微服務的安全、韌性、隱私、可運維等能力。
咱們剛纔看到的只是水面之上的冰山,水面之下還隱藏着大量的基礎能力須要編寫。真的要達成微服務架構模式的願景,須要繁重的工做量。就像冰山那樣,咱們要將通用能力沉澱下去,可以複用。若是讓各個業務團隊同時照顧冰山上下,各自開發各自的,那結果將是災難性的,企業用人成本極高,下面讓咱們展開Service Center的架構看看。
立足Service Center架構,「冰山下」的基礎能力庫編寫很重要
下面這個組件主要負責微服務的註冊發現,提供Restful API。
它有四個主要的模塊:
-
- 服務註冊發現:經過註冊發現完成服務拓撲的感知;
- 契約發現:每一個服務具有一個契約記錄,支持多種格式如Open API,gRPC proto;
- RBAC:基於角色的訪問控制,管理員能夠管理帳號,將帳號分發給微服務或者不一樣人員;
- 服務治理:針對微服務下發治理規則,好比重試,限流,熔斷,路由策略等。
交付一個雲服務遠遠不止交付業務功能,而是要去全方面的考慮安全,韌性,隱私,可運維等能力,固然咱們將部分的能力能夠交給一些中間件來完成,好比網關。然而仍有大量功能須要本身編寫,且能夠複用在每一個微服務中,這就是基礎能力庫編寫的初衷。
-
- 配額管理:雲資源按照租戶進行配額管理,租戶所能使用的資源受到嚴格限制
- 告警:當微服務發生關鍵問題時要直接上報告警系統,而非經過雲服務設置閾值等告警策略
- 安全:加解密證書,密碼
- ID生成:ID的生成算法,用於生成微服務ID,實例ID等
- 多種中間件:調用過程須要被審計,調用鏈追蹤,生成指標監控等
該項目已經開源並捐獻給Apache, 項目地址https://github.com/apache/servicecomb-service-center
對於這些能力,抽取普通的庫函數也是徹底不夠用的,因此要作到以下能力:
可插拔:也就是按需在編譯期引入(受限於Go語言能力),例如配額系統的具體實如今社區是不須要的。
異構系統:也就是一個功能要有多種具體實現,好比審計,公有云存在一套審計系統須要對接,而社區則是本地日誌打印。
不一樣的算法:解密工具、ID生成器……面對不一樣的交付場景或安全要求,都要經過不一樣實現來替換算法。好比ID生成能夠是snowflake、UUID;加解密算法使用AES或者其餘公開算法。
如何經過Go Chassis加速雲服務開發?
爲了知足上面提到的需求多樣性,而且讓全部新規劃的組件受益、快速進行開發,咱們須要統一的框架和標準來加速開發,這就是華爲雲用Go語言編寫的開發框架Go Chassis誕生的緣由。因此你們看能夠看到go chassis的源碼和設計有着service center代碼的影子,感興趣的同窗能夠去深刻閱讀下。
從Go Chassis的開發框架能夠看到,業務邏輯是用戶本身編寫的業務代碼,框架分爲協議層、中間層和插件套件三部分,管理部分是雲服務,框架開發出來的應用能夠快速對接使用這些雲能力。好比:
-
- 註冊發現插件能夠對接Service Center與kubenetes
- 配額管理插件能夠對接雲服務的配額管理服務
- 中間件如指標監控對接到prometheus
那麼如何經過這個框架來加速咱們的開發呢?
手段1:將後端服務做爲插件使用
後端服務指的是不禁本身組織開發並運維,從應用運行到基礎設施不可見的黑盒子服務。常見的後端包括配額管理、認證鑑權服務和對象存儲服務,雲原生的其中一個要素是把後端服務看成附加資源。
當咱們調用這些後端服務時,其實它們並不在微服務的治理體系內,考慮到可測試性(好比mock測試)以及可替換性(業務可以連續,且隨時更換更好的服務,應對變換的需求等),咱們須要將它們插件化,以靈活的進行選擇替換或者去除。
手段2:沉澱需求基線
在咱們提供任何一種服務前,咱們都須要知足基本的要求,好比:
-
- 請求體必須作大小限制
- API必須限流
- 密碼不能明文存儲
- 訪問進行認證鑑權
- 無單點故障
- 訪問審計
- 運維能力
考慮到這些需求,首先要將運行時的調用模型標準化。因爲不一樣部門會有私有協議訴求,那麼服務治理就交給核心框架完成,協議由業務部門決定自主研發或是集成現有協議。
當公司內部不一樣部門都在開發本身的協議作本身的服務治理時,再將業務統一在一個架構、工具鏈上,就很是困難。
因此,咱們使用Invocation概念來統一協議描述,這樣就能夠在統一的處理鏈中進行處理。
處理鏈的設計知足AOP,也就是在業務處理的先後加入代碼邏輯進行特殊處理,好比審計用戶操做。
ResponseCallBack 用於接受後置handler返回的結果,因此每個handler處理時均可以按需定義本身的ResponseCallBack來獲取後面handler,甚至是業務邏輯代碼的執行結果,讓通用邏輯(即中間件)和業務邏輯完全解耦。
目前Go Chassis已經支持的中間件包括限流、熔斷、負載均衡、認證鑑權和審計,都用此機制來實現:將公司所有的工具鏈,服務治理手段,安全合規等都落入處處理鏈中,來快速加快研發速度,並統一規範,減小管理負擔。
框架內部提供給了命令式調用能力,好比指標收集。
也提供了聲明式使用方式,好比流量管理,其具有基於流量特徵的限流能力。
從插件能力全景圖能夠看到,Go Chassis目前已經支持多種生態,並對多種後端系統提供了抽象接口,從而幫助應用快速開發。
經過這樣的框架,咱們可讓業務團隊專一於業務代碼開發,而無需理解後端的複雜性和其餘非功能需求。帶來的收益以下:
• 對於龐大的系統能夠進行mock測試,提高交付質量
• 應對不一樣的交付場景
• 保證後端可替換性
• 研發職責界面分離
從架構或者業務演進的角度來思考,後端使用的技術是在快速演進的,咱們須要經過後端服務的快速替換來確保系統和產品的及時演進,因此接口設計的可替換性大於可重用性。這也知足程序設計原則的依賴倒置,當咱們再開發一個新的微服務時,僅僅須要實現他的業務邏輯便可。
手段3:經過配置簡化開發流程
這也是一種命令式調用方式,其結構以下:
Source層: 配置源是一種標準接口,能夠經過實現一個source來接入不一樣配置源,它定義配置來自哪一個資源:能夠來自遠端系統,來自本地文件,來自環境變量或是啓動命令行。source負責將配置項緩存到本地內存,用戶能夠選擇加載任意的source實現。
remote source:對接分佈式配置管理系統,目前對接了攜程開源的配置中心Apollo。
Config manager:負責整合管理全部source的配置,每一個source能夠定義優先級,當經過manager獲取配置時,若是2個不一樣的source有相同的配置,那麼就會取最大優先級的配置。
Event Dispatcher:用戶能夠經過Archaius API進行配置變化監聽,當source內部的配置項新增、更新、刪除、時,都會通知監聽器。
Source優先級:優先級由大到小依次爲Config center、CLI、ENV、file,當有相同配置項的時候僅優先級大的配置生效。在一個分佈式系統中,遠程的配置中心理應擁有最大優先級。而在本地運行一個獨立的進程時,一般的思惟是命令行參數優先級高於環境變量,高於本地文件內容。擁有了這樣一套機制後,用戶就無需再寫代碼處理配置項生效邏輯。
Archaius API: 封裝底層實現,提供友好的API供開發者使用。
其中,內存source很是重要,它使得UT測試更加簡單。File source使得本地進程的測試可行。遠程的配置中心好比攜程的Apollo,則幫助系統進行聯調測試並支撐生產環境。
手段4:易處理
意思是它們能夠瞬間開啓或中止。 這裏咱們不會談到快速的開始,由於Go語言和Docker運行時,容器平臺就能處理這樣的一個場景,因此咱們談談面向意外的處理。
這個Protocol server一般表明一個協議,也能夠是某種編程模型,好比http。
還有個框架的配置樣例,意思是在一個微服務進程中拉起了2個http端口和grpc端口服務。
在收到系統信號後,就會遍歷的中止每一個server。
另外由社區開發者貢獻的自定義優雅停機功能,能夠容許用戶劫持信號和停機處理過程,也能夠在先後自定義處理過程。
手段5:輕量級內核
目前,Go Chassis只依賴必要的prometheus、opentracing、jwt、k8s client、Go-restful相關的依賴庫。
註冊發現也是可插拔的。
另外,包括grpc協議、kubernetes註冊中心等多種能力都在另外一個倉庫中提供,能夠按需引入
擁有本身從新制造的輪子
擁有本身從新制造的輪子是Go Chassis開發框架logo想要傳達的理念。
我認爲真正有能力的團隊不會本身從新制造輪子,由於他們懂什麼是輪子,什麼樣的輪子適合本身,並將這種抽象的輪子引入並進行加強,打形成更加適合本身的輪子,你是「越野輪子」仍是「雪地輪子」,品類皆由你定。咱們將本身研發團隊積累的能力抽象成多種接口及插件,爲的就是不要重複製造輪子,而是基於現有輪子從新打造,讓項目產品跑的更快。
Go Chassis的案例分享
首先是基於Go Chassis和Service Center進行服務治理的視頻通話後臺,其一直應用於華爲榮耀手機和智慧屏等終端上,且上線了公有云,有效支撐終端公司暢聯通話上億註冊用戶。
第二個案例是基於Go Chassis開發服務治理底座的邊緣處理能力,它管理全國29個省、自治區的將近10萬邊緣節點,超過50萬邊緣應用的部署。支撐了1萬多個收費站的門架信息採集業務的不斷調整、更新,知足了每日3億條以上的信息採集。爲往後車路協同、自動駕駛等創新業務的發展提供了良好的平臺支撐。
(https://github.com/kubeedge/kubeedge)
除此以外,華爲雲ServiceStage就是無縫託管基於GoChassis開發的微服務,並在此之上提供免運維的微服務引擎功能
( https://www.huaweicloud.com/product/servicestage.html)
總結
一、定義你的應用開發通訊協議
一家公司很是重要的兩樣東西是企業文化與行爲規範,這是每一個公司的領導者必須優先定義的事情,它就像是一種通訊協議,保證團隊之間可以良好的協做。這樣領導者就無需事必躬親,甚至能夠作到無爲而治。這套機制就是所謂的「通訊協議」
因此定義一套通訊協議是很是重要的。Go chassis就是Go研發團隊的通訊協議。
每一個微服務都是個小團隊開發的,有多是同一個團隊,也多是不一樣團隊,咱們所作的框架是爲了定義一套最簡化的範式(接口與模型),以此來減輕研發的成本,同時兼顧擴展性,不要對開發有過分的限制。咱們規範化了API first來審視API設計,依賴管理來審視合理的服務關係,並規定全部的能力要沉澱爲插件與中間件,而這些都是爲了定義研發團隊開發與治理雲服務的「通訊協議」。
二、Go在新基建中的做用
互聯網演進第一代是PC,第二代是手機,第三代即是萬物互聯,5G時代容許更多的設備接入,而較小的設備勢必會催生新的半導體,新的操做系統(好比說華爲鴻蒙),這樣一層層下去,勢必會須要一種新的語言及對應的框架,Go語言的特性就很契合這樣一個位置,而分佈式的設備也須要一種框架來進行治理,Go Chassis也將在這裏扮演比較重要的角色。
綜上,我認爲Go語言極可能成爲基礎設施領域的一個開發底座,從kubeedge、視頻雲等項目使用Go Chassis就能夠看出端倪。
歡迎你們參與社區, Go Chassis開源項目地址:https://github.com/go-chassis/go-chassis
本文分享自華爲雲社區《華爲雲的Go語言云原生實戰經驗:創建雲原生應用開發基礎能力》,原文做者:灰灰噠 。