最近在学习.net core的微服务体系架构。微服务之间的通信常常通过gRPC进行同步通信,但是需要注意的是,大多数微服务之间的通信是通过事件总线进行异步通信。在微软介绍.net微服务体系架构的项目eShop中,微服务之间进行同步通信的场景很多,大多数都是HTTP/REST,目前只有自定义聚合器与微服务之间通信是使用的gRPC。整套微服务架构体系,其实除了客户端与网关(BFF)之间,使用HTTP/REST,均可使用gRPC(只要网关支持HTTP/REST与gRPC的转换)

  • BFF转发外部请求

  • 微服务之间

  • 自定义聚合器与微服务

1.gRPC是什么?

A high-performance, open-source universal RPC framework。

gRPC是一个高性能的通信协议,它基于HTTP/2protocol buffers。它是微服务之间进行同步通信的主要选择。与之相对的,就是其他协议,如AMQP的异步通信队列或者发布/订阅模式。

RPC(remote procedure call 远程过程调用)框架实际是提供了一套机制,使得应用程序之间可以进行通信,而且也遵从server/client模型。使用的时候客户端调用server端提供的接口就像是调用本地的函数一样.

与HTTP/JSON相比,gRPC的优势:

  • 高性能:协议缓冲区是一种二进制的高性能序列化机制。根据语言的不同,实现协议缓冲区的速度比JSON序列化快8倍,而消息的大小可能比JSON序列化小60%-80%。

  • 支持数据流,说白了,还是快

  • 约定显示,与语言无关:使用proto文件定义服务端与客户端之间的约定

2.在.net core中使用gRPC

在.NET Core 3.0众多更新中,其中有一个重要的更新就是对gRPC的原生支持。从.NET Core3.0开始,无论是开发工具还是框架中,都与gRPC进行了深度的集成,这让使用gRPC的体验如丝般顺滑。

真的有这么丝滑吗?

2.1 工具

工具集成-丝滑享受,主要体现在msbuild,开发者可以直接使用宇宙第一IDE:Vistual Studio或者.NET Core SDK命令dotnet build,通过.proto文件去生成需要的gRPC服务端和客户端代码。这里有两个必要条件:

安装工具包

Google.Protobuf,Grpc.Tools

Install-Package Google.Protobuf -Version 3.12.2
Install-Package Grpc.Tools -Version 2.29.0

.proto的引用

proto文件必须在.csproj中引用。在中使用标签。

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

其中GrpcServices属性:指明生成的代码是客户端还是服务端,或者Both(这是默认值)。当编译代码时(无论是通过运行Visual StudioBuild还是dotnet build),所有代码都将生成并放在obj文件夹中。这是微软故意这样做的,因为这些代码不应该出现在源代码控制存储库中,他们都是生成的,只要.proto文件在,他们都能随时生成。

2.2 实际使用的技巧-亲测有用

参考晓晨博客

主要目标

  • 让客户端和服务端共用一个Protos文件夹,避免重复

  • 使用MSBuild变量在csproj中添加Protobuf标签,避免繁琐修改csproj

服务端

 <ItemGroup><Protobuf Include="..\Protos\*.proto" GrpcServices="Server" Link="Protos\%(RecursiveDir)%(Filename)%(Extension)" /></ItemGroup>

客户端

  <ItemGroup><Protobuf Include="..\Protos\*.proto" GrpcServices="Client" Link="Protos\%(RecursiveDir)%(Filename)%(Extension)" /></ItemGroup>
  • Include:加通配符的路径,去指定proto文件的路径

3.创建服务端

3.1 安装包

创建gRPC服务端,需要包Grpc.AspNetCore

Install-Package Grpc.AspNetCore -Version 2.29.0

很幸运,VS2019已经为我们准备好服务端的模板。我们可以创建一个gRPC服务端项目。这个模板已经引入了Grpc.AspNetCore包。你可以在模板中搜到的。

3.2 引入proto文件

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

当然这,模板已经为我们生成了。并且生成了GreeterService.cs

3.3 加入gRPC管道

  • gRPC添加到终结点路由中

app.UseEndpoints(endpoints =>{endpoints.MapGrpcService<GreeterService>();endpoints.MapGet("/", async context =>{await context.Response.WriteAsync("Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");});});

ASP.NET Core 中间件和功能共享路由管道,因此可以将应用配置为提供其他请求处理程序。其他请求处理程序与已配置的 gRPC 服务并行工作。

  • 注册服务

 public void ConfigureServices(IServiceCollection services){services.AddGrpc();}

当然这,模板已经为我们生成了,不要模板自己刀耕火种也是可以的。

4.创建客户端

4.1 安装包

创建gRPC客户端,需要包Google.Protobuf,Grpc.Tools,Grpc.Net.Client

Install-Package Google.Protobuf -Version 3.12.2
Install-Package Grpc.Tools -Version 2.29.0
Install-Package Grpc.Net.Client -Version 2.29.0

