gRPC的結(jié)構(gòu)?

          在我們搭建gRPC通信系統(tǒng)之前,首先需要知道gRPC的結(jié)構(gòu)組成。?

          首先,需要一個server(服務(wù)器),它用來接收和處理請求,然后返回響應(yīng)。?


          既然有server,那么肯定有client(客戶端),client的作用就是向server發(fā)送請求,具體就是生成一個請求,然后把它發(fā)送到server,然后等待server的響應(yīng)。
          ?


          但是它們不必是一對一的關(guān)系,在整個系統(tǒng)里,可以有多個server,也可以有多個client。根據(jù)實際情況,一個應(yīng)用程序可能是gRPC的server,也可能是gRPC的client,也可能兩者都是。
          ?

          ?

          gRPC里面server和client并不是直接通信的,gRPC可以使用protocol buffer定義的消息來生成代碼。?


          當(dāng)client發(fā)送請求的時候,它會和server端生成的代碼進(jìn)行交互;同樣在client端也有生成的代碼,client端生成的代碼負(fù)責(zé)提供一個隧道,這個隧道被用來吧client端生成的消息發(fā)送給server。
          ?

          因為server和client兩端都有生成的代碼,所以如何序列化和反序列化,以及如何進(jìn)行來回的傳輸?shù)燃?xì)節(jié),我們都可以不了解。?

          ?


          但是為了讓server和client端來回傳輸通信,我們還需要一個協(xié)議,傳輸協(xié)議就負(fù)責(zé)把消息來回的傳遞。所以它并不需要懂得這些消息的內(nèi)容,生成的代碼會負(fù)責(zé)理解這些消息,但是傳輸協(xié)議需要負(fù)責(zé)把消息從一端傳遞到另一端。
          ?

          目前,好像gRPC只能使用Protocol Buffer這一個傳輸協(xié)議。但是gRPC在設(shè)計的時候,它的傳輸層是可插拔的,所以如果我們想把Protocol
          Buffer使用某種JSON或XML的協(xié)議替換掉,是可行的。如果你有特定的需求使用Protocol Buffer無法實現(xiàn)的話,那么你也可以創(chuàng)建自己的傳輸協(xié)議。?

          ?

          設(shè)計步驟?

          總共應(yīng)該分三步。設(shè)計原則是從里到外(看上面結(jié)構(gòu)圖)。?

          所以:?

          *
          首先我們應(yīng)該定義消息(message)。這些消息使用Protocol?Buffer來進(jìn)行定義?

          *
          定義完消息,我們使用Proto-c編譯器來生成server和client端的代碼,它們會負(fù)責(zé)把消息在兩端之間來回傳遞?

          *
          現(xiàn)在,我們就可以寫client和server了。?

          ?

          ?

          gRPC?生命周期?

          ?

          ?

          gRPC或者RPC的生命周期可以參考上圖。?

          首先,需要創(chuàng)建一個隧道,該隧道會包裝實際用來傳輸消息的線路協(xié)議。?

          例如如果我們的server和client之間使用HTTP/2協(xié)議,那么這個隧道就會包裝一個server和client之間的TCP連接。?

          這些隧道的優(yōu)點是,它們只需要創(chuàng)建一次。一旦隧道創(chuàng)建了,你就可以在你應(yīng)用程序的生命周期之內(nèi)持續(xù)的使該隧道來回發(fā)送消息。?

          ?

          隧道建立好之后,就該創(chuàng)建client了。client也是可以復(fù)用的,不必沒有個rpc調(diào)用都重建client。但是在調(diào)用之前,我們需要把client建立好。?


          現(xiàn)在client進(jìn)入隧道,這個client通常是提供給我們的,我們不需要自己實現(xiàn)任何代碼。使用Proto-c編譯消息定義生成的代碼將會給我們提供client需要的一切。我們只需要提供隧道即可。
          ?

          ?


          client創(chuàng)建好之后,client就準(zhǔn)備好給server發(fā)送請求了。這一步是必須的,gRPC無法讓server端初始化請求發(fā)送給client端,請求都是client端初始化的。
          ?


          但是client初始化請求之后,server端是可以發(fā)送多個響應(yīng)回來的,這個以后再說。這時,client可以隨著請求發(fā)送一些metadata(元數(shù)據(jù)),這些metadata是關(guān)于請求的,但不是請求對象本身。
          ?

          ?


          請求被發(fā)送以后呢,server可以(但不是必須)把metadata返回。所以,你實際上可以在client和server之間進(jìn)行這種“預(yù)約對話”。client可以發(fā)送一些metadata,然后server可以把一些metadata發(fā)送回來,這些都是發(fā)生在server開始處理請求之前。
          ?

          ?

          生命周期的最后一部分就是發(fā)送和接收消息。就以簡單的情況為例,現(xiàn)在server就應(yīng)該把響應(yīng)發(fā)送回去了,因為client已經(jīng)發(fā)送了請求,所以響應(yīng)就是要返回。?

          ?

          注意,關(guān)于metadata需要注意的是,gRPC內(nèi)置的身份認(rèn)證系統(tǒng)是用來做client和server的身份認(rèn)證的。?

          但是這個metadata也為你提供了檢查實際用戶身份的機(jī)制。所以,如果你需要認(rèn)證或者授權(quán)實際用戶,就需要在RPC請求這個級別來實現(xiàn)。也就是在這里。?

          如果是client和server的身份認(rèn)證,以后再寫。。?

          ?

          身份認(rèn)證
          這里指的不是用戶的身份認(rèn)證,而是指多個server和client之間,它們?nèi)绾巫R別出來誰是誰,并且能安全的進(jìn)行消息傳輸。
          在身份認(rèn)證這方面,gRPC一共有4種身份認(rèn)證的 機(jī)制:
          * 不采取任何措施的連接,也就是不安全的連接。
          * TLS/SSL 連接。
          * 基于 Google Token 的身份認(rèn)證。
          * 自定義的身份認(rèn)證提供商。? ?
          針對第一種不安全的連接,client和server默認(rèn)將會采用HTTP/1,沒有其他特殊的安全措施,也就是使用明文在網(wǎng)絡(luò)上傳輸。所以盡量別用不安全連接,容易被截獲。
          但是不安全連接卻不需要其他任何特殊的處理,不需要CA證書等等,所以適合于快速建立gRPC的情況,后期再添加其他安全措施也行。 ?
          如果采用了TLS/SSL,那么想截獲傳輸?shù)南⒕捅容^困難了,而且默認(rèn)也是使用HTTP/2。HTTP/2的很多實現(xiàn)根本就不支持不安全連接,所以gRPC也不會嘗試使用這些不安全連接,但是如果gRPC發(fā)現(xiàn)它是在一個安全的連接上面,它就會嘗試把這些連接升級到HTTP/2,這時你的消息的傳輸速度就會變得更快,因為HTTP/2協(xié)議的效率更高。
          但是需要注意的是,client會對這些證書進(jìn)行驗證,所以不能因為這是一個安全連接,那么就啥也不用干。
          client會去檢查證書的授權(quán)來確保證書的真實性。所以如果你使用的是生成的證書,那么你還需要在client端做一些額外的工作來確保client能夠識別出這些server證書的合理性。
          ? 當(dāng)使用基于 Google Token
          的身份認(rèn)證方式時,需要注意的是它需要安全的連接,所以你可以把這種認(rèn)證方式想象為在SSL/TLS上面的一層。所以你需要有安全連接,在此之上,你才能使用基于Google
          Token的認(rèn)證方式。? ? 最后一個是自定義身份認(rèn)證,你可能想要的是OAuth 2.0這種認(rèn)證協(xié)議,但是gRPC并沒有自帶OAuth
          2.0協(xié)議,但是還是有很多用于不同語言的插件可以支持OAuth 2.0的。所以如果有需要的話,可以去官網(wǎng)查一下。
          你也可以自己實現(xiàn)一個身份認(rèn)證協(xié)議,但是自己實現(xiàn)的肯定是和語言有關(guān)的,而且gRPC也會盡量配合這種語言。所以不是讓你的認(rèn)證協(xié)議像gRPC這樣工作,而是讓你盡量用該語言慣用的方式。所以使用C#開發(fā)一個身份認(rèn)證提供商和使用Go語言可能會不太一樣。這塊的詳細(xì)信息需要去官網(wǎng)查閱。
          ?
          消息傳輸類型
          gRPC的消息傳輸類型有4種。
          * 第一種是一元的消息,就是簡單的請求--響應(yīng)。
          * 第二種是server streaming(流),server會把數(shù)據(jù)streaming回給client。
          * 第三種是client streaming,也就是client會把數(shù)據(jù)streaming給server。
          * 最后是雙向streaming。 ?
          ?一元消息

          這里有一個server,一個client。gRPC從client發(fā)送請求到server開始,然后server做一些處理,生成一個響應(yīng)并返回。所以在這次遠(yuǎn)程調(diào)用里,有一個請求,一個響應(yīng)。
          這個Protocol Buffer的消息格式大約是這樣: rpc 方法名(請求類型) returns(響應(yīng)類型)?
          在這里,即使請求的時候不需要帶有數(shù)據(jù)(參數(shù)),你仍然需要傳遞一個空的請求類型的對象。所以在gRPC里就必須有請求類型和響應(yīng)類型,因為gRPC不知道你帶沒帶數(shù)據(jù),而且未來你有可能需要帶上
          數(shù)據(jù)。 ?
          Server Streaming
          Server
          Streaming的請求和響應(yīng)管道還是一樣的,但不同的是,雖然一切也是始于client到server的一個請求,然后server處理完之后或者當(dāng)server正在生成響應(yīng)的時候,server會一次發(fā)送一部分結(jié)果回來,也就是把響應(yīng)sreaming回來。
          一個常見的用例就是流式視頻。你發(fā)送一個請求,想要看某種類型的動作片,然后server會把視頻數(shù)據(jù)的一部分緩沖流發(fā)送回來,這樣client就不需要等到整個視頻一次性返回再看,一次返回一塊即可。
          當(dāng)使用這種遠(yuǎn)程調(diào)用的時候,我們只需要在響應(yīng)類型前面加一個關(guān)鍵字stream即可: rpc 方法名(請求類型) returns(stream?響應(yīng)類型)?
          這樣的話,server就相當(dāng)于會返回一個數(shù)組的響應(yīng),但是一次只返回一個。 ?
          Client Streaming
          與Server streaming對應(yīng)的就是Client streaming。
          常見的用例就是上傳文件,你可能需要緩沖,這樣的話就會把請求分為多塊來執(zhí)行,一次包含一部分?jǐn)?shù)據(jù)。需要注意的時候,在發(fā)送期間,server會一直等待,直到整個請求都被接收到。在接收到整個請求之前,server不會做任何處理動作。最后當(dāng)server接收到所有數(shù)據(jù)并處理完之后,server會發(fā)送一個響應(yīng)返回給client。
          不難猜,client streaming的格式是這樣的: rpc 方法名(stream?請求類型) returns(響應(yīng)類型)?
          這個遠(yuǎn)程調(diào)用就相當(dāng)于,一個請求數(shù)據(jù)的數(shù)組,一次發(fā)送一個元素,最后所有請求處理完成后返回單個響應(yīng)。 ?
          雙向Streaming

          最后一種就是雙向streaming。在這種方式下,client會發(fā)送一個初始的請求,也許接下來還會發(fā)送幾個請求,與此同時server就開始把響應(yīng)發(fā)送回來了,這時client可以繼續(xù)發(fā)送額外的請求。所以整個過程非常的異步,而且沒有什么預(yù)定義的結(jié)構(gòu)來規(guī)定請求和響應(yīng)如何構(gòu)造。所以你也可以想到,在你的server和client之間,肯定是需要異步處理的。
          雙向streaming的格式如下: rpc 方法名(stream?請求類型) returns((stream?響應(yīng)類型)?
          這也就意味著一個數(shù)組的數(shù)據(jù)將會被發(fā)送,一個數(shù)組的數(shù)據(jù)也將會被響應(yīng),但都是一次只發(fā)送一個數(shù)據(jù)。

          友情鏈接
          ioDraw流程圖
          API參考文檔
          OK工具箱
          云服務(wù)器優(yōu)惠
          阿里云優(yōu)惠券
          騰訊云優(yōu)惠券
          京東云優(yōu)惠券
          站點信息
          問題反饋
          郵箱:[email protected]
          QQ群:637538335
          關(guān)注微信

                日韩欧美激情一区二区 | 免费夜色污私人影院在线观看 | 日本十八禁网站 | 男人插女人下面 | 天堂中文在线视频 |