微服務 - 服務之間的通信gRPC

来源:https://www.cnblogs.com/xiongheng/archive/2020/07/06/13214637.html
-Advertisement-
Play Games

微服務之間的通信之gRPC 介紹 gRPC是一種與語言無關的高性能遠程過程調用 (RPC) 框架,gRPC是Google發佈的基於HTTP 2.0傳輸層協議承載的高性能開源軟體框架,提供了支持多種編程語言的、對網路設備進行配置和納管的方法。由於是開源框架,通信的雙方可以進行二次開發,所以客戶端和服務 ...


微服務之間的通信之gRPC

介紹

gRPC是一種與語言無關的高性能遠程過程調用 (RPC) 框架,gRPC是Google發佈的基於HTTP 2.0傳輸層協議承載的高性能開源軟體框架,提供了支持多種編程語言的、對網路設備進行配置和納管的方法。由於是開源框架,通信的雙方可以進行二次開發,所以客戶端和伺服器端之間的通信會更加專註於業務層面的內容,減少了對由gRPC框架實現的底層通信的關註。

gRPC 的主要優點是:

  • 現代高性能輕量級 RPC 框架。
  • 協定優先 API 開發,預設使用協議緩衝區,允許與語言無關的實現。
  • 可用於多種語言的工具,以生成強類型伺服器和客戶端。
  • 支持客戶端、伺服器和雙向流式處理調用。
  • 使用 Protobuf 二進位序列化減少對網路的使用。

這些優點使 gRPC 適用於:

  • 效率至關重要的輕量級微服務。

  • 需要多種語言用於開發的 Polyglot 系統。

  • 需要處理流式處理請求或響應的點對點實時服務。

以上摘自Microsoft Document

微服務中gRPC的交互過程

 

  1. 交換機在開啟gRPC功能後充當gRPC客戶端的角色,採集伺服器充當gRPC伺服器角色;
  2. 交換機會根據訂閱的事件構建對應數據的格式(GPB/JSON),通過Protocol Buffers進行編寫proto文件,交換機與伺服器建立gRPC通道,通過gRPC協議向伺服器發送請求消息;
  3. 伺服器收到請求消息後,伺服器會通過Protocol Buffers解譯proto文件,還原出最先定義好格式的數據結構,進行業務處理;
  4. 數據梳理完後,伺服器需要使用Protocol Buffers重編譯應答數據,通過gRPC協議向交換機發送應答消息;

交換機收到應答消息後,結束本次的gRPC交互。上圖展示的是gRPC交互過程的具體流程,這也是Telemetry觸發方式其中之一,稱為Dial-out模式。簡單地說,gRPC就是在客戶端和伺服器端開啟gRPC功能後建立連接,將設備上配置的訂閱數據推送給伺服器端。我們可以看到整個過程是需要用到Protocol Buffers將所需要處理數據的結構化數據在proto文件中進行定義。

微服務中gRPC的使用

1、想要使用grpc首先需要先引入gRPC的包

  引入包的方法是:選中服務--->打開管理庫程式包管理器--->選中瀏覽--->輸入  Grpc.AspNetCore  --->選中第一個下載即可

  註釋:兩個服務之間需要通信則這兩個服務都需要引入gRPC的包

2、添加gRPC文件

  在服務端中添加Protos文件夾(存儲所有gRPC文件),在文件夾中添加一個  協議緩衝區文件,文件尾碼為 .proto

  設計 gRPC 的文件語法,有關 gRPC 文件語法的詳細信息,參考一些國內的博客,如《Protobuf語言指南——.proto文件語法詳解》。

  我項目中使用的語法:

 1 syntax = "proto3";
 2 
 3 option csharp_namespace = "BS.GrpcServices.WorkTask";
 4 
 5 package BS.GrpcServices.WorkTask;
 6 
 7 service WorkTaskGrpc{
 8     rpc SubmitWorkTask(SubmitRequest) returns (SubmitResponse);
 9 }  
10 
11 message SubmitRequest{
12     string Id = 1;
13     int32  Survey = 2;
14     string OrderId = 3;
15 }
16 
17 message SubmitResponse{
18     bool Result = 1;
19 }

代碼詳解:

  • BS.GrpcServices.WorkTask:生成的程式集,供外部引用,引入方法:using BS.GrpcServices.WorkTask;

  • WorkTaskGrpc:程式集中的類,也是存儲服務之間通信的方法集,引入程式集後通過繼承當前類,則可以調用類中的方法

  • SubmitWorkTask:類中的方法,也是兩個服務之間通信的方法,通信的主要邏輯均存在當前方法中

  • SubmitRequest:Request預設代表傳入參數,Submit與方法相匹配

  • SubmitResponse:Response預設代表返回值,Submit與方法相匹配

3、項目文件配置

  雙擊客戶端的服務項目,打開項目文件(.csproj尾碼的文件),在文件中輸入以下代碼:

