基于gRPC服务发现与服务治理的方案
重溫最少化集群搭建,我相信很多朋友都已經(jīng)搭建出來,基于Watch機(jī)制也實(shí)現(xiàn)了出來,相信也有很多朋友有了自己的實(shí)現(xiàn)思路,但是,很多朋友有個疑問,我API和服務(wù)分離好了,怎么通過服務(wù)中心進(jìn)行發(fā)現(xiàn)呢,這個過程是通過什么來實(shí)現(xiàn)的呢,本篇我們就來介紹這個“調(diào)用過程”。
本篇干貨較多,沒有代碼,閱讀請注意休息!
?
服務(wù)化引入
網(wǎng)站系統(tǒng)隨著不斷的發(fā)展,越來越復(fù)雜,架構(gòu)的變遷也會從MVC—>SOA—>微服務(wù),從簡單到復(fù)雜,從集中到分布,服務(wù)化框架的引入是SOA—>微服務(wù)過程必須要解決的問題。面對服務(wù)的增多,服務(wù)分布的部署,服務(wù)與服務(wù)之間相互的調(diào)用,不得不使用服務(wù)化框架去解決,著名的dubbo和spring cloud就是這樣產(chǎn)生的。
?
服務(wù)化框架介紹
服務(wù)化框架分為兩部分:遠(yuǎn)程調(diào)用、注冊中心。
?
遠(yuǎn)程調(diào)用:遠(yuǎn)程調(diào)用的傳輸協(xié)議有很多種,可以走h(yuǎn)ttp、webservice、tcp等。facebook的thrift、google的grpc、alibaba的dubbo都是世界上主流的rpc框架。其重點(diǎn)在于安全、快速、跨語言。
注冊中心:用于存放,服務(wù)的ip地址和狀態(tài)信息等。比較好的存放服務(wù)信息的方案有:zookeeper、consul、etcd。其重點(diǎn)在于避免單點(diǎn)問題,并且好維護(hù)。
?
服務(wù)化框架原理和調(diào)用方式
根據(jù)上面圖,服務(wù)化原理可以分為3步:
服務(wù)端啟動并且向注冊中心發(fā)送服務(wù)信息,注冊中心收到后會定時監(jiān)控服務(wù)狀態(tài)(常見心跳檢測);
客戶端需要開始調(diào)用服務(wù)的時候,首先去注冊中心獲取服務(wù)信息;
客戶端創(chuàng)建遠(yuǎn)程調(diào)用連接,連接后服務(wù)端返回處理信息;
?
第3步又可以細(xì)分,下面說說遠(yuǎn)程過程調(diào)用的原理:目標(biāo):客戶端怎么調(diào)用遠(yuǎn)程機(jī)器上的公開方法:
?
服務(wù)發(fā)現(xiàn),向注冊中心獲取服務(wù)(這里需要做的有很多:拿到多個服務(wù)時需要做負(fù)載均衡,同機(jī)房過濾、版本過濾、服務(wù)路由過濾、統(tǒng)一網(wǎng)關(guān)等);
客戶端發(fā)起調(diào)用,將需要調(diào)用的服務(wù)、方法、參數(shù)進(jìn)行組裝;
序列化編碼組裝的消息,這里可以使用json,也可以使用xml,也可以使用protobuf,也可以使用hessian,幾種方案的序列化速度還有序列化后占用字節(jié)大小都是選擇的重要指標(biāo),對內(nèi)筆者建議使用高效的protobuf,它基于TCP/IP二進(jìn)制進(jìn)行序列化,體積小,速度快。
傳輸協(xié)議,可以使用傳統(tǒng)的io阻塞傳輸,也可以使用高效的nio傳輸(Netty);
服務(wù)端收到后進(jìn)行反序列化,然后進(jìn)行相應(yīng)的處理;
服務(wù)端序列化response信息并且返回;
客戶端收到response信息并且反序列化;
?
RESTful和RPC
RESTful?:?嚴(yán)格意義上說接口很規(guī)范,操作對象即為資源,對資源的四種操作(post、get、put、delete),常見的http api都可以稱為Rest接口。
?
RPC?:?我們常說的遠(yuǎn)程方法調(diào)用,就是像調(diào)用本地方法一樣調(diào)用遠(yuǎn)程方法,通信協(xié)議大多采用二進(jìn)制方式。?
?
Http vs 高性能二進(jìn)制協(xié)議
http相對更規(guī)范,更標(biāo)準(zhǔn),更通用,無論哪種語言都支持http協(xié)議。如果你是對外開放API,例如開放平臺,外部的編程語言多種多樣,你無法拒絕對每種語言的支持,相應(yīng)的,如果采用http,無疑在你實(shí)現(xiàn)SDK之前,支持了所有語言,所以,現(xiàn)在開源中間件,基本最先支持的幾個協(xié)議都包含RESTful。
RPC協(xié)議性能要高的多,例如Protobuf、Thrift、Kyro等,(如果算上序列化)吞吐量大概能達(dá)到http的二倍(甚至更高)。響應(yīng)時間也更為出色。千萬不要小看這點(diǎn)性能損耗,公認(rèn)的,微服務(wù)做的比較好的,例如,netflix、阿里,曾經(jīng)都傳出過為了提升性能而合并服務(wù)。如果是交付型的項目,性能更為重要,因?yàn)槟阗u給客戶往往靠的就是性能上微弱的優(yōu)勢。
?
RESTful筆者不做實(shí)際操作的介紹,程序員們個個都懂。
?
gRPC介紹
gRPC is a modern, open source, high-performance remote procedure call (RPC) framework that can run anywhere. It enables client and server applications to communicate transparently, and makes it easier to build connected systems.
gRPC是一種可以在任何地方運(yùn)行的現(xiàn)代、開源、高性能遠(yuǎn)程過程調(diào)用(RPC)框架,它使客戶端和服務(wù)端應(yīng)用程序透明地通信,并使構(gòu)建連接的系統(tǒng)更容易。
gRPC 一開始由 google 開發(fā),是一款語言中立、平臺中立、開源的遠(yuǎn)程過程調(diào)用(RPC)系統(tǒng)。
在gRPC里客戶端應(yīng)用可以像調(diào)用本地對象一樣直接調(diào)用另一臺不同的機(jī)器上服務(wù)端應(yīng)用的方法,使得您能夠更容易地創(chuàng)建分布式應(yīng)用和服務(wù)。與許多 RPC 系統(tǒng)類似,gRPC 也是基于以下理念:定義一個服務(wù),指定其能夠被遠(yuǎn)程調(diào)用的方法(包含參數(shù)和返回類型)。在服務(wù)端實(shí)現(xiàn)這個接口,并運(yùn)行一個 gRPC 服務(wù)器來處理客戶端調(diào)用。在客戶端擁有一個存根能夠像服務(wù)端一樣的方法。
基于HTTP/2
HTTP/2 提供了連接多路復(fù)用、雙向流、服務(wù)器推送、請求優(yōu)先級、首部壓縮等機(jī)制。可以節(jié)省帶寬、降低TCP鏈接次數(shù)、節(jié)省CPU,幫助移動設(shè)備延長電池壽命等。gRPC 的協(xié)議設(shè)計上使用了HTTP2 現(xiàn)有的語義,請求和響應(yīng)的數(shù)據(jù)使用HTTP Body 發(fā)送,其他的控制信息則用Header 表示。
IDL使用ProtoBuf
gRPC使用ProtoBuf來定義服務(wù),ProtoBuf是由Google開發(fā)的一種數(shù)據(jù)序列化協(xié)議(類似于XML、JSON、hessian)。ProtoBuf能夠?qū)?shù)據(jù)進(jìn)行序列化,并廣泛應(yīng)用在數(shù)據(jù)存儲、通信協(xié)議等方面。壓縮和傳輸效率高,語法簡單,表達(dá)力強(qiáng)。
多語言支持(C, C++, Python, PHP, Nodejs, C#, Objective-C、Golang、Java)
gRPC支持多種語言,并能夠基于語言自動生成客戶端和服務(wù)端功能庫。目前已提供了C版本grpc、Java版本grpc-java 和 Go版本grpc-go,其它語言的版本正在積極開發(fā)中,其中,grpc支持C、C++、Node.js、Python、Ruby、Objective-C、PHP和C#等語言,grpc-java已經(jīng)支持Android開發(fā)。
?
與thrift,dubbo,motan等比較
?
使用gRPC的公司:
Mochi中國
阿里OTS
騰訊部分部門
Tensorflow項目中使用了grpc
CoreOS — Production API for etcd v3 is entirely gRPC. etcd v3的接口全部使用grpc
Square — replacement for all of their internal RPC. one of the very first adopters and contributors to gRPC.
ngrok — all 20+ internal services communicate via gRPC 一個內(nèi)網(wǎng)轉(zhuǎn)發(fā)產(chǎn)品
Netflix
Yik Yak
VSCO
Cockroach
?
gRPC的優(yōu)點(diǎn)和缺點(diǎn):
優(yōu)點(diǎn):
protobuf二進(jìn)制消息,性能好/效率高(空間和時間效率都很不錯);
proto文件生成目標(biāo)代碼,簡單易用;
序列化反序列化直接對應(yīng)程序中的數(shù)據(jù)類,不需要解析后在進(jìn)行映射(XML,JSON都是這種方式);
支持向前兼容(新加字段采用默認(rèn)值)和向后兼容(忽略新加字段),簡化升級;
支持多種語言(可以把proto文件看做IDL文件);
Netty等一些框架集成;
缺點(diǎn):
GRPC尚未提供連接池,需要自行實(shí)現(xiàn);
尚未提供“服務(wù)發(fā)現(xiàn)”、“負(fù)載均衡”機(jī)制;
因?yàn)榛贖TTP2,絕大部多數(shù)HTTP Server、Nginx都尚不支持,即Nginx不能將GRPC請求作為HTTP請求來負(fù)載均衡,而是作為普通的TCP請求。(nginx1.9版本已支持);
Protobuf二進(jìn)制可讀性差(貌似提供了Text_Fromat功能,沒用過);
默認(rèn)不具備動態(tài)特性(可以通過動態(tài)定義生成消息類型或者動態(tài)編譯支持);
?
protobuf的版本
PB具有三個版本:
1:Google官方版本:https://github.com/google/protobuf/tree/master/csharp(谷歌官方開發(fā)、比較晦澀和高大上,主庫名字:Google.ProtoBuf.dll)
2:.Net社區(qū)版本(一):https://github.com/mgravell/protobuf-net(.Net社區(qū)愛好者開發(fā),寫法上比較符合.net上的語法習(xí)慣,主庫名字:protobuf-net.dll)
3:.Net社區(qū)版本(二):https://github.com/jskeet/protobuf-csharp-port(據(jù)說是由谷歌的.net員工為.net開發(fā),在官方?jīng)]有出來csharp的時候開發(fā),到發(fā)博文時還在維護(hù),主庫名字:Google.ProtocolBuffers.dll)
至于選用那個版本,跨平臺的需求不大的話,可以用版本二、大的話可以選用一或者三。(本文后續(xù)選用二為例)
? ? ? ??
gRPC服務(wù)發(fā)現(xiàn)與服務(wù)治理的方案
目前gRPC主流分布式方案有這么幾種: etcd, zookeeper, consul.
1、集中式LB(Proxy Model)
在服務(wù)消費(fèi)者和服務(wù)提供者之間有一個獨(dú)立的LB,通常是專門的硬件設(shè)備如 F5,或者基于軟件如 LVS,HAproxy等實(shí)現(xiàn)。LB上有所有服務(wù)的地址映射表,通常由運(yùn)維配置注冊,當(dāng)服務(wù)消費(fèi)方調(diào)用某個目標(biāo)服務(wù)時,它向LB發(fā)起請求,由LB以某種策略,比如輪詢(Round-Robin)做負(fù)載均衡后將請求轉(zhuǎn)發(fā)到目標(biāo)服務(wù)。LB一般具備健康檢查能力,能自動摘除不健康的服務(wù)實(shí)例。 該方案主要問題:
?
1、單點(diǎn)問題,所有服務(wù)調(diào)用流量都經(jīng)過LB,當(dāng)服務(wù)數(shù)量和調(diào)用量大的時候,LB容易成為瓶頸,且一旦LB發(fā)生故障影響整個系統(tǒng);
2、服務(wù)消費(fèi)方、提供方之間增加了一級,有一定性能開銷。
?
2、進(jìn)程內(nèi)LB(Balancing-aware Client)
針對第一個方案的不足,此方案將LB的功能集成到服務(wù)消費(fèi)方進(jìn)程里,也被稱為軟負(fù)載或者客戶端負(fù)載方案。服務(wù)提供方啟動時,首先將服務(wù)地址注冊到服務(wù)注冊表,同時定期報心跳到服務(wù)注冊表以表明服務(wù)的存活狀態(tài),相當(dāng)于健康檢查,服務(wù)消費(fèi)方要訪問某個服務(wù)時,它通過內(nèi)置的LB組件向服務(wù)注冊表查詢,同時緩存并定期刷新目標(biāo)服務(wù)地址列表,然后以某種負(fù)載均衡策略選擇一個目標(biāo)服務(wù)地址,最后向目標(biāo)服務(wù)發(fā)起請求。LB和服務(wù)發(fā)現(xiàn)能力被分散到每一個服務(wù)消費(fèi)者的進(jìn)程內(nèi)部,同時服務(wù)消費(fèi)方和服務(wù)提供方之間是直接調(diào)用,沒有額外開銷,性能比較好。該方案主要問題:
?
1、開發(fā)成本,該方案將服務(wù)調(diào)用方集成到客戶端的進(jìn)程里頭,如果有多種不同的語言棧,就要配合開發(fā)多種不同的客戶端,有一定的研發(fā)和維護(hù)成本;
2、另外生產(chǎn)環(huán)境中,后續(xù)如果要對客戶庫進(jìn)行升級,勢必要求服務(wù)調(diào)用方修改代碼并重新發(fā)布,升級較復(fù)雜。
?
3、獨(dú)立 LB 進(jìn)程(External Load Balancing Service)
該方案是針對第二種方案的不足而提出的一種折中方案,原理和第二種方案基本類似。
不同之處是將LB和服務(wù)發(fā)現(xiàn)功能從進(jìn)程內(nèi)移出來,變成主機(jī)上的一個獨(dú)立進(jìn)程。主機(jī)上的一個或者多個服務(wù)要訪問目標(biāo)服務(wù)時,他們都通過同一主機(jī)上的獨(dú)立LB進(jìn)程做服務(wù)發(fā)現(xiàn)和負(fù)載均衡。該方案也是一種分布式方案沒有單點(diǎn)問題,一個LB進(jìn)程掛了只影響該主機(jī)上的服務(wù)調(diào)用方,服務(wù)調(diào)用方和LB之間是進(jìn)程內(nèi)調(diào)用性能好,同時該方案還簡化了服務(wù)調(diào)用方,不需要為不同語言開發(fā)客戶庫,LB的升級不需要服務(wù)調(diào)用方改代碼。
該方案主要問題:部署較復(fù)雜,環(huán)節(jié)多,出錯調(diào)試排查問題不方便。
?
服務(wù)發(fā)現(xiàn)負(fù)載均衡實(shí)現(xiàn)
gRPC開源組件官方并未直接提供服務(wù)注冊與發(fā)現(xiàn)的功能實(shí)現(xiàn),但其設(shè)計文檔已提供實(shí)現(xiàn)的思路,并在不同語言的gRPC代碼API中已提供了命名解析和負(fù)載均衡接口供擴(kuò)展。?
其基本實(shí)現(xiàn)原理:
1、服務(wù)啟動后gRPC客戶端向命名服務(wù)器發(fā)出名稱解析請求,名稱將解析為一個或多個IP地址,每個IP地址標(biāo)示它是服務(wù)器地址還是負(fù)載均衡器地址,以及標(biāo)示要使用那個客戶端負(fù)載均衡策略或服務(wù)配置。
2、客戶端實(shí)例化負(fù)載均衡策略,如果解析返回的地址是負(fù)載均衡器地址,則客戶端將使用grpclb策略,否則客戶端使用服務(wù)配置請求的負(fù)載均衡策略。
3、負(fù)載均衡策略為每個服務(wù)器地址創(chuàng)建一個子通道(channel)。
4、當(dāng)有rpc請求時,負(fù)載均衡策略決定那個子通道即grpc服務(wù)器將接收請求,當(dāng)可用服務(wù)器為空時客戶端的請求將被阻塞。
原文地址:?https://www.cnblogs.com/SteveLee/p/9813591.html
.NET社區(qū)新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com
總結(jié)
以上是生活随笔為你收集整理的基于gRPC服务发现与服务治理的方案的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: .NET 源代码库指南
- 下一篇: 独立版Jexus配置SSL,支持http