.NET Core微服务开发服务间调用篇-GRPC

在单体应用中,相互调用都是在一个进程内部调用,也就是说调用发生在本机内部,因此也被叫做本地方法调用;在微服务中,服务之间调用就变得比较复杂,需要跨网络调用,他们之间的调用相对于与本地方法调用,可称为远程过程调用,简称RPC(Remote procedure call)。

看过上篇API网关篇,知道案例中包含商品、订单两个微服务,本文将会演示如何采用开源的,高性能rpc框架(grpc),通过订单微服务调用产品微服务内的接口。没有看过上篇文章不影响,我先提供下项目代码结构图,方便你阅读。下面将会一步一步分享如何使用Grpc进行服务之间调用。

步骤1:首先定义服务锲约-proto文件

1.创建类库(.NET Standard),作为服务契约项目,命名为-AAStore.ProductCatalog.DataContracts如图:

2.安装三个nuget包

Google.Protobuf
Grpc
Grpc.Tools

3.开始定义proto文件:product.api.proto

syntax = <span data-raw-text="" "="" data-textnode-index="11" data-index="445" class="character">"proto3<span data-raw-text="" "="" data-textnode-index="11" data-index="452" class="character">";optioncsharp_namespace = <span data-raw-text="" "="" data-textnode-index="15" data-index="480" class="character">"AAStore.ProductCatalog.Api.V1<span data-raw-text="" "="" data-textnode-index="15" data-index="510" class="character">";
packageAAStore;serviceProductApi{rpcGetProduct(GetProductRequest) returns(GetProductResponse);
}//请求消息体
messageGetProductRequest{
int32Id=1;
}
//返回消息体 
messageGetProductResponse{
stringproductName=1;
}

Grpc协议使用Protobuf简称proto文件来定义接口名、调用参数以及返回值类型。比如product.api.proto文件,定义一个接口GetProduct方法,它的请求结构体是GetProductRequest,包含一个int类型的id属性,它的返回结构体GetProductResponse包含一个输出string类型的产品名称属性。

4.添加product.api.proto文件到项目中,双击项目或者右键-》编辑项目文件,添加一下代码

<ItemGroup>
<Protobuf Include=<span data-raw-text="" "="" data-textnode-index="58" data-index="972" class="character">"..\Schema\grpc\v1\product.api.proto<span data-raw-text="" "="" data-textnode-index="58" data-index="1008" class="character">"GrpcServices=<span data-raw-text="" "="" data-textnode-index="60" data-index="1023" class="character">"Both<span data-raw-text="" "="" data-textnode-index="60" data-index="1028" class="character">"Link=<span data-raw-text="" "="" data-textnode-index="62" data-index="1035" class="character">"product.api.proto<span data-raw-text="" "="" data-textnode-index="62" data-index="1053" class="character">"/>
</ItemGroup>

然后build项目,此时gprc代码已经生成了,在obj文件项目,如图

步骤2:Grpc服务端实现

选择项目AAStore.ProductCatalog(详情见项目代码结构图)安装包Grpc.AspNetCore,同时添加引用项目AAStore.ProductCatalog.DataContracts

<ItemGroup>
<PackageReference Include=<span data-raw-text="" "="" data-textnode-index="74" data-index="1262" class="character">"Grpc.AspNetCore<span data-raw-text="" "="" data-textnode-index="74" data-index="1278" class="character">"Version=<span data-raw-text="" "="" data-textnode-index="76" data-index="1288" class="character">"2.29.0<span data-raw-text="" "="" data-textnode-index="76" data-index="1295" class="character">"/>
</ItemGroup><ItemGroup>
<ProjectReference Include=<span data-raw-text="" "="" data-textnode-index="85" data-index="1356" class="character">"..\AAStore.ProductCatalog.DataContracts\AAStore.ProductCatalog.DataContracts.csproj<span data-raw-text="" "="" data-textnode-index="85" data-index="1440" class="character">"/>
</ItemGroup>

然后定义获取产品方法的逻辑和实现,供产品api站点项目调用