<ItemGroup>
  <Protobuf Include="Protos\WorkTask.proto" GrpcServices="Server" />
</ItemGroup>

  輸入完成之後保存即可;

  雙擊客戶端的服務項目,打開項目文件(.csproj尾碼的文件),在文件中輸入以下代碼:

<ItemGroup>
  <Protobuf Include="..\BS.WorkTask.API\Protos\WorkTask.proto" GrpcServices="Client" Link="Protos\WorkTask.proto" />
</ItemGroup>

  輸入完成之後保存即可;

4、Startup.cs文件

  客戶端打開Startup.cs文件,輸入以下代碼:

AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true); //允許使用不加密的HTTP/2協議
services.AddGrpcClient<WorkTaskGrpc.WorkTaskGrpcClient>(options =>
{
     options.Address = new Uri(Configuration.GetValue<string>("ServiceUrls:WorkTaskAPI"));
});

  代碼註解:上述代碼是打通gRPC通信的最後一個關鍵點,客戶端通過以上方法與gRPC展開通信,才能訪問到服務端的gRPC程式集(BS.GrpcServices.WorkTask)

  特別註意:上述代碼的第一行,備註為允許使用不加密的 HTTP/2協議 是一定不能忽略的,少了此行代碼通信則無法完成,因為gRPC就是通過當前協議來完成通信的

5、方法的實現

  實現方法通過引用gRPC程式集,繼承 WorkTaskGrpc.WorkTaskGrpcBase 類,實現方法如下:

 1 using BS.GrpcServices.WorkTask;
 2 using Grpc.Core;
 3 
 4 namespace BS.WorkTask.API.Services
 5 {
 6     public class WorkTaskService : WorkTaskGrpc.WorkTaskGrpcBase
 7     {
 8         public override async Task<SubmitResponse> SubmitWorkTask(SubmitRequest request, ServerCallContext context)
 9         {
10             。。。。。。
11 
12             if(result.Succeeded)
13                 return new SubmitResponse() { Result = true };
14             else
15                 return new SubmitResponse() { Result = false };
16         }
17     }
18 }

  調用方法通過引用gRPC程式集,創建 WorkTaskGrpc.WorkTaskGrpcClient 對象,通過對象調用類中的方法,調用方法如下:

 1 using BS.GrpcServices.WorkTask;
 2 
 3 namespace BS.ApiAggregator.Controllers
 4 {
 5     [Route("api/worktask")]
 6     [ApiController]
 7     public class WorkTaskController: ControllerBase
 8     {
 9         WorkTaskGrpc.WorkTaskGrpcClient _workTaskClient;
10         public WorkTaskController(WorkTaskGrpc.WorkTaskGrpcClient workTaskClient)
11         {
12             _workTaskClient = workTaskClient;
13         }
14 
15         [HttpPost("submit")]
16         public async Task<IActionResult> SubmitAsync(GrpcServices.WorkTask.SubmitRequest request)
17         {
18             try
19             {
20                 var clientResult = await _workTaskClient.SubmitWorkTaskAsync(request);
21                 if (clientResult.Result)
22                 {
23                     。。。。。。
24                     return Ok(OperateResult.Success);
25                 }
26             }
27             catch (Exception ex)
28             {
29                 。。。。。
30             }
31         }
32     }
33 }  

  提醒事項:

  1. 中間省略的代碼是處理邏輯,與gRPC無關
  2. 調用方法在客戶端內編寫,實現方法在服務服務端被編寫,兩個位置不可混淆
  3. 客戶端代表的是調用方,服務端代表的是被調用方

 總結:

  gRPC的配置相對來說比較複雜,對於一些服務比較少的微服務來說,不建議使用,可以通過傳統的httpclient通信即可,相對於純文本傳輸來說,gRPC傳輸的是二進位數據,使得傳輸數據體積小、負載低,保持更加緊湊和高效,對於傳入的參數較大的情況的話,用gRPC的話則顯得不夠靈活

