微服务之间的通信之gRPC
介绍
gRPC是一种与语言无关的高性能远程过程调用 (RPC) 框架,gRPC是Google发布的基于HTTP 2.0传输层协议承载的高性能开源软件框架,提供了支持多种编程语言的、对网络设备进行配置和纳管的方法。由于是开源框架,通信的双方可以进行二次开发,所以客户端和服务器端之间的通信会更加专注于业务层面的内容,减少了对由gRPC框架实现的底层通信的关注。
gRPC 的主要优点是:
- 现代高性能轻量级 RPC 框架。
- 协定优先 API 开发,默认使用协议缓冲区,允许与语言无关的实现。
- 可用于多种语言的工具,以生成强类型服务器和客户端。
- 支持客户端、服务器和双向流式处理调用。
- 使用 Protobuf 二进制序列化减少对网络的使用。
这些优点使 gRPC 适用于:
-
效率至关重要的轻量级微服务。
-
需要多种语言用于开发的 Polyglot 系统。
-
需要处理流式处理请求或响应的点对点实时服务。
以上摘自Microsoft Document
微服务中gRPC的交互过程
- 交换机在开启gRPC功能后充当gRPC客户端的角色,采集服务器充当gRPC服务器角色;
- 交换机会根据订阅的事件构建对应数据的格式(GPB/JSON),通过Protocol Buffers进行编写proto文件,交换机与服务器建立gRPC通道,通过gRPC协议向服务器发送请求消息;
- 服务器收到请求消息后,服务器会通过Protocol Buffers解译proto文件,还原出最先定义好格式的数据结构,进行业务处理;
- 数据梳理完后,服务器需要使用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 TaskSubmitWorkTask(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 TaskSubmitAsync(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 }
提醒事项:
- 中间省略的代码是处理逻辑,与gRPC无关
- 调用方法在客户端内编写,实现方法在服务服务端被编写,两个位置不可混淆
- 客户端代表的是调用方,服务端代表的是被调用方
总结:
gRPC的配置相对来说比较复杂,对于一些服务比较少的微服务来说,不建议使用,可以通过传统的httpclient通信即可,相对于纯文本传输来说,gRPC传输的是二进制数据,使得传输数据体积小、负载低,保持更加紧凑和高效,对于传入的参数较大的情况的话,用gRPC的话则显得不够灵活
文章参考自:https://blog.csdn.net/zhaobw831/article/details/101638695
https://baijiahao.baidu.com/s?id=1633335936037018920&wfr=spider&for=pc