publicTask<GetProductResponse> GetProduct(GetProductRequest request, ServerCallContext context)
{
returnTask.FromResult(newGetProductResponse
{
//todo 具体的逻辑下面代码仅为显示
ProductName = <span data-raw-text="" "="" data-textnode-index="110" data-index="1730" class="character">"测试商品grpc<span data-raw-text="" "="" data-textnode-index="112" data-index="1739" class="character">"
}) ;
}

选择AAStore.ProductCatalog.Api产品api项目添加引用项目AAStore.ProductCatalog

<ItemGroup>
<ProjectReference Include=<span data-raw-text="" "="" data-textnode-index="121" data-index="1871" class="character">"..\AAStore.ProductCatalog\AAStore.ProductCatalog.csproj<span data-raw-text="" "="" data-textnode-index="121" data-index="1927" class="character">"/>
</ItemGroup>

新增ProductServices.cs并继承ProductApiBase类,实现grpc服务

public classProductServices : ProductApi.ProductApiBase
{
public override Task<GetProductResponse> GetProduct(GetProductRequest request, ServerCallContext context)
{
return newGrpcProductServices().GetProduct(request, context);
}
}

由于AAStore.ProductCatalog.Api项目不是通过grpc模板项目创建的,所以在Startup类中手工添加gprc服务和中间件代码:

public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddGrpc();
}app.UseEndpoints(endpoints =>
{
endpoints.MapGrpcService<ProductServices>();
endpoints.MapControllers();
});

最后在Program文件配置站点启动监听8081端口,我们并运行它

webBuilder.ConfigureKestrel(options =>
{
// Setup a HTTP/2 endpoint without TLS.
options.ListenLocalhost(8081, o => o.Protocols =
HttpProtocols.Http2);
});

步骤3:Grpc客户端实现-调用Grpc服务

选择AAStore.Orde项目(具体见项目代码结构图),安装Grpc.AspNetCore包,并且添加项目引用AAStore.ProductCatalog.DataContracts

<ItemGroup>
<ProjectReference Include=<span data-raw-text="" "="" data-textnode-index="171" data-index="3123" class="character">"..\AAStore.ProductCatalog.DataContracts\AAStore.ProductCatalog.DataContracts.csproj<span data-raw-text="" "="" data-textnode-index="171" data-index="3207" class="character">"/>
</ItemGroup><ItemGroup>
<PackageReference Include=<span data-raw-text="" "="" data-textnode-index="180" data-index="3268" class="character">"Grpc.AspNetCore<span data-raw-text="" "="" data-textnode-index="180" data-index="3284" class="character">"Version=<span data-raw-text="" "="" data-textnode-index="182" data-index="3294" class="character">"2.29.0<span data-raw-text="" "="" data-textnode-index="182" data-index="3301" class="character">"/>
</ItemGroup>

新建ProductGateway.cs,封装产品微服务公开grpc服务的调用