文章參考自:https://blog.csdn.net/zhaobw831/article/details/101638695

        https://baijiahao.baidu.com/s?id=1633335936037018920&wfr=spider&for=pc


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 我們一般創建的線程都是普通非守護線程,守護線程是為普通線程服務的。這個說法比較抽象。 具體一個很大的區別是: JVM中所有的線程都是守護線程的時候,JVM就可以退出了--JVM不會等待守護線程是否運行結束 如果還有一個或以上的非守護線程則不會退出 非守護線程例子 public static void ...
  • 一直想深入go語言,下定決心今年要狠抓go語言 | 文章名稱 | 文章鏈接 | | | | | Golang網路編程 | https://www.cnblogs.com/ZhuChangwu/p/13198872.html | | | | | | | ...
  • 一、實現Runnable介面 public class RunnableDemo implements Runnable { public void run() { try { Thread.sleep(100); } catch (InterruptedException e) { e.print ...
  • 從今天起,我將製作一個電影推薦項目,在此寫下博客,記錄每天的成果。 其實,從我發佈 C# 爬取貓眼電影數據 這篇博客後, 我就已經開始製作電影推薦項目了,今天寫下這篇博客,也是因為項目進度已經完成50%了,我就想在這一階段停一下,回顧之前學到的知識。 一、主要為手機端 考慮到項目要有實用性,我選擇了 ...
  • using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System. ...
  • 前言 上一篇【.Net Core微服務入門全紀錄(六)——EventBus-事件匯流排】中使用CAP完成了一個簡單的Eventbus,實現了服務之間的解耦和非同步調用,並且做到數據的最終一致性。這一篇將使用IdentityServer4來搭建一個鑒權中心,來完成授權認證相關的功能。 IdentitySe ...
  • private:私有成員,在類的內部才可以訪問。 protected:保護成員,該類內部和繼承類中可以訪問。 public:公共成員,完全公開,沒有訪問限制。 internal:當前程式集內可以訪問。 ...
  • 一、TLS 線程本地存儲(Thread Local Storage),字面意思就是專屬某個線程的存儲空間。變數大體上分為全局變數和局部變數,一個進程中的所有線程共用地址空間,這個地址空間被劃分為幾個固有的區域,比如堆棧區,全局變數區等,全局變數存儲在全局變數區,虛擬地址固定;局部變數存儲在堆棧區,虛... ...
一周排行
    -Advertisement-
    Play Games
  • 1. 說明 /* Performs operations on System.String instances that contain file or directory path information. These operations are performed in a cross-pla ...
  • 視頻地址:【WebApi+Vue3從0到1搭建《許可權管理系統》系列視頻:搭建JWT系統鑒權-嗶哩嗶哩】 https://b23.tv/R6cOcDO qq群:801913255 一、在appsettings.json中設置鑒權屬性 /*jwt鑒權*/ "JwtSetting": { "Issuer" ...
  • 引言 集成測試可在包含應用支持基礎結構(如資料庫、文件系統和網路)的級別上確保應用組件功能正常。 ASP.NET Core 通過將單元測試框架與測試 Web 主機和記憶體中測試伺服器結合使用來支持集成測試。 簡介 集成測試與單元測試相比,能夠在更廣泛的級別上評估應用的組件,確認多個組件一起工作以生成預 ...
  • 在.NET Emit編程中,我們探討了運算操作指令的重要性和應用。這些指令包括各種數學運算、位操作和比較操作,能夠在動態生成的代碼中實現對數據的處理和操作。通過這些指令,開發人員可以靈活地進行算術運算、邏輯運算和比較操作,從而實現各種複雜的演算法和邏輯......本篇之後,將進入第七部分:實戰項目 ...
  • 前言 多表頭表格是一個常見的業務需求,然而WPF中卻沒有預設實現這個功能,得益於WPF強大的控制項模板設計,我們可以通過修改控制項模板的方式自己實現它。 一、需求分析 下圖為一個典型的統計表格,統計1-12月的數據。 此時我們有一個需求,需要將月份按季度劃分,以便能夠直觀地看到季度統計數據,以下為該需求 ...
  • 如何將 ASP.NET Core MVC 項目的視圖分離到另一個項目 在當下這個年代 SPA 已是主流,人們早已忘記了 MVC 以及 Razor 的故事。但是在某些場景下 SSR 還是有意想不到效果。比如某些靜態頁面,比如追求首屏載入速度的時候。最近在項目中回歸傳統效果還是不錯。 有的時候我們希望將 ...
  • System.AggregateException: 發生一個或多個錯誤。 > Microsoft.WebTools.Shared.Exceptions.WebToolsException: 生成失敗。檢查輸出視窗瞭解更多詳細信息。 內部異常堆棧跟蹤的結尾 > (內部異常 #0) Microsoft ...
  • 引言 在上一章節我們實戰了在Asp.Net Core中的項目實戰,這一章節講解一下如何測試Asp.Net Core的中間件。 TestServer 還記得我們在集成測試中提供的TestServer嗎? TestServer 是由 Microsoft.AspNetCore.TestHost 包提供的。 ...
  • 在發現結果為真的WHEN子句時,CASE表達式的真假值判斷會終止,剩餘的WHEN子句會被忽略: CASE WHEN col_1 IN ('a', 'b') THEN '第一' WHEN col_1 IN ('a') THEN '第二' ELSE '其他' END 註意: 統一各分支返回的數據類型. ...
  • 在C#編程世界中,語法的精妙之處往往體現在那些看似微小卻極具影響力的符號與結構之中。其中,“_ =” 這一組合突然出現還真不知道什麼意思。本文將深入剖析“_ =” 的含義、工作原理及其在實際編程中的廣泛應用,揭示其作為C#語法奇兵的重要角色。 一、下劃線 _:神秘的棄元符號 下劃線 _ 在C#中並非 ...