您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關如何實現(xiàn)微服務框架Apache ServiceComb的開放性設計,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
開源微服務框架 Apache ServiceComb 的前身為華為云的 微服務引擎 CSE (Cloud Service Engine) 云服務, ServiceComb 的早期版本和多數(shù)第一批做微服務或分布式框架先賢一樣,為了追求高性能,做過非常多如 改善編碼效率 和改進通信協(xié)議等嘗試。然而,隨著業(yè)務規(guī)模的遞增,需求也逐漸呈現(xiàn)多樣化,單方面通過傳統(tǒng)手段追求高性能導致在面對多樣化需求時遇到了各種挑戰(zhàn),遺留系統(tǒng)的通信、接入各種不同的終端、協(xié)議健壯性、防攻擊等各種挑戰(zhàn)迎面而來。
Apache ServiceComb,愿景是幫助企業(yè)快速構建云原生應用,通過一系列解決方案幫助用戶快速開發(fā)微服務應用的同時實現(xiàn)對這些微服務應用的高效運維管理,保持中立性以避免廠商LockIn成為了關鍵任務。對于此, Apache ServiceComb 需要有友好的機制能夠對接各微服務主流技術棧技術 或 開發(fā)框架。
在系列挑戰(zhàn)的驅動下, Aapche ServiceComb 設計團隊逐步形成了 “全面開放,使用標準協(xié)議,架構易于拆分和擴展,對開發(fā)人員友好,可以與業(yè)界其他主流框架互通集成” 的共識, 本文將著重分享這些共識是如何體現(xiàn)在Apache ServiceComb 的設計中的。
開放和標準應用到設計的不同的層面。一方面是連接組織和開發(fā)人員,一方面是連接異構系統(tǒng)。組織和開發(fā)人員的復雜性來源于技能的多樣性,大家使用不同的開發(fā)語言,同一種開發(fā)語言存在多樣的開發(fā)習慣;系統(tǒng)的多樣性來源于系統(tǒng)之間的通信協(xié)議,為了實現(xiàn)與異構系統(tǒng)的通信,必須具備良好的適配不同通信協(xié)議的能力。
每位技術人員都或多或少擁有自己的 Coding 習慣或愛好的技術, 使用個人熟練的方式從事技術工作往往更加高效和舒適。
開源微服務框架 Apache ServiceComb 的早期版本實現(xiàn)了 gRPC 協(xié)議,然而在項目演進過程中我們發(fā)現(xiàn)大量技術人員并不熟悉書寫 IDL , 對 IDL 具體支持哪些特性也不清楚。 大多數(shù)情況下,用戶每碰到一個場景就需要翻開協(xié)議規(guī)范看一遍, 而 IDL 缺少配套的編輯或語法檢查等工具也導致了開發(fā)效率的降低。
于是 Apache ServiceComb 設計團隊開始思考是否有方法能夠在確保保持用戶開發(fā)習慣的前提下支持 gRPC 。
設計團隊結合自己的 Java 編程史,分析當下主流框架,并聽取社區(qū)用戶的反饋找到了一些共性:
使用 RPC 方式描述對外接口。gRPC 、Corba 、WebService 等技術人員諳于此道。
使用 JAX-RS 或 Spring MVC 風格開發(fā) REST 接口。REST 風格開發(fā)隨著微服務架構興起,JAX-RS 和 Spring MVC 已然成為 Java REST 的開發(fā)事實標準, Spring 的擁抱者都比較熟悉。
Apache ServiceComb 很快在社區(qū)設計層面達成了一致,通過缺省支持以上共性來擁抱90%的開發(fā)者, 讓大多數(shù)的 Java 開發(fā)者們能夠快速開始工作。
除以上共識外,Apache ServiceComb 還額外做了進一步的優(yōu)化,以保證不同編程風格的兼容性,使用戶或開發(fā)者倍感靈活及舒適。
在下面的例子中,展示了 Provider和Consumer 代碼的各種實現(xiàn),在同一個微服務中,這些編程方式可以同時出現(xiàn);同一段 Consumer 代碼中可以訪問各種不同的編程風格的 Provider 實現(xiàn)。
RPC 方式的 Provider
@RpcSchema(schemaId="hello") public class HelloImpl implements Hello{ @Override public String sayHi(String name){ return"Hello"+name; } @Override public String sayHello(Person person){ return"Helloperson"+person.getName(); } }
JAX-RS 方式的 Provider
代碼片段來自于 Apache ServiceComb JAX-RS sample
@RestSchema(schemaId="jaxrsHello") @Path("/jaxrshello") @Produces(MediaType.APPLICATION_JSON) public class JaxrsHelloImpl implements Hello{ @Path("/sayhi") @POST @Override public String sayHi(String name){ return"Hello"+name; } @Path("/sayhello") @POST @Override public String sayHello(Person person){ return"Helloperson"+person.getName(); } }
Spring MVC 方式的 Provider
代碼片段來自于 Apache ServiceComb Spring MVC sample
@RestSchema(schemaId="springmvcHello") @RequestMapping(path="/springmvchello",produces=MediaType.APPLICATION_JSON) public class SpringmvcHelloImpl implements Hello{ @Override @RequestMapping(path="/sayhi",method=RequestMethod.POST) public String sayHi(@RequestParam(name="name")String name){ return"Hello"+name; } @Override @RequestMapping(path="/sayhello",method=RequestMethod.POST) public String sayHello(@RequestBody Person person){ return"Helloperson"+person.getName(); } }
RPC 方式訪問上述三種服務的 Consumer
@RpcReference(microserviceName="hello",schemaId="hello") private Hello hello; System.out.println(hello.sayHi("JavaChassis"));
以上代碼片段全部出自 Apache ServiceComb Samples,有興趣者可閱讀了解或貢獻更多的智慧。
直至此處,或許開發(fā)者會產(chǎn)生疑問,既然 Consumer 可以通過一致的 API 方式訪問不同的Provider,為何還需要額外的 JAX-RS 和 Spring MVC 標簽?
原因是,這里的設計依據(jù)是 Apache ServiceComb的 Consumer考慮的不僅限于 類SDK 的 Consumer,還有瀏覽器等非 SDK 類的 Consumer,瀏覽器的 Conumer 識別的是 Http 形式的消息。 通過定義和使用這些標簽, 我們可以更加精細的指定瀏覽器如何訪問后臺接口。 類似于 Web Service 的 WSDL 描述語言, Apache ServiceComb 稱之為服務契約。
服務的契約會在服務運行時通過代碼定義自動生成,并注冊到服務中心。契約也可在運行時用于獨立的服務治理邏輯開發(fā),生成 Consumer 代碼。此外,也可作為 API 文檔對外發(fā)布,供非 SDK 的 Consumer 參考。
微服務強調(diào)服務自治,對外體現(xiàn)的功能全部以松耦合的接口方式提供,并且只能以通信的方式實現(xiàn)相互訪問。此原則給團隊協(xié)作帶來了根本性的變革。
微服務的一個開發(fā)團隊通常由5~6個人的全功能團隊組成,端到端的完成 場景需求分析、架構功能設計、開發(fā)和運維,團隊組織結構和業(yè)務系統(tǒng)的架構相匹配。團隊建立后的核心問題就是團隊之間如何進行高效的協(xié)作溝通,以決定不同微服務之間的協(xié)作通信。
Apache ServiceComb 通過確保讓開發(fā)人員保持自己的固有編程習慣及設計上的松耦合靈活性,讓微服務團隊之間可以進行高效協(xié)作,以避免在不同的微服務團隊討論編程風格受限于歷史舊賬而浪費寶貴的精力和時間。
在 RPC 的世界里,有 Corda IDL,WSDL,ProtoBuffer 等可以參考的優(yōu)秀實踐, REST 風格的接口讓團隊之間可以通過 HTTP 語義進行溝通,但卻不能像 IDL 一樣描述跨語言的數(shù)據(jù)格式。Open API 的出現(xiàn)很好地解決了這個問題。
Open API 首先是一個不斷發(fā)展壯大中的開放的標準。Open API 能兼顧 RPC 、REST 等不同的開發(fā)方式,并且吸收了大量的跨語言經(jīng)驗,能夠在不同的語言之間進行解析。
對于 Java 開發(fā)者,下面的代碼片段是日常所打交道的:
User: type:object properties: age: type:integer
如果開發(fā)人員有豐富的跨語言開發(fā)經(jīng)驗,可以看出 Swagger 在解決跨語言編程方面API定義沖突的努力, 如 Swagger 通過 format 來定義數(shù)據(jù)類型的存儲格式,以解決不同的語言在數(shù)據(jù)類型表示上的差異:
User: type:object properties: age: type:integer format:int32
開源微服務框架 Apache SerivceComb 既遵循常規(guī)開發(fā)規(guī)范也特別關注開發(fā)效率。開發(fā)者可以先寫接口定義后寫代碼, 也可直接通過自己熟悉的方式編寫寫代碼, 兩種方式都會生成 服務契約(Open API 描述文件),并且將內(nèi)容注冊到服務中心。使用者可以從服務中心下載相關的服務契約進行開發(fā)。 Apache ServiceComb 的各種治理結構也是基于契約的,可以讓開發(fā)者獨立于業(yè)務實現(xiàn)對系統(tǒng)進行統(tǒng)一的管控治理。
開源微服務框架 Apache ServiceComb 早期版本提供了gRPC、REST、SOAP等多種協(xié)議,當前主要支持 REST 和Highway 高性能私有 RPC 兩種協(xié)議。
gRPC 相對于 REST 的最顯著優(yōu)點就是性能,它采用長連接、高效的二進制序列化方式,提供多種語言支持, 提供了 IDL 語言約束開發(fā)者按照標準的方式工作, 一切看起來是那么的完美。
實際上,Apache ServiceComb 的第一輪重構,首選也是 gRPC 。歷史第一次在華為云 微服務引擎 CSE 上線以后,面對了來自網(wǎng)關壓力挑戰(zhàn)。
網(wǎng)關作為業(yè)務接入端,必須高效的管理連接和保證公平,長連接容易導致拒絕服務。gRPC 程序開發(fā)完成后,開發(fā)人員無法利用系統(tǒng)提供的各種工具進行測試,網(wǎng)絡包分析也變得困難,給生產(chǎn)環(huán)境上的開發(fā)聯(lián)調(diào)造成了困難。隨著業(yè)務規(guī)模的增長,gRPC 面臨了諸如“其他三方系統(tǒng)如何與之直接通信? 如何跨網(wǎng)關與它間接通信?”等更嚴峻的挑戰(zhàn)。
解決這些問題,將需要我們擴展和改善老的協(xié)議和程序,提供 gRPC 客戶端支持,開發(fā)者需自行提供一個額外的表示層用于業(yè)務接口的邏輯轉換,造成大量的重復代碼。同時由于 gRPC 依賴于接口定義,并根據(jù)定義生成代碼,一套代碼只能跑在 gRPC 協(xié)議上,如果用戶希望業(yè)務應用可以使用如 REST等其他更加靈活的方式, 就需自行重新實現(xiàn)一套新的代碼邏輯。據(jù)以上的血淚史, gRPC 最終被 Apache ServiceComb 設計團隊定義為只能在中小型系統(tǒng)內(nèi)部之間使用,并通過協(xié)議網(wǎng)關與外部系統(tǒng)進行通信。并實現(xiàn)了 高性能私有協(xié)議 Highway 作為RPC首選默認協(xié)議。
REST 相較 gRPC ,最大的痛點是性能。
多數(shù)技術人員腦海里一個不成文的根深蒂固的觀點:”二進制編碼效率遠高于文本協(xié)議,采用二進制編碼的系統(tǒng)的性能遠高于采用文本的 HTTP ”。該觀點甚至會讓多數(shù)決策止步于理論,多數(shù)人甚至不愿嘗試去優(yōu)化 REST。
可喜的是 開源微服務框架 Apache ServiceComb 邁出了重構 REST 底層通信實現(xiàn)的第一步,基于 Netty 的異步框架來替換 Tomcat 實現(xiàn),實踐的效果大大超出預期,部分基準測試數(shù)據(jù)結果顯示比 gRPC 還好, gRPC最終輸在了HTTP2 協(xié)議上的額外報文。
優(yōu)化后的 REST 和業(yè)界開源的其他基于二進制的 RPC 實現(xiàn)的性能基本持平。在一個簡單的提供數(shù)據(jù)庫查詢的代碼邏輯中,優(yōu)化后的REST通信框架處理時間,占比總處理時間遠小于千分之一,這意味著再繼續(xù)在框架層面進行大量優(yōu)化也抵不上業(yè)務應用層面最簡單的一個操作帶來的消耗,Apache ServiceComb對 REST 的優(yōu)化已經(jīng)滿足要求,最終也選擇了 REST 作為首選和缺省協(xié)議(HTTP + json)。
我們并沒有就此止步。
需要遷移到 華為云 微服務引擎 CSE 的業(yè)務日益增長,部分歷史遺留系統(tǒng)也需進行對接。通信協(xié)議對應不同的開發(fā)者接口,每每增加通信協(xié)議,則需要對業(yè)務代碼進行大量的重復構建,造成大量無謂消耗。這是當時的華為云化轉型以及當下很多云化轉型企業(yè)或者云原生企業(yè)必將面臨的痛點。
于是乎,通信協(xié)議層被剝離了出來,和業(yè)務代碼隔離,系統(tǒng)運行基于契約,開源微服務框架 Apache ServiceComb 實現(xiàn)通信協(xié)議擴展機制。通信協(xié)議擴展機制,幫助用戶解決與 gRPC 框架、自定義二進制框架等許多遺留系統(tǒng)的對接通信問題。
在 Apache ServiceComb 框架中,切換協(xié)議非常簡單,不需要修改一行業(yè)務代碼。多個協(xié)議共存也是允許的。
ServiceComb: rest: address:0.0.0.0:8084 highway: address:0.0.0.0:8094
擴展性是系統(tǒng)進一步發(fā)展的基石。開源微服務框架 Apache ServiceComb 創(chuàng)造性地將擴展性拓展到 Provider 和 Consumer,讓開發(fā)者擁有一致的開發(fā)體驗。
連接開發(fā)者和通信協(xié)議層面已經(jīng)讓系統(tǒng)具備了很大的擴展性。微服務化給系統(tǒng)解耦、團隊自治帶來了很大的靈活性,加快了開發(fā)生產(chǎn)效率,但同時帶來了服務管控的復雜性,在微服務領域,不得不考慮雪崩效應、調(diào)用跟蹤、性能監(jiān)控與分析等實際管控治理問題。
基于服務契約,開源微服務框架 Apache ServiceComb 提供了動態(tài)插拔擴展的處理鏈機制,并且為這些管控治理能力提供了默認實現(xiàn),用戶可以靈活插拔這些處理模塊,或調(diào)整它們的順序以應對不同的處理場景,或自行實現(xiàn)以增加新的處理模塊。Provider 和 Consumer 都會經(jīng)過該處理鏈,這給客戶端治理功能開發(fā)帶來了極大的便利性。Apache ServiceComb 的運行結構如下:
圖1 Apache ServiceComb 運行時架構
Apache ServiceComb 同時支持同步和異步兩種編程接口,并在通信實現(xiàn)上采用了純異步方式,對于運行模型的擴展,也是基于異步回調(diào)接口的。該方式提供了比同步模式(比如 Filter)更加優(yōu)雅靈活的擴展方式。
在Apache ServiceComb 結構中,幾個核心的擴展機制均在 core 模塊 進行定義:
Producer Provider
Provider 編程模型的擴展,通過實現(xiàn)這個接口,可以適配不同的 Provider編 程風格;默認支持 RPC、Spring MVC 和 JAX-RS 三種風格。
Consumer Provider
Consumer 編程模型的擴展,通過實現(xiàn)這個接口,可以適配不同的 Consumer 編程風格;默認支持 RPC和RestTemplate 兩種風格。RestTemplate 是 Spring MVC 提供的 REST 編程接口,可以在服務層解除接口依賴,只依賴數(shù)據(jù)模型。
Handler
處理鏈的接口,通過擴展該接口,可以在處理過程中插入任意的邏輯。默認已經(jīng)支持負載均衡、錯誤注入、流量控制和調(diào)用鏈跟蹤等多個處理鏈。開發(fā)者可以針對 Consumer 和 Provider 定義不同的處理鏈,并且為訪問不同的微服務定制不同的處理鏈。
Transport
通信協(xié)議擴展,默認支持REST over Vertx、Rest over Servlet、Highway協(xié)議。
Invocation
中立的對象。所有的運行模型都面向這個中立的對象進行編程,當定義好服務接口后,對服務的治理和服務業(yè)務邏輯的開發(fā)可并行進行。在編程模型和通信模型里面,也面向這個對象進行編解碼。
Apache ServiceComb Java-chassis 預留了對接外部系統(tǒng)的接口,以讓開發(fā)者或用戶可以靈活快速切換使用第三方提供的服務,這里所指的外部系統(tǒng)包括但不限于:服務注冊發(fā)現(xiàn)的服務中心、配置管控和治理的配置中心、運行監(jiān)控和運維的治理中心等。
下圖展示了不同的開發(fā)框架支持和運行的第三方系統(tǒng)情況,這些基礎服務都給開發(fā)者預留了可以進行支持接入的接口。
圖2 Apache ServiceComb 外部擴展接入
重要的擴展:
ServiceRegistryClient
實現(xiàn)這個接口以對接不同的注冊服務。
ConfigCenterConfigurationSource
實現(xiàn)這個接口以對接不同的配置服務。
此外,ServiceComb還提供了對接Zipkin、Servo等開源系統(tǒng)的功能,這些可以從github代碼中查找到對應的例子。
一個完整的業(yè)務系統(tǒng)不是使用RPC框架就算完成了,它們還需要其他的計算資源。對于一般的業(yè)務系統(tǒng)都需要訪問數(shù)據(jù)庫,或者基于 J2EE 的設施進行工作。
開源微服務框架 Apache ServiceComb 可以以輕量級的方式運行,也可集成到其他系統(tǒng)框架。下面的示意圖說明了 Apache ServiceComb 的一些工作環(huán)境。
圖3 Apache ServiceComb 運行環(huán)境集成
若業(yè)務只需 REST 接口,可以輕量級的方式運行 Apache ServiceComb 。所有的REST接口運行于ServiceComb 提供的 Netty HTTP 之上。
若業(yè)務是基于 J2EE 來構建,那么 Apache ServiceComb 可以作為一個 Servlet ,運行于 Web 容器里面(如 Tomcat、Jetty 等)。
若業(yè)務基于 Spring Boot 生態(tài)構建,Apache ServiceComb 可作為一個starter對外提供 REST 服務,開發(fā)者可以自由使用其他基于 Spring Boot 的功能。
由于 Apache ServiceComb 使用了Spring,因此天然繼承了Spring的原有優(yōu)勢,可和很多通用的組件很好的集成,如 mybatis、JPA 等。各種集成方式,都可以從ServiceComb官網(wǎng)或者ServiceComb 示例庫找到對應的例子。
開源微服務框架 Apache ServiceComb 的主體代碼是由華為云微服務引擎捐贈給 Apache 軟件基金會的,愿景是幫助企業(yè)快速構建云原生應用,通過一系列解決方案幫助用戶快速開發(fā)微服務應用的同時實現(xiàn)對這些微服務應用的高效運維管理。本次設計團隊將開放性設計部分細節(jié)點點滴滴分享出來也是為了能夠對解放微服務開發(fā)者和用戶能有所幫助。
當前越來越多的貢獻者已加入到 社區(qū)行列,Apache ServiceComb 會和這些志愿者們一起一如既往堅持這個理念,爭取給業(yè)界帶來更多好的技術和分享。也期望有更多有志者一起行動。
以上就是如何實現(xiàn)微服務框架Apache ServiceComb的開放性設計,小編相信有部分知識點可能是我們?nèi)粘9ぷ鲿姷交蛴玫降?。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業(yè)資訊頻道。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。