【.NET6】gRPC服务端和客户端开发案例,以及minimal API服务、gRPC服务和传统webapi服务的访问效率大对决
前言:随着.Net6的发布,Minimal API成了当下受人追捧的角儿。而这之前,程序之间通信效率的王者也许可以算得上是gRPC了。那么以下咱们先通过开发一个gRPC服务的教程,然后顺势而为,再接着比拼一下minimal api服务和gRPC服务在通信上的效率。以下,Enjoy:
1、创建一个gRPC服务项目。开发模板选项如下图所示。
2、新建项目MyFirstGRPCService,用来开发gRPC服务端使用。
3、选择.Net6 LTS版本。
4、初始项目,自动引用了包 Grpc.AspNetCore,用于提供gRPC基础服务。以及Protos文件夹下有proto文件,services文件夹下有与之对应的类文件。
5、proto文件和对应的类文件的内容比对,以及它们之间的关系。
6、新增一个test.proto文件,定义服务名称和方法名称,以及参数和返回值属性。
7、项目文件,可以看到新增的proto文件被自动引入到项目里面。
8、添加完毕需要生成一下。此处更正个错误,proto文件里面,int类型需要指定为int32,否则会出问题。然后在项目目录下cmd,执行dotnet run一下。
9、执行dotnet run 以后。会在根目录的obj文件夹下,产生一个以Grpc结尾的中间类文件,该文件里面提供了服务有关的内容实现。
10、然后新增一个测试服务类,此时就可以引用自动生成的文件里面提供的Grpc类,该类和proto文件里面定义的保持一致。
11、在服务里面重写方法,以及提供参数。注意空参数也需要传一个Empty类型的参数进去。可以自行比对重写的服务与proto文件的一些关联点。
12、新增一个控制台项目TestConsole,当作客户端,用来做交互使用。并且引入所需要的包,包括Google.Protobuf、Grpc.Net.Client和Grpc.Tools。
13、把protos文件,直接复制到客户端项目目录下。Proto文件起到一个中间连接的作用,类似WCF服务的契约代理类。
14、GRPC服务端的program文件里面,对刚才新增的TestService服务进行注册(类似依赖注入的注册)。
15、打开服务端项目文件,拷贝里面的proto的引用地址。
16、客户端对应的proto内容在人品好的情况下,会在拷贝proto文件的时候自动生成。如果人品不好的情况下,就需要从服务端里面拷贝了。拷贝过来以后,需要把Server改为Client,用来指示该服务是面向客户端的。
17、按照服务端一样的方式,在项目目录下cmd,输入dotnet run,显示Hello,World的时候(控制台程序program里面默认有个输出的,没有删除,所以会显示),在obj路径下会生成中间类文件。服务端生成的是面向服务的的,客户端生成的是面向客户端的。
18、新建一个测试类,用来测试GRPC客户端调用的。客户端调用需要指定访问的GRPC地址,地址当前服务端没有指定,咱们可以在服务端的launchSettings.json文件里面获取到。
19、测试服务类需要静态引用我们在proto文件定义的服务,然后在测试方法里面进行远程过程调用。
20、启动GRPC服务端,然后客户端调用测试方法,并启动,获得到了GRPC服务端返回的结果内容,说明我们搭建的简单的gRPC服务端和客户端程序OK。
21、接下来进行一个对比测试。关于使用webapi和gRPC的访问性能测试。先新建一个minimal api项目:TestPerformanceApi。
22、新增一个POST请求方式的api接口Test,用于做测试使用。为了简单些,不带参数并且只返回两个写死的属性,一个name和一个age。(备注:如果不晓得minimal api的,可以查看我的另一篇关于minimal api的文章)。
23、新增一个控制台程序,用于测试访问minimal api服务使用。有关代码和引用的包,如下图所示。此处循环访问500次进行测试,访问方式使用HttpClientFactory。
24、访问gRPC的服务,也加个循环500次调用。
25、既然都写到这里了,那同时也新增一个传统的webapi项目好了,一起验证下。
26、新增一个测试传统webapi的项目TestTraditionalApi,然后新增一个Test2的api控制器,有关代码如图所示。为了保持和minimal api地址一致,减少其他可能性损耗,route路由也直接指定了action。
27、再新增一个控制台项目,用来测试访问传统webapi。代码同测试mini api的控制台程序,只是访问的URL地址不一样。
28、启动gRPC服务、minimal API服务、以及传统webapi服务。为了防止先启动的控制台占据资源优势,以及避免启动项的项目占据资源优势,新增一个无任何功能的项目当作启动项,然后服务全部从 调试-启动新实例 里面进行打开。
29、访问500次gRPC服务结果:
30、访问500次 minimal api服务结果:
31、访问500次传统webapi服务结果。
32、为了防止其他可能性干扰,我把控制台输出其他信息全部屏蔽掉,并且循环次数新增到2000次,并且均测试两次,降低首次访问创建实例期间的延迟。其他代码雷同,均增加至2000次*2,并取消控制台打印。
33、先测试gRPC服务的结果。第一个2000次访问,耗时4399ms,第二次耗时3140ms.
34、然后是minimal api。第一个2000次使用了53347ms,第二个2000次使用了52459ms.
35、访问传统的webapi,第一个2000次使用了92025ms,第二个2000次访问,使用了90627ms.
36、gRPC效率有点偏高,为了防止可能是网络震荡导致的问题,最后再重新测一次。第一个2000次使用了68709ms,第二个2000次使用了65987ms
37、结论:由此可见,在没有任何其他限制情况下,minimal api的访问效率最高,gRPC服务次之,传统webapi最慢。gRPC此处是传入了参数,所以也有可能增加了些许时差,有兴趣的小伙伴可以自行继续测试。
本轮测试使用的开发环境是VS2022企业版,运行环境全部都是.NET 6,本地机器配置(五年多的老古董了),可以参考如下截图:
38、以上就是本文章的全部内容。欢迎大佬们留言、点赞或转发推广~~
【.NET6】gRPC服务端和客户端开发案例,以及minimal API服务、gRPC服务和传统webapi服务的访问效率大对决的更多相关文章
- thrift服务端到客户端开发简单示例
(1)首先我们在服务器端写个helloworld.thrift文件,如下所示: service HelloWorld{ string ping(1: string name), string getp ...
- 【Eureka】服务端和客户端
[Eureka]服务端和客户端 转载:https://www.cnblogs.com/yangchongxing/p/10778357.html Eureka服务端 1.添加依赖 <?xml v ...
- 【.NET+MQTT】.NET6 环境下实现MQTT通信,以及服务端、客户端的双边消息订阅与发布的代码演示
前言: MQTT广泛应用于工业物联网.智能家居.各类智能制造或各类自动化场景等.MQTT是一个基于客户端-服务器的消息发布/订阅传输协议,在很多受限的环境下,比如说机器与机器通信.机器与物联网通信等. ...
- 使用Apache CXF开发WebServices服务端、客户端
在前一篇的博客中,我使用Xfire1.x来开发了WebServies的服务端. 但是如果你访问Apache的官网,可以看到xfire已经被合并了. 最新的框架叫做CXF. Apache CXF = C ...
- WebService-03-使用CXF开发服务端和客户端
写在前面的话 前面两节说了使用Java提供的包开发服务端和客户端,现在使用CXF来开发,CXF提供了两个类发而服务,一个是ServerFactoryBean,另一个是JaxWsServerFactor ...
- app开发中如何利用sessionId来实现服务端与客户端保持回话
app开发中如何利用sessionId来实现服务端与客户端保持回话 这个问题太过于常见,也过于简单,以至于大部分开发者根本没有关注过这个问题,我根据和我沟通的开发者中,总结出来常用的方法有以下几种: ...
- WCF开发的流程-服务端和客户端之间的通讯(内含demo讲解)
讲解技术之前,恳请博友让我说几句废话.今天是我第一在博客园发布属于自己原创的博文(如有雷同,那是绝对不可能的事,嘿嘿).之前一直是拜读各位博友的大作,受益匪浅的我在这对博友们说声谢谢,谢谢你们的共享! ...
- Centos6.9 搭建rsync服务端与客户端 案例:全网备份项目
rsync的企业工作场景说明 1)定时备份 1.1生产场景集群架构服务器备份方案项目 借助cron+rsync把所有客户服务器数据同步到备份服务器 2)实时复制 本地数据传输模式(local-only ...
- python thrift 服务端与客户端使用
一.简介 thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发.它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C++, Java, Python, PHP, Ruby, Erlang, ...
随机推荐
- oracle基础:怎样把查询的null转换为0、打印、定义变量
https://blog.csdn.net/xuxile/article/details/49943665 oracle怎样把查询的null转换为0 1.查询的null转换为0 NVL(Expr1,E ...
- 菜鸡的Java笔记 第二十三 - java 抽象类的概念
abstractClass 抽象类的概念 1.抽象类的基本定义 2.抽象类的使用原则 不会抽象类与接口,java = 没学 ...
- [tc14634]ExtremeSpanningTrees
保序回归论文题 要求某一个边集为原图的最小生成树,这等价于非树边比所在环(指树上)的所有边小,最大生成树类似 将这些大小关系的限制看作一张有向图,即若要求$w_{i}\le w_{j}$则连边$(i, ...
- [atARC078F]Mole and Abandoned Mine
注意到最终图的样子可以看作一条从1到$n$的路径,以及删去这条路径上的边后,路径上的每一个点所对应的一个连通块 考虑dp,令$f_{S,i}$表示当前1到$n$路径上的最后一个点以及之前点(包括$i$ ...
- [51nod1587]半现串
将s所有长度为d/2的子串放进ac自动机中,直接匹配就可以判定半现串了再对其做一个差分,询问一个前缀的半现串个数,在ac自动机上数位dp,f[i][j][0/1]表示走了i步(i位的字符串),走到节点 ...
- [luogu5423]Valleys
先考虑不要求有洞,那么可以将所有权值排序,然后不断插入,那么一个连通块就是一个答案,加上连通块大小即可考虑并查集如何判断是否有洞,可以发现对于任意一个无洞的直角多边形,都有$90度内角-90度外角=4 ...
- Gin 如何动态生成模型 swagger 文档
在做 API 接口开发时, 一般会统一 API 返回格式, 例如 { "code": 200, "data": { //xxxxx //xxxxx }, &qu ...
- Codeforces 708E - Student's Camp(前缀和优化 dp)
Codeforces 题目传送门 & 洛谷题目传送门 神仙 *3100,%%% 首先容易注意到 \(\forall i\in[1,m]\),第 \(i\) 行剩余的砖块一定构成一个区间,设其为 ...
- C/C++ Qt TabWidget 实现多窗体创建
在开发窗体应用时通常会伴随分页,ToolBar组件可以实现顶部工具栏菜单,每一个ToolBar组件关联到一个TabWidget组件的Tab标签内,这样我们就可以实现一个复杂的多窗体分页结构,此类结构也 ...
- Excel-在整个工作簿中查找/替换
13.在整个工作簿中查找/替换 调范围为:工作簿,默认是工作表: