.netcore - gRPC vs WebApi 耗时比较

测试环境

gRPC & WebApi 服务运行环境

项目
CPU 1
内存 2GB
操作系统 ubuntu 虚拟机
软件 docker
运行时 .NET Core 3.0

测试场景

使用不同gRPC和WebApi实现一个UserService,提供SayHi的接口,接收一个字符串参数,返回对这个字符串的简单拼接后的结果,进行单连接/多连接循环调用、并行调用,记录最小耗时、最大耗时、平均耗时。

我非常认同内存、CPU占用很重要,但水平有限,这里不做测试了,起初设计的是采用微软官方推荐的方式实现gRPC服务,但这种方式实测下来比WebApi还慢,因此增加了采用gRPC官方提供的实现方式进行对比。

gRPC官方提供的实现方式: https://github.com/grpc/grpc/tree/master/src/csharp

.netcore3.0推荐的实现方式是用VS2019创建gRPC项目时直接使用gRPC模版创建,这种情况下实际创建的是一个Web项目,并且自动引用了Grpc.AspNetCore包,这个包里面做了一些封装且引用了Google.Protobuf、Grpc.Tools、Grpc.Core.Api等

最终的测试项目结构如下

  • GrpcService:基于.netcore3.0推荐的gRPC实现方式,实际是一个Web项目
  • GrpcServiceConsoleApp:基于gRPC官方提供的实现方式,是一个控制台应用程序
  • WebApi:基于.netcore3.0的WebApi项目
  • Test:用于测试调用的客户端,是一个控制台应用程序

测试代码在此: https://github.com/RiccoYuan/gRPC.NetCoreTest

测试结果

1000次For循环调用,循环里面每次创建新的连接

项目/耗时(毫秒) 平均耗时 最小耗时 最大耗时
GrpcService 13.113 9 738
GrpcServiceConsoleApp 2.854 1 176
WebApi 6.331 5 56

1000次For循环调用,只在循环外面创建一次连接

项目/耗时(毫秒) 平均耗时 最小耗时 最大耗时
GrpcService 5.649 4 18
GrpcServiceConsoleApp 2.178 1 131
WebApi 1.155 1 7

1000次Parallel并行调用,这里只测试了每次创建新的连接的情况

项目/耗时(毫秒) 平均耗时 最小耗时 最大耗时
GrpcService 13296.676 10875 17642
GrpcServiceConsoleApp 2350.708 471 3652
WebApi 8128.383 943 10645

手动进行了多次测试,结果相对而言都差不多,得出以下结论:

  • 从客户端建立连接到拿到请求响应,在单线程循环调用和多线程并行调用,gRPC的耗时都比WebApi快3倍左右,符合预期。

  • 在客户端只建立单个连接的情况下,WebApi比gRPC更快,这里面的原因我还不知道。

  • 上述的任何场景下,gRPC官方提供的实现方式比.netcore3.0推荐的gRPC实现方式快。

暂且认为,gRPC官方提供的实现方式优于WebApi优于.netcore3.0推荐的gRPC实现方式

为什么.netcore3.0推荐的gRPC实现方式会慢这么多,可能是封装的代码还需要优化吧,相信官方在后面的版本会修复这个问题。

2019/11/06更新

我此前在官方仓库提了个issue,也得到了作者反馈,作者的意思是至少比WebApi快,O(∩_∩)O哈哈~ https://github.com/grpc/grpc-dotnet/issues/628

posted @ 2019-10-24 09:29  RiccoYuan  阅读(2510)  评论(2编辑  收藏  举报