微服务 - 服务之间的通信gRPC

微服务之间的通信之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后缀的文件),在文件中输入以下代码:


  "Protos\WorkTask.proto" GrpcServices="Server" />

  输入完成之后保存即可;

  双击客户端的服务项目,打开项目文件(.csproj后缀的文件),在文件中输入以下代码:


  "..\BS.WorkTask.API\Protos\WorkTask.proto" GrpcServices="Client" Link="Protos\WorkTask.proto" />

  输入完成之后保存即可;

4、Startup.cs文件

  客户端打开Startup.cs文件,输入以下代码:

AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true); //允许使用不加密的HTTP/2协议
services.AddGrpcClient(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 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 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

你可能感兴趣的:(微服务 - 服务之间的通信gRPC)