4.2 引入与服务端相同的proto文件

  <ItemGroup><Protobuf Include="Protos\greet.proto" GrpcServices="Client" /></ItemGroup>

4.3 编码

static async Task Main(string[] args)
{Console.WriteLine("Hello gRPC!");AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);var channel = GrpcChannel.ForAddress("https://localhost:5001");var greeterClient = new Greeter.GreeterClient(channel);//https://docs.microsoft.com/zh-cn/aspnet/core/grpc/troubleshoot?view=aspnetcore-3.0&WT.mc_id=DT-MVP-5003133var reply = await greeterClient.SayHelloAsync(new HelloRequest{Name = "Garfield"});Console.WriteLine("Greeter 服务返回数据: " + reply.Message);Console.ReadKey();//var counterClient = new Count.CounterClient(channel);This switch must be set before creating the GrpcChannel/HttpClient.//AppContext.SetSwitch(//    "System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);The port number(5000) must match the port of the gRPC server.//var channel = GrpcChannel.ForAddress("http://localhost:5000");//var client = new Greet.GreeterClient(channel);
}

5.微服务中使用

如引言所述,gRPC主要用于微服务之间同步通信。

主要运用场景,已经根据业务划分的多个微服务无法满足实际出现的业务场景,需要联合多个微服务进行业务处理。没错,这就是微服务架构体系中的自定义聚合器,实际上聚合器也是一种微服务,负责聚合多个微服务提供较粒度更小的微服务更为强大的自定义微服务。至于使用方式,依然是引入Grpc.Net.Client包,此包本来就是HttpClient基础上实现的,大可以把此当作一个gPRC的HttpClient使用。

6.配置无TLS的gRPC

6.1 服务端配置

gRPC只支持HTTP/2。通常,当客户端连接到服务端时,连接使用HTTP1.1完成,只有当服务器和客户端都支持HTTP/2时才提升为HTTP/2,这就是协议提升,实际上,同类似的, Websocket就是这样通过http操作,走协议提升。这个协议提升使用协议协商执行,通常需要使用ALPN协议实现,这个协议要求必须TLS。

这意味着,在默认情况下,您需要启用一个TLS端点,以便能够使用gRPC。

但是,这里有一个但是,在内部的微服务中,可能是没有启用TLS的,也没必要,因为大家都是自己人,取消TLS,提高效率。在这种情况下,你有两个选择:

  • 打开一个Kestrel,监听HTTP/2

  • 打开两个Kestrel,一个监听HTTP1.1,另一个监听HTTP/2

如果您的服务器除了支持gRPC客户端还必须支持HTTP1.1客户端,则需要第二个选项。下面的代码就是展示了第二种方法(Program.cs):

WebHost.CreateDefaultBuilder(args).ConfigureKestrel(options =>{options.Listen(IPAddress.Any, 5000, listenOptions =>{listenOptions.Protocols = HttpProtocols.Http1AndHttp2;});//Setup a HTTP/2 endpoint without TLS.options.Listen(IPAddress.Any, 5001, listenOptions =>{listenOptions.Protocols = HttpProtocols.Http2;});})
  • 5000:提供http web api

  • 5001:提供gRPC

6.2 在.NET Core客户端调用

但是,这还不够,我们需要告诉gRPC客户端,客户端可以直接连接到HTTP/2端点,而不需要TLS,口头或者文档说明。

在默认情况下.NET Core不允许gRPC客户端连接到非TLS(non-TLS)端点-不安全的gRPC的服务,十有八九都会报异常

Unhandled exception. System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception. ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.

那么怎么办,就需要如下代码:

// This switch must be set before creating the GrpcChannel/HttpClient.
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);// The port number(5000) must match the port of the gRPC server.
var channel = GrpcChannel.ForAddress("http://localhost:5000");
var client = new Greet.GreeterClient(channel);

上述设置只能在客户端开始时设置一次。

7.配置TLS的gRPC

毫无疑问,微服务场景之外的gRPC服务还是需要TLS的。

7.1 方法一:appsetting.json

{"Kestrel": {"Endpoints": {"HttpsInlineCertFile": {"Url": "https://localhost:5001","Protocols": "Http2","Certificate": {"Path": "<path to .pfx file>","Password": "<certificate password>"}}}}
}

7.2 方法二:Program.cs

public static IHostBuilder CreateHostBuilder(string[] args) =>Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder =>{webBuilder.ConfigureKestrel(options =>{options.Listen(IPAddress.Any, 5001, listenOptions =>{listenOptions.Protocols = HttpProtocols.Http2;listenOptions.UseHttps("<path to .pfx file>", "<certificate password>");});});webBuilder.UseStartup<Startup>();});

8.写在末尾

Azure App Service 和IIS目前都还不支持gRPC.  另外Http.Sys也不支持gRPC所依赖的HTTP响应。详情请看github issues

参考链接

https://grpc.io/

https://www.cnblogs.com/shanyou/p/3452938.html

