Bugsnag(注:一家云端bug監(jiān)控服務(wù)商)每天處理數(shù)以億計(jì)的錯(cuò)誤信息,為了處理這些數(shù)據(jù),考慮優(yōu)先構(gòu)建一個(gè)可擴(kuò)展,性能強(qiáng)大的后端系統(tǒng),并從中學(xué)到很多有挑戰(zhàn)性的技術(shù)。最近,我們推出了新版本的儀表板,這個(gè)項(xiàng)目要求擴(kuò)展系統(tǒng),來(lái)處理服務(wù)呼叫的顯著增加,這些呼叫是跟蹤用戶發(fā)布和會(huì)話所需的。
儀表板的發(fā)布在進(jìn)行中,工程團(tuán)隊(duì)將Bugsnag的后端功能分解成稱之為管道(pipeline)的微服務(wù)體系。將管道擴(kuò)展到支持發(fā)布,意味著增加新的服務(wù),并修改現(xiàn)有服務(wù),也可預(yù)見到許多新的服務(wù)器和客戶端的交互。為了處理上述架構(gòu)的變化,需要采用一致性的方式來(lái)設(shè)計(jì),實(shí)施和集成企業(yè)的服務(wù)。Bugsnag是一家多語(yǔ)言的公司,服務(wù)是用Java,Ruby,Go和Node.js等多語(yǔ)言編寫,因此企業(yè)需要一種與平臺(tái)無(wú)關(guān)的方法。
本文將介紹為什么我們最終選擇了gRPC作為Pipeline的默認(rèn)通信框架。
達(dá)到REST API設(shè)計(jì)的極限
現(xiàn)有系統(tǒng)傳統(tǒng)上使用具有JSON有效載荷的REST API進(jìn)行同步通信。這種選擇是基于占?jí)旱剐员壤某墒於?、熟悉度和工具的可用性做出的,但是隨著跨洲際工程團(tuán)隊(duì)的增長(zhǎng),企業(yè)需要設(shè)計(jì)一致的,基于RESTful API的工具。
不幸的是,這感覺就像試圖將簡(jiǎn)單的方法調(diào)用變成一個(gè)數(shù)據(jù)驅(qū)動(dòng)的RESTful界面。這滿足了RESTful接口的verb,header,URL標(biāo)識(shí)符,資源的URL和有效載荷的神奇組合,并做了一個(gè)清潔,簡(jiǎn)單,看起來(lái)幾乎不可能實(shí)現(xiàn)的功能界面。RESTful有很多規(guī)則和解釋,在大多數(shù)情況下會(huì)導(dǎo)致REST ish接口,這需要花費(fèi)額外的時(shí)間和精力來(lái)保持其純度。
最終,考慮到RESTAPI的復(fù)雜性,我們找到了替代方案。希望微服務(wù)盡可能相互隔離,減少交互和解耦服務(wù)。它可以讓企業(yè)在很短的時(shí)間內(nèi)創(chuàng)造出一個(gè)可行的服務(wù),并防止跳過hoops。
評(píng)估REST的替代方案
不要輕易選擇通信框架。大型組織(如Netflix)可以擁有超過500+個(gè)微服務(wù)的后端系統(tǒng)。遷移這些服務(wù)以取代不充分的服務(wù)間通信會(huì)花費(fèi)大量時(shí)間,從后勤和財(cái)務(wù)角度看這很不切實(shí)際?;〞r(shí)間從一開始就考慮正確的框架,可以省去很多未來(lái)的浪費(fèi)。
我們花了大量的時(shí)間來(lái)制定評(píng)估標(biāo)準(zhǔn)和研究、選擇。Bugsnag到底長(zhǎng)什么樣子呢?
技術(shù)標(biāo)準(zhǔn)
在研究可用選項(xiàng)時(shí),使用了一些特定的標(biāo)準(zhǔn)來(lái)評(píng)估。要考慮的事情是基于微服務(wù)架構(gòu)的最有效的方法。主要目標(biāo)是自由地使用通信,消除通信的復(fù)雜性,了解每項(xiàng)服務(wù)的責(zé)任所在。其中的一些技術(shù)問題是:
速度 - 對(duì)于大量的請(qǐng)求/響應(yīng)API調(diào)用,需要將調(diào)用本身的延遲作為性能和用戶響應(yīng)速度的最小因素。延遲的主要組成部分是連接成本,傳輸成本和消息編碼/解碼時(shí)間。
基礎(chǔ)架構(gòu)兼容性 - 框架在基礎(chǔ)架構(gòu)中扮演的角色如何?主要是關(guān)于負(fù)載平衡和自動(dòng)擴(kuò)展?我們使用托管在Google云端平臺(tái)上的Kubernetes服務(wù),因此需要框架來(lái)兼容這種環(huán)境。
開發(fā)工具 - 在實(shí)現(xiàn)框架時(shí),提供盡可能小的摩擦將會(huì)使開發(fā)人員更快捷。哪些工具可以幫助編碼,本地測(cè)試端點(diǎn),以及單元和集成測(cè)試的stubbing/mocking?當(dāng)事情出錯(cuò)時(shí),我們需要能夠看到包括內(nèi)容在內(nèi)的請(qǐng)求信息。消息格式等因素也可以使調(diào)試更容易依賴于工具,例如JSON消息是人可讀的,但是二進(jìn)制消息將需要額外的努力來(lái)解碼。
成熟度和采用 - 對(duì)于初創(chuàng)公司來(lái)說(shuō),資源是有限的,需要花費(fèi)在公司的核心業(yè)務(wù)上,而不是修復(fù),測(cè)試和增強(qiáng)第三方框架。諸如框架的普及,大規(guī)模使用的例子,社區(qū)的活躍程度以及框架本身的成熟度等因素都是穩(wěn)定性的良好指標(biāo)。需要強(qiáng)調(diào)的是,選擇一個(gè)解決具體問題的框架,而并非選擇最新最熱的。
多平臺(tái)支持 - 在真正的微服務(wù)思維中,使用最適合其目的的語(yǔ)言編寫企業(yè)的服務(wù),目前包括Java,Ruby,Go和Node??蚣苁欠駷楝F(xiàn)有的語(yǔ)言選擇提供了一流的支持,同時(shí)提供了用其他語(yǔ)言編寫新服務(wù)的選項(xiàng)?
代碼量 - 框架應(yīng)該有助于降低工程成本。企業(yè)需要編寫和維護(hù)多少代碼才能使其工作?與業(yè)務(wù)邏輯相比,這是多少樣板代碼?
安全 - 所有的內(nèi)部通信都應(yīng)該被認(rèn)證和加密。我們需要能夠使用所有通信的SSL / TLS(或等價(jià)物)。
設(shè)計(jì)上的考慮,并非都與技術(shù)有關(guān)
服務(wù)API是最重要的接口之一,因?yàn)樵陂_發(fā)過程中對(duì)設(shè)置服務(wù)期望至關(guān)重要。解決服務(wù)API的設(shè)計(jì)是一項(xiàng)艱巨的任務(wù),當(dāng)不同的團(tuán)隊(duì)負(fù)責(zé)所涉及的不同服務(wù)時(shí),該任務(wù)會(huì)被放大。最大限度地減少由于預(yù)期不匹配而浪費(fèi)的時(shí)間和精力,與縮短編碼時(shí)間一樣有價(jià)值。由于Bugsnag擁有跨地區(qū)的工程團(tuán)隊(duì),因此溝通時(shí)間有限。必須通過簡(jiǎn)化溝通,確保事情不用那么多解釋,否則錯(cuò)誤很容易產(chǎn)生,事情很容易被拖延。
以下是在選擇框架時(shí)的一些設(shè)計(jì)考慮因素:
強(qiáng)類型 - 消息是否是強(qiáng)類型的?如果通過服務(wù)邊界發(fā)送的消息清晰可見,那么可以消除由于類型而造成的設(shè)計(jì)和運(yùn)行時(shí)錯(cuò)誤。
打開解釋 - 能夠直接從服務(wù)API規(guī)范生成客戶端庫(kù),減少了誤解的問題。錯(cuò)誤條件 - 有一套明確定義的錯(cuò)誤代碼可以更容易一致地交流問題。
文檔 - 服務(wù)API應(yīng)該是易讀易懂的。定義服務(wù)API的格式應(yīng)該盡可能清楚,準(zhǔn)確地描述端點(diǎn)。
版本控制 - 更改是不可避免的,這是一個(gè)很好的選擇,在某些時(shí)候,服務(wù)API將需要修改。所使用的消息傳遞格式和服務(wù)定義可以影響修改API并將其部署到生產(chǎn)的容易程度。是否有明確的路徑來(lái)增加版本及其相應(yīng)的庫(kù),并推出更改?
微服務(wù)最佳實(shí)踐,為什么可擴(kuò)展性是重要的
除了上面列出的標(biāo)準(zhǔn)外,還需要選擇一個(gè)易于擴(kuò)展的框架。隨著微服務(wù)的發(fā)展,企業(yè)需要越來(lái)越多的“開箱即用”功能,發(fā)展的同時(shí),為系統(tǒng)增加了更多的復(fù)雜性。因此企業(yè)希望的功能包括:
異常處理 - 在請(qǐng)求級(jí)別提供一個(gè)處理異常的機(jī)制。它允許捕獲有關(guān)請(qǐng)求的重要上下文元數(shù)據(jù),例如發(fā)出請(qǐng)求的用戶,可以用例外報(bào)告。我們使用Bugsnag輕松地監(jiān)視這些異常。
智能重試 - 在特定條件下重試請(qǐng)求,例如僅在5xx狀態(tài)碼上。這包括支持各種退避策略,如指數(shù)退避。
服務(wù)發(fā)現(xiàn)配置 - 將通信框架連接到流行的服務(wù)發(fā)現(xiàn)應(yīng)用程序(如Zookeeper,Eureka或Consul)的選項(xiàng)可以提供一種快速簡(jiǎn)便的解決方案,以繞過企業(yè)的架構(gòu)來(lái)請(qǐng)求路由。
度量、跟蹤和日志記錄 - 可觀察性對(duì)于復(fù)雜的分布式系統(tǒng)是必不可少的,但是應(yīng)該小心監(jiān)視的內(nèi)容。在服務(wù)邊界自動(dòng)收集指標(biāo)和跟蹤信息可以快速回答常見問題,例如“我的服務(wù)對(duì)請(qǐng)求響應(yīng)緩慢嗎?”以及“請(qǐng)求失敗的頻率如何?”。
熔斷 - 這種模式可以通過自動(dòng)檢測(cè)問題和快速失敗來(lái)防止級(jí)聯(lián)服務(wù)故障。也可以由長(zhǎng)時(shí)間緩慢的請(qǐng)求來(lái)觸發(fā),以提供響應(yīng)降級(jí)的服務(wù)而不是不斷地超時(shí)。
緩存和批處理 - 通過使用緩存或批處理請(qǐng)求來(lái)加速請(qǐng)求。
大多數(shù)框架不會(huì)提供所有功能,但至少它們應(yīng)該是可擴(kuò)展的,以便在需要時(shí)添加。
什么是gRPC和協(xié)議緩沖區(qū)?
沒有一個(gè)框架是萬(wàn)能的。我們探索的一些選項(xiàng)包括Facebook的Thrift,Apache Hadoop的Avro,Twitter的Finagle,甚至使用JSON模式。
我們的需求更接近于遠(yuǎn)程程序調(diào)用(RPC),給予所需要的細(xì)粒度控制。使用RPC的另一個(gè)吸引力是使用接口描述語(yǔ)言或IDL。IDL允許以獨(dú)立于語(yǔ)言的格式描述服務(wù)API,將接口與任何特定的編程語(yǔ)言分離。他們可以提供一系列的好處,包括服務(wù)API的一個(gè)單一的事實(shí)來(lái)源,并可能被用來(lái)生成客戶端和服務(wù)器代碼來(lái)與這些服務(wù)進(jìn)行交互。IDL的例子包括Thrift,Avro,CORBA,當(dāng)然還有ProtocolBuffers。
最后,明確的獲勝者是基于協(xié)議緩沖區(qū)的gRPC。
什么是gRPC?
我們選擇了gRPC,因?yàn)樗鼭M足了我們的功能需求(包括未來(lái)的可擴(kuò)展性),背后的活躍社區(qū)以及HTTP / 2框架的使用。
gRPC是由Google開發(fā),設(shè)計(jì)用于傳統(tǒng)的RPC調(diào)用。該框架使用最新的網(wǎng)絡(luò)傳輸協(xié)議HTTP / 2,主要用于通過使用流的單個(gè)TCP連接來(lái)實(shí)現(xiàn)低延遲和多路復(fù)用請(qǐng)求。與REST over HTTP / 1.1相比,gRPC非常快速和靈活。
gRPC的性能對(duì)于設(shè)置管道來(lái)處理儀表板發(fā)布的大量增加至關(guān)重要。此外,HTTP / 2是下一個(gè)標(biāo)準(zhǔn)化的網(wǎng)絡(luò)協(xié)議,可以利用為HTTP / 2開發(fā)的工具和技術(shù)(如Envoy代理),并為gRPC提供一流的支持。由于多路復(fù)用流支持,gRPC支持雙向通信,不限于簡(jiǎn)單的請(qǐng)求/響應(yīng)呼叫。
什么是Protobufs(協(xié)議緩沖區(qū))?
Protocol Buffers或protobufs是定義和序列化結(jié)構(gòu)化數(shù)據(jù)為高效的二進(jìn)制格式的一種方式,也是由Google開發(fā)的。二者的有效結(jié)合,也是我們選擇gRPC的主要原因之一。
以前有許多與想修復(fù)的版本相關(guān)的問題。微服務(wù)意味著必須不斷更新,需要適應(yīng)并保持向前和向后兼容的接口,protobufs對(duì)此非常有用。由于是二進(jìn)制格式,所以它們也是通過wire快速發(fā)送的小型有效載荷。
Protobuf消息使用關(guān)聯(lián)的IDL進(jìn)行描述,它提供了一個(gè)緊湊的,強(qiáng)類型的,向后兼容的格式來(lái)定義消息和RPC服務(wù)。我們使用最新的proto3規(guī)范,并在此處顯示protobuf消息的實(shí)際示例。
所有字段proto3都是可選的。如果未設(shè)置字段,將始終使用默認(rèn)值。這與字段編號(hào)相結(jié)合提供了一個(gè)API,可以非常抵抗打破變化。通過遵循一些簡(jiǎn)單的規(guī)則,向前和向后兼容性可以成為大多數(shù)API更改的默認(rèn)值。
protobuf格式還允許定義RPC服務(wù)本身。服務(wù)端點(diǎn)與消息結(jié)構(gòu)共存,在單個(gè)protobuf文件中提供RPC服務(wù)的自包含定義。對(duì)于我們的跨洲際的工程團(tuán)隊(duì)來(lái)說(shuō),這非常有用,他們可以從一個(gè)文件中了解服務(wù)如何工作,生成客戶端并開始使用它。以下是我們的服務(wù)之一:
該框架能夠生成代碼來(lái)使用protobuf文件與這些服務(wù)進(jìn)行交互,這是另一個(gè)優(yōu)勢(shì),它可以自動(dòng)生成需要的所有類。這個(gè)生成的代碼負(fù)責(zé)消息建模,并提供一個(gè)存根類,其中包含與您的服務(wù)端點(diǎn)相關(guān)的重復(fù)方法調(diào)用。
支持多種語(yǔ)言,包括C ++,Java,Python,Go,Ruby,C#,Node,Android,Objective-C和PHP。但是,使用protobuf文件維護(hù)和同步生成的代碼是個(gè)問題。我們已經(jīng)能夠通過使用Protobuf文件自動(dòng)生成客戶端庫(kù)來(lái)解決這個(gè)問題,會(huì)在即將發(fā)布的下一篇博客文章中分享更多的內(nèi)容。
gRPC最好的特性之一是支持中間件模式,被稱為攔截器。它允許擴(kuò)展所有的gRPC實(shí)現(xiàn)(這對(duì)企業(yè)來(lái)說(shuō)很重要),能夠輕松訪問所有請(qǐng)求,從而實(shí)現(xiàn)自己的微服務(wù)最佳實(shí)踐。gRPC還內(nèi)置了對(duì)一系列認(rèn)證機(jī)制的支持,包括SSL / TLS。
gRPC社區(qū)
我們正處于gRPC采用的開始階段,期待社區(qū)提供更多的工具和技術(shù)。很高興能夠加入這個(gè)充滿活力的社區(qū),并對(duì)未來(lái)的項(xiàng)目有一些想法,我們希望看到這些項(xiàng)目是開放源代碼或我們自己寫的。
gRPC工具的當(dāng)前狀態(tài)
gRPC比較新,缺乏可用的開發(fā)工具,特別是與經(jīng)驗(yàn)豐富的REST over HTTP / 1.1協(xié)議相比。搜索教程和示例時(shí),這一點(diǎn)尤其明顯,因?yàn)橹挥猩贁?shù)有用的信息。二進(jìn)制格式也使消息不透明,需要努力解碼。雖然有一些選擇,例如JSON代碼轉(zhuǎn)換器可以幫助,但預(yù)計(jì)需要做一些基礎(chǔ)工作,以便為gRPC提供順暢的開發(fā)體驗(yàn)。
我們喜歡用Apiary 來(lái)記錄外部API。使用服務(wù)協(xié)議緩沖區(qū)(protobuf)文件自動(dòng)生成交互式文檔的等價(jià)物,將是理想的有效的內(nèi)部通信gRPCAPI。protobuf文件的靜態(tài)分析在運(yùn)行時(shí)能捕獲更多的bug。使用Checkstyle作為Java代碼,并且把它用作類似于protobuf的文件。自定義攔截器可以提供跟蹤,日志記錄和錯(cuò)誤監(jiān)視功能。我們希望開源我們的Bugsnag gRPC攔截器,以自動(dòng)捕獲并向Bugsnag報(bào)告錯(cuò)誤。gRPC的增長(zhǎng)和采用
在過去幾年中,gRPC的普及度大幅增長(zhǎng),Square,Lyft,Netflix,Docker,Cisco和CoreOS等公司大規(guī)模采用。Netflix Ribbon是基于RPC調(diào)用使用REST的微服務(wù)通信框架的事實(shí)標(biāo)準(zhǔn)。今年,他們宣布,由于其多語(yǔ)言支持和更好的可擴(kuò)展性/可組合性,他們正在向gRPC過渡。該框架最近也于2017年3月加入了CNCF基金會(huì),支持重量級(jí)的Kubernetes和Prometheus。gRPC社區(qū)非常活躍,與開源gRPC生態(tài)系統(tǒng) 列出了許多gRPC激動(dòng)人心的項(xiàng)目。
另外,gRPC有我們認(rèn)同的原則
Lyft在轉(zhuǎn)向gRPC方面做了大量的討論,這與我們的經(jīng)驗(yàn)非常相似:使用Protocol Buffers和gRPC生成統(tǒng)一的API。值得一試。
gRPC現(xiàn)在還處于初期階段,存在一些明顯的磨合問題,但未來(lái)前景光明。總的來(lái)說(shuō),我們對(duì)gRPC如何整合到后端系統(tǒng)非常樂觀,并且很高興見證這個(gè)框架的發(fā)展。
原文鏈接:
https://blog.bugsnag.com/grpc-and-microservices-architecture/?utm_source=tuicool&utm_medium=referral