publicclassProductGateway
{
privatereadonlyProductApiClient _client;
publicProductGateway()
{
AppContext.SetSwitch(<span data-raw-text="" "="" data-textnode-index="206" data-index="3514" class="character">"System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport<span data-raw-text="" "="" data-textnode-index="206" data-index="3573" class="character">", true);
_client = newProductApiClient(GrpcChannel.ForAddress(<span data-raw-text="" "="" data-textnode-index="213" data-index="3648" class="character">"http://localhost:8081<span data-raw-text="" "="" data-textnode-index="213" data-index="3670" class="character">"));//TODO 根据动态配置
}publicasyncTask<GetProductResponse> GetProduct(GetProductRequest request)
{
returnawait_client.GetProductAsync(request);
}
}

新建OrderService.cs,添加GetOrder方法,在其方法内调用产品微服务GetProduct方法

publicasyncTask<string> GetOrder()
{
varproductModel = await_productGateway.GetProduct(newGetProductRequest() { Id = 1});
return$<span data-raw-text="" "="" data-textnode-index="256" data-index="4081" class="character">"Order Service=>从产品微服务获取产品信息:{productModel.ProductName}<span data-raw-text="" "="" data-textnode-index="259" data-index="4136" class="character">";
}

然后在订单控制器中调用

[Route(<span data-raw-text="" "="" data-textnode-index="264" data-index="4167" class="character">"api/[controller]<span data-raw-text="" "="" data-textnode-index="264" data-index="4184" class="character">")]
[ApiController]
publicclassOrderController: ControllerBase
{
privatereadonlyRestOrderService _restOrderService;
publicOrderController()
{
_restOrderService = newRestOrderService();
}
[HttpGet(template:<span data-raw-text="" "="" data-textnode-index="294" data-index="4451" class="character">"Get<span data-raw-text="" "="" data-textnode-index="294" data-index="4455" class="character">")]
publicasyncTask<string> GetOrder()
{
returnawait_restOrderService.GetOrder();
}
}

至此,客户端代码已经完成,我们运行来看看

通过网关访问订单服务,查看调用结果

我们发现结果也是一样的,以上演示了如何使用grpc进行服务间的调用,最后使用一张图作结。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/308785.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于.NetCore3.1搭建项目系列 —— 认证授权方案之Swagger加锁

1开始在之前的使用Swagger做Api文档中&#xff0c;我们已经使用Swagger进行开发接口文档&#xff0c;以及更加方便的使用。这一转换&#xff0c;让更多的接口可以以通俗易懂的方式展现给开发人员。而在后续的内容中&#xff0c;为了对api资源的保护&#xff0c;我们引入了认证授…

今晚8点,dotnet课堂全新起航,张善友/陈计节/刘腾飞我们一起来聊聊abp的故事...

直播主题&#xff1a;我们和Abp的故事直播嘉宾&#xff1a;张善友&#xff0c;陈计节&#xff0c;刘腾飞直播话题张善友&#xff1a;我是如何使用Abp的刘腾飞&#xff1a;利用Abp的模块化解决单体和分布式混合架构陈计节&#xff1a;Abp开源项目的DevOps实践Abp VNext 处于被低…

你知道技术委员会吗?嗯,一个既重要却又鸡肋的神秘组织

这是头哥侃码的第209篇原创前几天&#xff0c;在某群里有个有关 “技术委员会” 的话题讨论的挺火。很多时候&#xff0c;这种争论是不可能有结果的&#xff0c;因为每个人都会从自己的立场和三观出发&#xff0c;公说公有理&#xff0c;婆说婆有理&#xff0c;一般除了搞得唾沫…

[SpringBoot2]Lombok

引入依赖 <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency>idea中搜索安装lombok插件 简化JavaBean开发 NoArgsConstructor //无参构造器 //全参构造器 //AllArgsConstructor Data ToStrin…

谷歌提议更改Istio指导委员会

导语谷歌认为&#xff0c;社区成员可以通过提交代码和非代码贡献的任何组合来对Istio项目产生影响。正文近日&#xff0c;谷歌针对Kubernetes环境的开源Istio服务网格项目的管理&#xff0c;提出了改变规则的理由&#xff0c;并提出了围绕贡献者席位和社区席位创建具有相同投票…

[SpringBoot2]yaml

简介 YAML 是 “YAML Ain’t Markup Language”&#xff08;YAML 不是一种标记语言&#xff09;的递归缩写。在开发的这种语言时&#xff0c;YAML 的意思其实是&#xff1a;“Yet Another Markup Language”&#xff08;仍是一种标记语言&#xff09;。 非常适合用来做以数据…

Golden Master Pattern :一种在.NET Core中重构遗留代码的利器

在软件开发领域中工作的任何人都将需要在旧代码中添加功能&#xff0c;这些功能可能是从先前的团队继承而来的&#xff0c;您需要对其进行紧急修复。可以在文献中找到许多遗留代码的定义&#xff0c;我更喜欢的定义是&#xff1a;“通过遗留代码&#xff0c;我们指的是我们害怕…

[SpringBoot2]web场景_静态资源规则与定制化

静态资源目录 只要静态资源放在类路径下&#xff1a; called /static (or /public or /resources or /META-INF/resources 访问 &#xff1a; 当前项目根路径/ 静态资源名 原理&#xff1a; 静态映射/**。 请求进来&#xff0c;先去找Controller看能不能处理。不能处理的所有请…

【Ids4实战】最全的 v4 版本升级指南

&#xff08;恰似一江春水向东流&#xff09;最近听说IdentityServer4从v3升级到v4了&#xff0c;其实很简单&#xff0c;就是nuget包升级一下的事儿&#xff0c;不过没想到涉及到的内容还挺多&#xff0c;要不然也不会直接从3.1直接蹦到4.0&#xff0c;这么大的跨度&#xff0…

你真的清楚DateTime in C#吗?

DateTime&#xff0c;就是一个世界的大融合。日期和时间&#xff0c;在我们开发中非常重要。DateTime在C#中&#xff0c;专门用来表达和处理日期和时间。本文算是多年使用DateTime的一个总结&#xff0c;包括DateTime对象的整体应用&#xff0c;以及如何处理不同的区域、时区、…

【翻译】.NET 5中的性能改进

在.NET Core之前的版本中&#xff0c;其实已经在博客中介绍了在该版本中发现的重大性能改进。 从.NET Core 2.0到.NET Core 2.1到.NET Core 3.0的每一篇文章&#xff0c;发现谈论越来越多的东西。然而有趣的是&#xff0c;每次都想知道下一次是否有足够的意义的改进以保证再发表…

[SpringSecurity]框架概述

概要 Spring 是非常流行和成功的 Java 应用开发框架&#xff0c;Spring Security 正是 Spring 家族中的 成员。Spring Security 基于 Spring 框架&#xff0c;提供了一套 Web 应用安全性的完整解决方 案。 正如你可能知道的关于安全方面的两个主要区域是“认证”和“授权”&a…

[译]使用DOT语言和GraphvizOnline来可视化你的ASP.NETCore3.0终结点01

这是系列文章中的第一篇&#xff1a;使用GraphvizOnline可视化ASP.NETCore3.0终结点。.第1部分-使用DOT语言来可视化你的ASP.NETCore3.0终结点(本文)第2部分-向ASP.NET Core应用程序添加终节点图第3部分-使用ImpromptuInterface创建一个自定义的DfaGraphWriter&#xff0c;以便…

.NET Core CLI 的性能诊断工具介绍

前言开发人员的.NET Core项目上线后&#xff0c;经常会出现各种问题&#xff0c;内存泄漏&#xff0c;CPU 100%&#xff0c;处理时间长等&#xff0c; 这个时候就需要快速并准确的发现问题&#xff0c;并解决问题&#xff0c; 除了项目本身的日志记录外&#xff0c;NET Core 为…

[SpringSecurity]HelloWorld入门案例

入门案例 第一步 创建springboot工程 第二步 引入相关依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springfram…

ASP.NET Core静态文件处理源码探究

前言静态文件&#xff08;如 HTML、CSS、图像和 JavaScript&#xff09;等是Web程序的重要组成部分。传统的ASP.NET项目一般都是部署在IIS上&#xff0c;IIS是一个功能非常强大的服务器平台&#xff0c;可以直接处理接收到的静态文件处理而不需要经过应用程序池处理&#xff0c…

[SpringSecurity]基本原理_过滤器链

SpringSecurity 本质是一个过滤器链&#xff1a; 从启动是可以获取到过滤器链&#xff1a; org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFil ter org.springframework.security.web.context.SecurityContextPersistenceFilter org.s…

通过Windows Visual Studio远程调试WSL2中的.NET Core Linux应用程序

最近两天在Linux中调试.NET Core应用程序&#xff0c;同时我发现在Linux中调试.NET Core应用程序并不容易。一直习惯在Visual Studio中进行编码和调试。现在我想的是可以简单快速的测试.NET Core应用在Linux。所以通过本篇文章我们能了解到如何在Windows中使用Visual Studio进行…

[SpringSecurity]基本原理_过滤器加载过程

过滤器如何进行加载的&#xff1f; 1.使用SpringSecurity配置过滤器 DelegatingFilterProxy 其中上面的getTargetBeanName()得到的名字是FilterChainProxy 找到FilterChainProxy这个类中的doFilter方法 最后两张图片里面的代码表示&#xff1a; 用了一个增强for循环和getFi…