本文翻译自 ASP.NET Blog | gRPC vs HTTP APIs,作者 James,译者 Edison Zhou。
写在开头
现在,ASP.NET Core使开发人员可以构建gRPC服务。gRPC是一个远程过程调用框架,专注于高性能和开发人员的生产力。ASP.NET Core 3.0中集成了gRPC,因此您可以结合使用现有的ASP.NET Core日志系统,配置系统,身份验证模式来构建新的gRPC服务。
这篇文章将gRPC与基于JSON的HTTP API进行了比较,讨论了gRPC的优缺点,以及何时可以使用gRPC构建应用程序。
gRPC的优点
1、增强开发人员的生产力
使用gRPC服务,客户端应用程序可以直接在不同计算机上的服务应用上调用方法,就好像它是本地对象一样。gRPC基于定义服务的思想,指定可以通过传递参数和返回类型的远程调用方法。服务器端,实现此接口并运行gRPC服务来处理客户端调用。客户端,使用强类型的gRPC客户端,该客户端提供与服务器相同的方法。
gRPC能够实现对代码生成的完美支持的目标。gpro开发的核心文件是.proto文件,该文件使用Protobuf接口定义语言(IDL)定义gRPC服务和消息的契约,例如下面这个Greet.proto文件所示:
Greet.proto // The greeting service definition. service Greeter { // Sends a greeting rpc SayHello (HelloRequest) returns (HelloReply); } // The request message containing the user‘s name. message HelloRequest { string name = 1; } // The response message containing the greetings message HelloReply { string message = 1; }
Protobuf IDL是一种语言无关的语法,因此它可以在gRPC服务和不同语言实现的客户端之间共享。gRPC框架使用.proto文件来生成服务基类、消息和完整客户端的代码进行编码。例如,这里使用生成的强类型Greeter客户端来调用服务:
Program.cs var channel = GrpcChannel.ForAddress("https://localhost:5001") var client = new Greeter.GreeterClient(channel); var reply = await client.SayHelloAsync(new HelloRequest { Name = "World" }); Console.WriteLine("Greeting: " + reply.Message);
通过在服务器和客户端之间共享.proto文件,可以端到端地生成消息和客户端代码。客户端的代码生成消除了客户端和服务器上重复的消息定义,并为您创建了一个强类型的客户端。无需编写客户端,可在拥有许多服务的应用程序中为开发者节省大量开发时间。
2、高性能
gRPC消息使用Protobuf(一种有效的二进制消息格式)进行序列化。Protobuf在服务器和客户端上可以实现非常快速地序列化。Protobuf序列化产生的消息负载也较小,这在有限带宽的移动应用程序等情况下很重要。
gRPC需要HTTP/2,这是HTTP的主要版本,与HTTP 1.x相比,它具有显着的性能优势:
- 二进制成帧和压缩。HTTP/2协议在发送和接收方面都是紧凑高效的。
- 在单个TCP连接上多个HTTP/2调用的复用。复用消除了应用程序层的队头阻塞。
3、实时服务
HTTP/2为长期的实时通信流提供了基础,gRPC为通过HTTP/2的流传输提供很好的支持。
gRPC服务支持所有流组合:
- 一元(无串流)
- 服务器到客户端流
- 客户端到服务器流
- 双向流
请注意,将消息广播到多个连接的概念本身并不天然存在于gRPC中。例如,在一个聊天室中,应将新的聊天消息发送到该聊天室中的所有客户端,要求每个gRPC调用将新的聊天消息分别流式传输到客户端。SignalR是此方案的一个适用框架,SignalR具有持久连接的概念,并内置了对广播消息的支持。
4、超时措施 与 取消机制
gRPC允许客户端指定他们愿意等待一个RPC完成的最长时间。该期限被发送到服务器,服务器可以决定它是否超出了限期采取什么行动。例如,服务器可能会在超时后取消正在进行的gRPC/HTTP/数据库请求。
通过子gRPC调用传播最长时限和取消机制,有助于强制执行资源限制行为。
gRPC的缺点
有限的浏览器支持
gRPC具有出色的跨平台支持!如今,gRPC已经有了多种编程语言的实现。但是,您仍然无法直接从浏览器中调用gRPC服务。gRPC大量使用了HTTP/2的功能,但却没有浏览器提供支持gRPC客户端的Web请求所需的控制级别。例如,浏览器不允许调用者要求使用HTTP/2,或提供对HTTP/2协议之下的帧的访问。
gRPC-Web是gRPC团队的另一项技术,可在浏览器中提供有限的gRPC支持。gRPC-Web由两部分组成:一个支持所有现代浏览器的JavaScript客户端,以及服务器上的一个gRPC-Web代理。gRPC-Web客户端调用代理,代理将gRPC请求转发到gRPC服务器。
gRPC-Web并非支持所有gRPC的功能。例如,它不支持客户端和双向流,并且对服务器流的支持也很有限。
不可读
使用JSON的HTTP API请求以文本形式发送,并且适合利于阅读和创建。
默认情况下,gRPC消息使用Protobuf编码。尽管Protobuf可以高效发送和接收,但其二进制格式不是很可读的。Protobuf要求在.proto文件中指定的消息接口描述才能正确地反序列化。此外,还需要额外的工具来分析网络上的Protobuf有效负载并手动编写请求。
好在,已经有了一些诸如服务器反射和gRPC命令行工具之类的功能来辅助二进制Protobuf消息。另外,Protobuf消息也支持与JSON之间的转换。内置的JSON转换提供了一种在调试时将Protobuf消息与可读的JSON形式之间相互转换的有效方法。
gRPC建议方案
gRPC非常适合以下情况:
- 微服务 – gRPC专为低延迟和高吞吐量通信而设计。gRPC对于效率至关重要的轻量级微服务非常有用。
- 点对点实时通信 – gRPC对双向流具有出色的支持。gRPC服务可以实时推送消息而无需轮询。
- 多种语言环境 – gRPC工具支持所有流行的开发语言,因此gRPC是多语言环境的理想选择。
- 网络受限的环境 – gRPC消息使用一种轻量级消息格式Protobuf进行序列化。gRPC消息的大小始终小于同等级别的JSON消息。
结论
gRPC是ASP.NET Core开发人员的一个强大的新工具。尽管gRPC不能完全替代HTTP API,但在某些情况下可以提供更高的生产率和性能优势。
ASP.NET Core上的gRPC现在已经可用了!如果您想了解有关gRPC的更多信息,请查看以下资源:
- 阅读gRPC for .NET Core文档。
- 试用gRPC入门教程。
- 观看gRPC for ASP.NET Core,这是一个高性能API的新框架,在NDC Sydney上介绍了gRPC的简介。
此外,这里译者也推荐一下俺们大成都的晓晨Master的最新博文系列:ASP.NET Core gRPC入门全家桶 。