https://blog.csdn.net/yangguosb/article/details/80592777

https://docs.microsoft.com/zh-cn/aspnet/core/grpc/aspnetcore?view=aspnetcore-3.1&tabs=visual-studio

https://docs.microsoft.com/zh-cn/aspnet/core/grpc/troubleshoot?view=aspnetcore-3.1

https://www.cnblogs.com/stulzq/p/11581967.html

【gRPC】 在.Net core中使用gRPC相关推荐

  1. 如何在 ASP.NET Core 中为 gRPC 服务添加全局异常处理 ?

    咨询区 Dmitriy 我在 ASP.NET Core 中使用 GRPC.ASPNETCore 工具包写 gRPC 服务,现在我想实现 gRPC 的异常全局拦截,我的代码如下: app.UseExce ...

  2. 如何在.NET Core中为gRPC服务设计消息文件(Proto)

    如何在.NET Core中为gRPC服务设计消息 使用协议缓冲区规范定义gRPC服务非常容易,但从需求转换为.NET Core,然后管理服务的演变时,需要注意几件事. 创建gRPC服务的核心是.pro ...

  3. 基于 gRPC 和 .NET Core 的服务器流

    原文:https://bit.ly/3lpz8Ll 作者:Chandan Rauniyar 翻译:精致码农-王亮 早在 2019 年,我写过<用 Mapbox 绘制位置数据>一文,详细介绍 ...

  4. ASP.NET Core 3.0 gRPC 双向流

    目录 ASP.NET Core 3.0 使用gRPC ASP.NET Core 3.0 gRPC 双向流 ASP.NET Core 3.0 gRPC 认证授权 一.前言 在前一文 < 二. 什么 ...

  5. assembly 输出ab中所有数_.NET Core中批量注入Grpc服务

    (给DotNet加星标,提升.Net技能) 转自:张子浩cnblogs.com/ZaraNet/p/12167517.html GRPC 是谷歌发布的一个开源.高性能.通用RPC服务,尽管大部分 RP ...

  6. 在C#中使用gRPC及protobuf简介

    简介 gRPC提供了很多的语言开发包,C#也可以很容易使用.结合使用protobuf及其编译器,很容易地生成了gRPC的服务stub和proxy. 在CSharp中使用gRPC和Protobuf,可以 ...

  7. .NET Core 下使用 gRPC

    gRPC 是一种与语言无关的高性能远程过程调用 (RPC) 框架. https://grpc.io/docs/guides/ https://github.com/grpc/grpc-dotnet h ...

  8. ASP.NET Core 3.0 gRPC 身份认证和授权

    一.开头聊骚 本文算是对于 ASP.NET Core 3.0 gRPC 研究性学习的最后一篇了,以后在实际使用中,可能会发一些经验之文.本文主要讲 ASP.NET Core 本身的认证授权和gRPC接 ...

  9. GRPC与.net core

    QQ讨论群:953553560 正文 系列章节 GRPC与.net core GRPC截止时间与元数据 GRPC与netcore Identity GRPC与netcore IdentityServe ...

最新文章

  1. 【通知】2021-2022-1线性代数课程答疑安排
  2. 胶囊网络为何如此热门?与卷积神经网络相比谁能更胜一筹?
  3. java 字符整数_Java整数是否等于字符?
  4. 自己设计java流程审核_关于工作流引擎取回审批的设计方案与实现过程
  5. eclipse运行时不自动保存的解决方法
  6. ActiveMQ(一)简介与架构
  7. python diango_Django 安装
  8. 技术总监谈好的程序员如何写代码
  9. 一个朋友的一天,太酸了!
  10. ltp-ddt eth_iperf_tcp iperf dualtest遇到的问题
  11. mysql主从维护_mysql主从日常管理维护
  12. vijos 1057 盖房子 dp 最大子正方形
  13. Netty(三) 什么是 TCP 拆、粘包?如何解决?
  14. 基于java mail实现简单的QQ邮箱发送邮件
  15. java的setbounds_java Swing组件setBounds()简单用法实例分析
  16. spark记录(7)SparkCore的调优之数据倾斜调优
  17. jdbc mysql emoji 读取_mysql/Java服务端对emoji的支持
  18. 以太网MDIO总线调试笔记
  19. 协调世界时--UTC
  20. 如何写linux软件专利,Linux之父:软件专利和方法专利都挺扯淡

热门文章

  1. ReactNative 触摸事件处理
  2. 校招需要看的书 巩固的知识
  3. linux系统下nginx安装目录和nginx.conf配置文件目录
  4. BZOJ3172: [Tjoi2013]单词
  5. vmware 克隆后Linux没有eth网卡只有lo
  6. Linux下Gcc 的编译过程
  7. php函数的初步使用
  8. Atitit。 《吠陀》 《梨俱吠陀》overview 经读后感  是印度上古时期一些文献的总称...
  9. 【转】shell pipe与输入输出重定向的区别
  10. 数字图像处理技术在TWaver可视化中的应用