.NET World——gPRC概览
什么是gRPC
官方的定义:
gRPC is a modern open source high performance RPC framework that can run in any environment. It can efficiently connect services in and across data centers with pluggable support for load balancing, tracing, health checking and authentication. It is also applicable in last mile of distributed computing to connect devices, mobile applications and browsers to backend services.
gRPC是一种现代化开源的高性能RPC框架,能够运行于任意环境之中。它可以高效地在服务和数据中心内部与其间建立连接,并且可支持负载均衡,追踪,健康检测与认证功能。同时它也可用于分布式计算的“最后一公里”,连接设备,移动应用和浏览器到后端服务。
维基的定义:
gRPC (gRPC Remote Procedure Calls) is an open source remote procedure call (RPC) system initially developed at Google. It uses HTTP/2 for transport, Protocol Buffers as the interface description language, and provides features such as authentication, bidirectional streaming and flow control, blocking or nonblocking bindings, and cancellation and timeouts. It generates cross-platform client and server bindings for many languages. Most common usage scenarios include connecting services in microservices style architecture and connect mobile devices, browser clients to backend services.
gRPC(gRPC远程过程调用)是一种开源的远程过程调用系统,最初由谷歌进行开发。它使用HTTP/2作为传输协议。Protocol Buffer被用于接口描述语言,提供了诸如认证,双向流控制,阻塞或非阻塞绑定,取消与超时功能。它为多种语言生成跨平台的客户端与服务端绑定。最通用的使用场景包括在微服务样式架构中连接服务,以及连接移动设备,浏览器客户端到后端服务。
什么是RPC
从上面的解释里不难看出,要对gRPC有更直观的理解,首先需要明白RPC的定义。
继续看下维基上的内容:
In distributed computing, a remote procedure call (RPC) is when a computer program causes a procedure (subroutine) to execute in a different address space (commonly on another computer on a shared network), which is coded as if it were a normal (local) procedure call, without the programmer explicitly coding the details for the remote interaction. That is, the programmer writes essentially the same code whether the subroutine is local to the executing program, or remote. This is a form of client–server interaction (caller is client, executor is server), typically implemented via a request–response message-passing system. In the object-oriented programming paradigm, RPC calls are represented by remote method invocation (RMI). The RPC model implies a level of location transparency, namely that calling procedures is largely the same whether it is local or remote, but usually they are not identical, so local calls can be distinguished from remote calls. Remote calls are usually orders of magnitude slower and less reliable than local calls, so distinguishing them is important.
在分布式计算里,当计算机程序要运行一段代码,远程过程调用(RPC)会在不同的内存地址(一般是在网络里的不同计算机)上执行它。其无需程序员显示地对它的远程交互进行具体编码,编写代码的方式就如同一段普通的本地过程调用一般。即是,程序员所需写的代码是相同的,无论其调用的过程是在本地还是远程。这是一种客户端-服务端交互的形式(调用方是客户端,执行方是服务端),典型的实现方式是通过一种请求-响应的传递消息系统。在面向对象程序范式里,RPC调用被表示为远程方式调用(RMI)。RPC模型意味着一定程度的本地透明性,本地或是远程的调用过程大致而言是等同的,但又不是完全一样。远程调用通常比本地调用慢上几个数量级,同时也更加不可靠。
Remoting,Web Service,WCF
如果对RPC的概念还是理解不了的话,却曾使用过或者了解过诸如Remoting,Web Service或者WCF等技术的话,那么其实在这方面已经入门了。
Protocol buffers
Protocol buffers是谷歌开发的一套无关开发语言,无关平台的用于序列化结构数据的可扩展机制。它的用途与XML,JSON相同,但比它们更小,更快,更简洁。
作为gRPC中默认的接口定义语言,其既可以用于定义服务接口,也可以定义所必要的数据结构。
service HelloService {
rpc SayHello (HelloRequest) returns (HelloResponse);
}
message HelloRequest {
string greeting = 1;
}
message HelloResponse {
string reply = 1;
}
Protocol buffers的代码需要保存在扩展名为.proto
的文件之中。
服务类型
gRPC支持四种服务类型:
- 一元式RPC
- 服务端流式RPC
- 客户端流式RPC
- 双向流式RPC
一元式RPC,如同普通的方法调用一般,客户端的单一请求,至服务端后,返回唯一的响应。
rpc SayHello(HelloRequest) returns (HelloResponse){
}
服务端流式RPC,客户端发送一请求至服务端后,服务端返回一串消息数据流,客户端持续读取直到没有更多的消息。gRPC会确保消息的传输顺序。
rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse){
}
客户端流式RPC,客户端对一数据流写入一串信息后发送到服务端,并等待服务端返回响应。gRPC会确保消息的传输顺序。
rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse) {
}
双向流式RPC,客户端与服务端使用两个数据流,其间互无影响,可以同时进行数据传递。
rpc BidiHello(stream HelloRequest) returns (stream HelloResponse){
}
gRPC API
光有proto文件,并不能直接使用,还需gRPC中所提供的API将这些文件编译成不同程序语言的服务端与客户端代码。
在服务端,实现服务所定义的方法,并运行gRPC服务程序以处理客户端调用。gRPC架构负责解码传入的请求,执行服务的方法,最后对服务的响应进行编码。
在客户端,会有一个名为存根(stub)的本地对象,实现与服务端相同的方法。这样只需调用这个本地对象的方法,传入合适的protocol buffers消息类型的参数,gRPC负责将请求发送至服务端,再返回相应的结果。
如果使用过诸如WCF这样的PRC技术,对这一过程应该是十分熟悉了。
感到陌生的大概是gRPC中将proto文件编译成代码的插件工具,例如Grpc.Tools
。
所以还是举个具体的例子以便理解。
.NET中的gPRC
首先建立两个Console工程。
dotnet new console -o gRPCServer
dotnet new console -o gRPCClient
接着,在此两个工程同级目录下新建一个名为protos的文件夹。
如此,目录下的文件夹应该有如下几个:
- gRPCServer
- gRPCClient
- protos
protos文件夹下新加一个greet.proto文件。
syntax = "proto3";
option csharp_namespace = "GrpcGreeter";
package Greet;
// 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;
}
然后,进入gRPCServer文件夹,添加相关的类库包。
dotnet add package Grpc
dotnet add package Grpc.Tools
dotnet add package Google.Protobuf
并在csproj文件中加入下列配置:
<ItemGroup>
<Protobuf Include="../protos/*.proto" OutputDir="protos" CompileOutputs="false" GrpcServices="Service" />
</ItemGroup>
运行dotnet build
,可以看到在gRPCServer工程下新生成一个protos文件夹,以及Greet.cs与GreetGrpc.cs文件。
在Program类中加入Greeter的实现类和相关接口方法,并创建服务端启动程序。
class Program
{
const int Port = 51234;
static void Main(string[] args)
{
var server = new Server
{
Services = { Greeter.BindService(new GreeterImpl()) },
Ports = { new ServerPort("localhost", Port, ServerCredentials.Insecure) }
};
server.Start();
Console.WriteLine("Greeter server listening on port " + Port);
Console.WriteLine("Press any key to stop the server...");
Console.ReadKey();
server.ShutdownAsync().Wait();
}
}
class GreeterImpl : Greeter.GreeterBase
{
// Server side handler of the SayHello RPC
public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
{
return Task.FromResult(new HelloReply { Message = "Hello " + request.Name });
}
}
通过dotnet run
命令启动此服务端。
之后再进入gRPCClient文件夹,加入同样的类库包。
在csproj文件中加入类似的配置,注意GrpcServices属性改为了Client:
<ItemGroup>
<Protobuf Include="../protos/*.proto" OutputDir="protos" CompileOutputs="false" GrpcServices="Client" />
</ItemGroup>
运行dotnet build
,同样生成protos文件夹及两个proto文件。
Program类中加入客户端调用代码。
static void Main(string[] args)
{
var channel = new Channel("127.0.0.1:51234", ChannelCredentials.Insecure);
var client = new Greeter.GreeterClient(channel);
var reply = client.SayHello(new HelloRequest { Name = "Ken" });
Console.WriteLine(reply.Message);
channel.ShutdownAsync().Wait();
Console.ReadKey();
}
运行客户端后,应该就可以看到调用服务端方法后返回的结果。
.NET Core 3.0
在最新的.NET Core 3.0中,加入了对gRPC更多的支持。当创建一个Web项目时,选择ASP.NET Core 3.0,可以发现新增了gRPC Service项目模板。
从建立的项目代码中可以看出其不再是普通的Web应用,而是完全变成了gRPC的服务端。
public void ConfigureServices(IServiceCollection services)
{
services.AddGrpc();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
// 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
endpoints.MapGrpcService<GreeterService>();
});
}
.NET World——gPRC概览的更多相关文章
- Activity之概览屏幕(Overview Screen)
概览屏幕 概览屏幕(也称为最新动态屏幕.最近任务列表或最近使用的应用)是一个系统级别 UI,其中列出了最近访问过的 Activity 和任务. 用户可以浏览该列表并选择要恢复的任务,也可以通过滑动清除 ...
- Atitit 软件工程概览attilax总结
Atitit 软件工程概览attilax总结 1.1. .2 软件工程的发展 进一步地,结合人类发展史和计算机世界演化史来考察软件工程的发展史. 表2 软件工程过程模型 表2将软件工程的主要过程模型做 ...
- iOS开发系列—Objective-C之基础概览
概览 前面我们已经用了几章内容进行C语言介绍,当然要通过几篇文章完整的介绍C语言的知识是不太现实的,例如C语言的文件操作.内存申请等我们都没有重点介绍,当然核心知识点基本都已经提到了,后面有时间我们会 ...
- iOS开发系列--IOS程序开发概览
概览 终于到了真正接触IOS应用程序的时刻了,之前我们花了很多时间去讨论C语言.ObjC等知识,对于很多朋友而言开发IOS第一天就想直接看到成果,看到可以运行的IOS程序.但是这里我想强调一下,前面的 ...
- Azure SQL Database (19) Stretch Database 概览
<Windows Azure Platform 系列文章目录> Azure SQL Database (19) Stretch Database 概览 Azure SQL Da ...
- Web前端开发大系概览 (前端开发技术栈)
前言 互联网建立50多年了,网站开发技术日新月异,但web前端始终离不开浏览器,最终还是HTML+JavaScript+CSS这3个核心,围绕这3个核心而开发出来大量技术框架/解决方案. 我从2000 ...
- Atitit.自然语言处理--摘要算法---圣经章节旧约39卷概览bible overview v2 qa1.docx
Atitit.自然语言处理--摘要算法---圣经章节旧约39卷概览bible overview v2 qa1.docx 1. 摘要算法的大概流程2 2. 旧约圣经 (39卷)2 2.1. 与古兰经的对 ...
- 【WPF系列】基础学习-WPF架构概览
引言 WPF从.net framewok3.0加入以来,经历了很多跟新.每次更新都给用户带来了新的功能或者优化性能.下面我们首先看下WPF再.netFramework中的位置,接着介绍下WPF的架构框 ...
- jQuery1.11源码分析(1)-----Sizzle源码概览[原创]
最近在啃jQuery1.11源码,上来就遇到Sizzle这个jQuery的大核心,虽然已经清楚了Sizzle的用途,先绕过去也没事,但明知山有虎偏向虎山行才是我们要做的. 本文面向的阅读对象:正在学习 ...
随机推荐
- Communicating with the UI Thread_翻译
In the previous lesson you learned how to start a task on a thread managed by ThreadPoolExecutor. Th ...
- JAVA面试题 手写ArrayList的实现,在笔试中过关斩将?
面试官Q1:可以手写一个ArrayList的简单实现吗? 我们都知道ArrayList是基于数组实现,如果让你实现JDK源码ArrayList中add().remove().get()方法,你知道如何 ...
- 【攻略】百度货币识别API,搞定防诈骗的应用小程序
1.需求及方案: 近两年用外币进行诈骗的案件很多.例如:2015年12月,一安徽诈骗团伙,用不值1角人民币的50印蒂(intis,秘鲁旧货币,1991年发行新货币后已停止流通,目前无货币价值,仅有&q ...
- LaTeX大全
1.指数和下标可以用^和_后加相应字符来实现.比如: 2.平方根(square root)的输入命令为:\sqrt,n 次方根相应地为: \sqrt[n].方根符号的大小由LATEX自动加以调整.也可 ...
- xpath路径的写法
关于xpath路径的写法 1.选取节点 表达式 描述 nodename 选取此节点的所有子节点. / 从根节点选取. // 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置. . 选取当前节点 ...
- 如何挑选node docker镜像
如何挑选node docker镜像 在使用Jenkins构建前端项目的时候遇到一点问题: node的版本问题. 由于可能编译的项目历史不同,所依赖的node版本也各有千秋,直接把所有项目都升级到最新的 ...
- PHP正则匹配到2个字符串之间的内容,匹配HTML便签内容
PHP正则匹配到2个字符串之间的内容 $preg= '/xue[\s\S]*?om/i'; preg_match_all($preg,"学并思网址xuebingsi.com",$r ...
- 必懂的webpack高级配置
webpack高级配置 1.HTML中img标签的图片资源处理 使用时.只需要在html中正常引用图片即可.webpack就会找到对应的资源进行打包.并修改html中的引用路径 主要是将html中的i ...
- ssm下的CURD
https://github.com/MenghuiLiu/ssm-curd 以后有更新.... 照着前辈的足迹向前撸
- Jquery第一次考核
1. 什么是JS JavaScript 缩写.一种计算机脚本语言 JavaScript是一种动态.弱类型.基于原型的语言,通过浏览器可以直接执行 2. JS三大组成部件 ECMAScript DOM ...