grpc协议

gRPC is a burgeoning piece of technology that allows you to build web services where you can write code in your codebase’s native language; without writing your 50th custom HTTP Client to conform to some Swagger doc that you read on your company’s ill-maintained documentation hub. In this article, I will outline some of the basic concepts of gRPC and Protocol Buffers, some use cases for these technologies and finish with a simple demo of some cross-language gRPC services in action. I will also outline some common concerns at the end to consider. For official documentation, check out grpc.io.

gRPC是一项新兴的技术,它使您可以构建Web服务,从而可以使用代码库的本地语言编写代码。 而无需编写第50个自定义HTTP客户端以符合您在公司维护不良的文档中心上阅读的某些Swagger文档。 在本文中,我将概述gRPC和协议缓冲区的一些基本概念,这些技术的一些用例,并以运行中的一些跨语言gRPC服务的简单演示结尾。 最后,我还将概述一些常见问题,以供考虑。 有关官方文档,请查看grpc.io。

什么是协议缓冲区? (What are Protocol Buffers?)

Protocol buffers are a mechanism for serializing structured data. It is language-independent and uses an Interface Definition Language (IDL) for defining the shape of a given message and the properties within that message. Protobuf message definitions have values, but no methods; they are data-holders. Protobuf messages are defined in .proto files.

协议缓冲区是一种用于序列化结构化数据的机制。 它与语言无关,并且使用接口定义语言(IDL)来定义给定消息的形状和该消息中的属性。 Protobuf消息定义有值,但没有方法; 他们是数据持有者。 Protobuf消息在.proto文件中定义。

Protocol buffers has a compilation tool called protoc that can compile your code in many supported languages. The current list of officially-supported as of the writing of this article includes:

协议缓冲区具有一个称为protoc的编译工具,可以用许多受支持的语言编译您的代码。 截至本文撰写时,当前官方支持的列表包括:

  • C / C++C / C ++
  • Objective C目标C
  • C#C#
  • Dart镖
  • Go走
  • JavaJava
  • Kotlin (JVM)Kotlin(JVM)
  • Javascript (Node)Javascript(节点)
  • PHPPHP
  • PythonPython
  • RubyRuby
  • Javascript (Web)Javascript(网络)

There are other languages that have implementations but are not part of the “official” list yet, such as Swift and Haskell. You can find some of them on the grpc GitHub account.

还有其他具有实现功能但还不属于“官方”列表的语言,例如Swift和Haskell。 您可以在grpc GitHub帐户上找到其中的一些。

Protobufs use default values for all properties, so if you do not define an int, for example, it will default to 0. Strings will default to empty strings, booleans to false, etc.

Protobuf使用所有属性的默认值,因此,例如,如果您未定义int ,则它将默认为0 。 字符串默认为空字符串,布尔默认为false,等等。

You can define a protobuf message in a .proto file like so:

您可以在.proto文件中定义protobuf消息,如下所示:

message MovieItem {   //1 is the index used when serializing; do not reuse if the type of data changes!  string name = 1;  double price = 2;  bool inStock = 3;}

那么,什么是gRPC? (What is gRPC, then?)

gRPC is a group of technologies that allow you to communicate with other applications using Remote procedure calls (RPCs). Remote procedure calls are function calls that you make in your own codebase, but they execute on another machine, then return in your app. This abstracts the network from you, letting you call methods as if they were local code.

gRPC是一组技术,可让您使用远程过程调用(RPC)与其他应用程序进行通信。 远程过程调用是您在自己的代码库中进行的函数调用,但它们在另一台计算机上执行,然后返回您的应用程序。 这样可以从您那里抽象网络,让您像调用本地代码一样调用方法。

Sourced from: https://grpc.io/docs/what-is-grpc/introduction/
来源: https : //grpc.io/docs/what-is-grpc/introduction/

gRPC uses Protocol Buffers to serialize data between clients and servers, and has extra .proto syntax for defining services used in your applications. With the help of a gRPC plugin for protoc (or a plugin as part of your build script for your given platform), you can generate code that will give you the methods needed to call a given service, all with native typing in your language of choice (if applicable)!

gRPC使用协议缓冲区在客户端和服务器之间序列化数据,并具有额外的.proto语法来定义应用程序中使用的服务。 借助用于protoc的gRPC插件(或作为给定平台的构建脚本的一部分的插件),您可以生成代码,这些代码将为您提供调用给定服务所需的方法,所有代码均以本地语言输入选择(如果适用)!

You can define a gRPC service in your .proto file like this (we will dissect this .proto file later to explain how it works):

您可以像下面这样在.proto文件中定义gRPC服务(我们将在稍后剖析.proto文件以解释其工作原理):

syntax = "proto3";package moviecatalog;service MovieCatalog {  rpc SaveNewMovie (MovieItem) returns (AddMovieResponse) {}  rpc FetchExistingMovie (FetchMovieRequest) returns (MovieItem) {}}message MovieItem {    string name = 1;    double price = 2;    bool inStock = 3;}message AddMovieResponse {    bool wasSaved = 1;    int32 itemId = 2;}message FetchMovieRequest {    string name = 1;}

gRPC supports multiple data transfer methods: Request + Response (like your typical REST service), Server-side streaming (out of scope for this article), Client-side streaming (out of scope for this article), Bidirectional streaming (out of scope for this article).

gRPC支持多种数据传输方法:请求+响应(如典型的REST服务),服务器端流传输(本文范围之外),客户端流传输(本文范围之外),双向流传输(范围之外)对于本文)。

Examples of these other transfer methods can be explored in a future post.

这些其他传输方法的示例可以在以后的文章中探讨。

为什么我应该使用gRPC而不是REST(HTTP + JSON)? (Why should I use gRPC instead of REST (HTTP+JSON)?)

When using Protocol Buffers for sending messages over the network, your payloads are serialized in binary, so they are much smaller than XML or JSON on the wire. This can save you bandwidth ($$$) and improve network performance.

当使用协议缓冲区通过网络发送消息时,您的有效负载将以二进制序列化,因此它们比在线上的XML或JSON小得多。 这样可以节省带宽($$$)并提高网络性能。

NOTE: There is a slight overhead for serializing and deserializing binary packets (and a couple of bytes in the headers), so if you have thousands of super tiny messages from multiple clients, you may not save as much in terms of milliseconds compared to REST. However, in most cases, especially long-lasting connections, gRPC will beat out REST most of the time. For benchmarks, check out this article.

注意:序列化和反序列化二进制数据包(标头中有几个字节)会产生一些开销,因此,如果您有成千上万来自多个客户端的超细微消息,那么与REST相比,您节省的时间可能不会太多。 但是,在大多数情况下,尤其是持久的连接,gRPC在大多数情况下会击败REST。 有关基准,请查看本文 。

Since gRPC uses code generators that give you native code for your given language, this saves a lot of time in overhead when writing custom serializers for JSON or XML. Because gRPC gives you method stubs for service calls, this also means you do not have to use other tools (or manual effort) to make sure your calls include the appropriate payload structure, since they are enforced by actual code.

由于gRPC使用代码生成器为您的给定语言提供本机代码,因此在为JSON或XML编写自定义序列化程序时,可以节省大量时间。 因为gRPC为您提供了用于服务调用的方法存根,所以这也意味着您不必使用其他工具(或手动操作)来确保您的调用包含适当的有效负载结构,因为它们是由实际代码强制执行的。

我应该使用gRPC做什么样的事情? (What kind of things should I use gRPC for?)

Anything you use REST for today can be done with gRPC. gRPC also has support for byte streaming, so you can use it for sending things like audio and video data, or geolocation data over time, without polling for data over time with individual requests. Since gRPC uses HTTP/2, it also has support for multiple simultaneous streams multiplexed over the same connection.

今天使用REST的任何事情都可以通过gRPC完成。 gRPC还支持字节流传输,因此您可以使用它来发送诸如音频和视频数据或随时间推移的地理位置数据之类的消息,而无需随时间使用单个请求轮询数据。 由于gRPC使用HTTP / 2,因此它还支持在同一连接上多路复用的多个同时流。

好吧,给我看看代码! (Okay, show me the code!)

The following sample service will be a simple request+response service, similar to your typical REST call. Streaming will not be covered in this article, but may be addressed in a future one.

以下示例服务将是一个简单的请求+响应服务,类似于您的典型REST调用。 串流不会在本文中讨论,但将来可能会解决。

We will build a simple service for saving and fetching movies from a movie store. We will define the structure of a movie, the requests and responses, and the service contract. We will then implement the business logic for the service and create a server to host the service, as well as a few clients to interact with the service to demonstrate the various implementations in different programming languages. Let’s get started!

我们将建立一个简单的服务来保存和从电影商店中提取电影。 我们将定义电影的结构,请求和响应以及服务合同。 然后,我们将为该服务实现业务逻辑,并创建一个服务器来承载该服务,并创建一些客户端以与该服务进行交互,以展示使用不同编程语言的各种实现。 让我们开始吧!

Defining your service contract in .proto files Message payloads and gRPC service stubs are defined in .proto files. There is a decent amount of typing support in protobuf that will convert to the compiled language. You can see a full list of types in the Protocol Buffer language guide.

定义你的服务合同.proto文件信息的有效载荷和GRPC服务存根定义在.proto文件。 protobuf中有很多类型的键入支持,它们会转换为已编译的语言。 您可以在协议缓冲区语言指南中看到类型的完整列表。

Let’s break down what’s going on in the .proto file we showed before:

让我们分解一下我们之前显示的.proto文件中发生的事情:

(movie-service.proto)//Use this to set the proto language version. As of this article, proto3 is the current version and the syntax here will adhere to its rulessyntax = "proto3";//These are additional options you can provide to the proto compiler. We are using them to make our generated Java code a little bit more organized; this is not required.option java_package = "grpc.demo.java.moviecatalog";option java_outer_classname = "MovieCatalogProto";//Define the package/namespace that will be used in the generated codepackage moviecatalog;//Defines our gRPC service nameservice MovieCatalog {  //This has a few things going on, so let's dissect this line:  // `rpc` is a keyword that defines the contract (ie function/method name) of this remote procedure call  // `SaveNewMovie` is the name of the method that will be generated  // `(MovieItem)` is the message type we will pass as an argument to `SaveNewMovie()` in our code  // `returns (AddMovieResponse)` will send a message with the `AddMovieResponse` format back to the caller once it completes successfully  // `{}` is used for additional custom options that are out of scope for this article  rpc SaveNewMovie (MovieItem) returns (AddMovieResponse) {}  rpc FetchExistingMovie (FetchMovieRequest) returns (MovieItem) {}}//Defines a message (similar to a struct or data object) with the given namemessage MovieItem {  //Each property has a type that will be converted the appropriate equivalent in the compiled language  //`string` is the data type. *This must NOT change after it has been used in production or you WILL break clients*  //`name` is the label given to that data type. This can change later if you decide on a better name.  //`= 1;` is the interesting bit. The number here is an index used by the generated code to understand which value to serialize/deserialize between clients and servers. *This must NOT change* If you no longer wish to use this field in the future, you MUST create a new field and leave this one unused in your implementation but you can NOT remove it.  string name = 1;  double price = 2;  bool inStock = 3;}message AddMovieResponse {  bool wasSaved = 1;  int32 itemId = 2;}message FetchMovieRequest {  string name = 1;}

在Java中生成gRPC代码(Gradle) (Generating gRPC code in Java (Gradle))

You could use the protoc compiler via the command line if you wish, but if you need to build your proto files on a regular basis, you will want to generate it as part of your build to ensure you're up to date. Thankfully there are plugins for your build tool of choice to let you automate this process.

如果愿意,可以通过命令行使用protoc编译器,但是如果需要定期构建proto文件,则需要将其作为构建的一部分来生成,以确保最新。 值得庆幸的是,您可以选择用于构建工具的插件来使该过程自动化。

https://github.com/google/protobuf-gradle-plugin

https://github.com/google/protobuf-gradle-plugin

This example shows a Groovy-style Gradle file with the plugins you will need:

此示例显示了一个Groovy风格的Gradle文件,其中包含您需要的插件:

(build.gradle)buildscript {    repositories {        mavenCentral()    }    dependencies {        classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.12'    }}plugins {    // Apply the java plugin to add support for Java    id 'java'    //Required for protobuf    id "com.google.protobuf" version "0.8.12"    // Apply the application plugin to add support for building a CLI application.    id 'application'}//Update these versions as necessary; these are the current versions as of the writing of this article.def grpcVersion = '1.29.0';def protobufVersion = '3.12.2';//Search these repos for dependenciesrepositories {    mavenCentral()}dependencies {    //grpc dependencies    //The annotations api is used by the generated gRPC code    implementation 'javax.annotation:javax.annotation-api:1.3.2'    //This string interpolation ${} lets us reuse the version variables we defined above    implementation "io.grpc:grpc-all:${grpcVersion}"    implementation "com.google.protobuf:protobuf-java-util:${protobufVersion}"    runtimeOnly "io.grpc:grpc-netty-shaded:${grpcVersion}"    //You can use the testing libraries for unit testing your gRPC services (out of scope for this article)    testImplementation "io.grpc:grpc-testing:${grpcVersion}"}application {    // Define the main class for the application.    mainClassName = 'grpc.demo.java.App'}test {    // Use junit platform for unit tests    useJUnitPlatform()}//This holds the configuration for the protocol buffers compilation stepprotobuf {    // Configure the protoc executable    protoc {        // Download the proto compiler from maven central        artifact = 'com.google.protobuf:protoc:3.12.3'    }    //In order to get our gRPC service stubs and client/server code, we need to include the gRPC plugin for protobuf    plugins {        grpc {            artifact = "io.grpc:protoc-gen-grpc-java:${grpcVersion}"        }    }    //This is needed to apply the gRPC plugin to protoc    generateProtoTasks {        all()*.plugins {            grpc {                //This optional override for the output directory can be used to place generated code where you need it, in case you do not want generated code mixed with your hand-written code                outputSubDir = 'java'            }        }    }    //This changes the base directory where your protobuf and gRPC generated Java code will be dropped    generatedFilesBaseDir = "$projectDir/src/"}

用Java实现服务 (Implementing your service in Java)

(MovieCatalogService.java)package grpc.demo.java.moviecatalog.server;import static io.grpc.Status.ALREADY_EXISTS;import static io.grpc.Status.NOT_FOUND;import grpc.demo.java.moviecatalog.MovieCatalogGrpc;import grpc.demo.java.moviecatalog.MovieCatalogProto.AddMovieResponse;import grpc.demo.java.moviecatalog.MovieCatalogProto.FetchMovieRequest;import grpc.demo.java.moviecatalog.MovieCatalogProto.MovieItem;import io.grpc.StatusException;import io.grpc.stub.StreamObserver;import java.util.ArrayList;import java.util.List;//We need to extend the generated gRPC Service Stubs so that we can create true implementations for them herepublic class MovieCatalogService extends MovieCatalogGrpc.MovieCatalogImplBase {  private final List<MovieItem> moviesInCatalog;  public MovieCatalogService() {    //Populate our collection of movies available to query for. To keep things simple, we will just store data in memory.    var schindlersList = MovieItem.newBuilder().setName("Schindler's List").setPrice(12.99d).setInStock(true).build();    var piratesOfSiliconValley = MovieItem.newBuilder().setName("The Pirates of Silicon Valley").setPrice(10.99d)        .setInStock(true).build();    var warGames = MovieItem.newBuilder().setName("War Games").setPrice(22.99d).setInStock(true).build();    var princessBride = MovieItem.newBuilder().setName("The Princess Bride").setPrice(15.99d).setInStock(true).build();    var lionKing = MovieItem.newBuilder().setName("The Lion King").setPrice(24.99d).setInStock(true).build();    var aKnightsTale = MovieItem.newBuilder().setName("A Knight's Tale").setPrice(8.99d).setInStock(true).build();    moviesInCatalog = new ArrayList<>();    moviesInCatalog.add(schindlersList);    moviesInCatalog.add(piratesOfSiliconValley);    moviesInCatalog.add(warGames);    moviesInCatalog.add(princessBride);    moviesInCatalog.add(lionKing);    moviesInCatalog.add(aKnightsTale);  }  //We need to override each of the protobuf `rpc` methods we defined in our `.proto` file  @Override  public void fetchExistingMovie(FetchMovieRequest request, StreamObserver<MovieItem> responseObserver) {    MovieItem fetchedMovie;    try {      //Grab the first movie that has a substring of the requested movie's name      fetchedMovie = moviesInCatalog.stream()          .filter(movie -> movie.getName().contains(request.getName()))          .findFirst()          .orElseThrow(() -> new MovieNotFoundException(request.getName()));    } catch (MovieNotFoundException e) {      e.printStackTrace();      //Throw an exception visible to the client (NOT_FOUND is a constant defined in the generated gRPC error handling code. We use StatusException for reporting gRPC call exceptions back over the wire.)      responseObserver.onError(new StatusException(NOT_FOUND));      return;    }    System.out.println("Found movie: " + fetchedMovie.getName());    //Send response (this needs to be called in order to return the value we fetched back to the client)    responseObserver.onNext(fetchedMovie);    //Close request gracefully    responseObserver.onCompleted();  }  //This follows basically the same flow as the previous method as far as gRPC-related things  @Override  public void saveNewMovie(MovieItem request, StreamObserver<AddMovieResponse> responseObserver) {    boolean movieAlreadyExists = moviesInCatalog.stream()        .anyMatch(movie -> movie.getName().equalsIgnoreCase(request.getName()));    if (movieAlreadyExists) {      System.err.println("Movie " + request.getName() + " already exists!");      responseObserver.onError(new StatusException(ALREADY_EXISTS));    } else {      moviesInCatalog.add(request);      System.out.println("Saved movie: " + request.getName());      //We will treat the id as just the index of the item in our in-memory list      var response = AddMovieResponse.newBuilder()          .setWasSaved(true)          .setItemId(moviesInCatalog.indexOf(request))          .build();      responseObserver.onNext(response);      responseObserver.onCompleted();    }  }}

用Java设置服务器 (Setting up a server in Java)

(MovieServer.java)package grpc.demo.java.moviecatalog.server;import io.grpc.Server;import io.grpc.ServerBuilder;import java.io.IOException;import java.util.concurrent.TimeUnit;public class MovieServer {  public static void main(String[] args) throws IOException, InterruptedException {    var service = new MovieCatalogService(); //Instantiate our service that we defined above    System.out.println("Starting movie server...");    final int port = 9090;    var server = ServerBuilder.forPort(port)    .addService(service) //Here is where we register the service implementation we just completed to our server    .build()    .start(); //Start the server    System.out.println("Server started on port " + port + "!");    server.awaitTermination(); //Wait until the app is killed so that our server doesn't stop immediately.    //This is some magic to make sure we don't keep the server running if the app is terminated externally    Runtime.getRuntime().addShutdownHook(new Thread(() -> {      // Use stderr here since the logger may have been reset by its JVM shutdown hook.      System.err.println("*** shutting down gRPC server since JVM is shutting down");      try {        stopServer(server);      } catch (InterruptedException e) {        e.printStackTrace(System.err);      }      System.err.println("*** server shut down");    }));  }  private static void stopServer(Server server) throws InterruptedException {    if (server != null) {      server.shutdown().awaitTermination(30, TimeUnit.SECONDS);    }  }}

用Java设置客户端 (Setting up a client in Java)

(MovieClient.java)package grpc.demo.java.moviecatalog.client;import grpc.demo.java.moviecatalog.MovieCatalogGrpc;import grpc.demo.java.moviecatalog.MovieCatalogProto.AddMovieResponse;import grpc.demo.java.moviecatalog.MovieCatalogProto.FetchMovieRequest;import grpc.demo.java.moviecatalog.MovieCatalogProto.MovieItem;import io.grpc.ManagedChannelBuilder;public class MovieClient {  public static void main(String[] args) {    //Create our client channel. Since we are running on localhost, and to keep things simple, we will not be implementing security for this demo.    var channel = ManagedChannelBuilder        .forAddress("localhost", 9090)        .usePlaintext() //No encryption        .build();    //Create a blocking (synchronous) client to work with. This allows us to treat method calls like local calls. Alternatively, you could use a FutureStub if you wanted to use multithreading and asynchronous calls to the service.    var client = MovieCatalogGrpc.newBlockingStub(channel);    //Create a movie object based on what we defined in our `proto` file to save it to the server    var theMatrix = MovieItem.newBuilder().setName("The Matrix").setPrice(12.99).setInStock(true).build();    //Make the save call to the server with our movie    AddMovieResponse saveResponse = client.saveNewMovie(theMatrix);    System.out.println("Movie was saved: " + saveResponse.getWasSaved() + " / item id: " + saveResponse.getItemId());    //Try to fetch the movie we just saved to the server by constructing a request object    var fetchRequest = FetchMovieRequest.newBuilder().setName("The Matrix").build();    var fetchResponse = client.fetchExistingMovie(fetchRequest);    System.out.println(String.format(        "Fetch movie %s at price $%f. In stock?: %s",        fetchResponse.getName(),        fetchResponse.getPrice(),        fetchResponse.getInStock()    ));  }}

在.NET Core中生成gRPC代码 (Generating gRPC code in .NET Core)

There are currently (as of the writing of this article) two different main implementations of gRPC for .NET. The one we will be using here is the gRPC for .NET implementation, which you can find here. This example is given using a .NET Core 3.0 C# app.

当前(截至本文撰写),gRPC for .NET有两种不同的主要实现。 我们将在这里使用的是gRPC for .NET实现,您可以在此处找到。 使用.NET Core 3.0 C#应用程序给出了此示例。

We will use NuGet to install the following packages (in this demo we are using version 2.29):

我们将使用NuGet安装以下软件包(在此演示中,我们使用的是2.29版):

  • GrpcGrpc
  • Grpc.AspNetCoreGrpc.AspNetCore
  • Grpc.Net.ClientGrpc.Net.Client
  • Grpc.Net.ClientFactoryGrpc.Net.ClientFactory
  • Grpc.ToolsGrpc。工具
  • Google.Protobuf (in this example, 3.12.3)

    Google.Protobuf(在此示例中为3.12.3 )

(grpc-demo-dotnet.csproj)<Project Sdk="Microsoft.NET.Sdk">    <PropertyGroup>        <OutputType>Exe</OutputType>        <TargetFramework>netcoreapp3.0</TargetFramework>        <RootNamespace>grpc_demo_dotnet</RootNamespace>    </PropertyGroup>    <ItemGroup>      <PackageReference Include="Google.Protobuf" Version="3.12.3" />      <PackageReference Include="Grpc" Version="2.29.0" />      <PackageReference Include="Grpc.AspNetCore" Version="2.29.0" />      <PackageReference Include="Grpc.Net.Client" Version="2.29.0" />      <PackageReference Include="Grpc.Net.ClientFactory" Version="2.29.0" />      <PackageReference Include="Grpc.Tools" Version="2.29.0" PrivateAssets="All" />    </ItemGroup>    <!-- This item group needs to be added manually so that the gRPC plugins can generate the gRPC client code -->    <ItemGroup>        <Protobuf Include="Protobuf/movie-service.proto" GrpcServices="MovieCatalog" />    </ItemGroup></Project>

在.NET Core(C#)中设置客户端 (Setting up a client in .NET Core (C#))

(Client.cs)using System;using Grpc.Core;using Moviecatalog;namespace grpc_demo_dotnet{    internal static class Client    {        private static void Main(string[] args)        {            Console.WriteLine("Starting gRPC client...");            //Create a channel with details about the server we want to connect to            var channel = new Channel("localhost", 9090, ChannelCredentials.Insecure);            //Pass our channel to the client            var client = new MovieCatalog.MovieCatalogClient(channel);            //Create a fetch request for a movie we know exists in the default data            var fetchRequest = new FetchMovieRequest            {                Name = "War Games"            };            //Call the client method like a normal method            var response = client.FetchExistingMovie(fetchRequest);            Console.WriteLine($"Fetched movie from server: {response}");            //Construct a new movie (with strong native C# typing)            var createRequest = new MovieItem            {                Name = "Toy Story",                Price = 29.99d,                InStock = false            };            //Save our movie like you would expect!            var saveResponse = client.SaveNewMovie(createRequest);            Console.WriteLine($"Saved new movie: {saveResponse}");        }    }}

在Node(JS)中生成gRPC代码 (Generating gRPC code in Node (JS))

Node.js has a handy set of syntax that will dynamically generate your gRPC service code for you at runtime:

Node.js具有一组方便的语法,可以在运行时为您动态生成gRPC服务代码:

在Node.js中设置客户端 (Setting up a client in Node.js)

//Boilerplate for generating gRPC codeconst PROTO_PATH = '../protobuf/movie-service.proto';const grpc = require('grpc');const protoLoader = require('@grpc/proto-loader');const packageDefinition = protoLoader.loadSync(    PROTO_PATH,    {        keepCase: true,        longs: String,        enums: String,        defaults: true,        oneofs: true    });const movie_proto = grpc.loadPackageDefinition(packageDefinition).moviecatalog;//Our actual client codefunction main() {    //Start the client    let client = new movie_proto.MovieCatalog('localhost:9090', grpc.credentials.createInsecure());    //Create a movie (any unassigned values in JS will default to the protobuf defaults. Extras can be captured by the server, but are out of scope for this article)    let terminator2 = {        name: 'Terminator 2',        price: 20.95,        inStock: true    };    console.log('Saving movie: ', terminator2);    //Call our save rpc and log a success or failure    client.SaveNewMovie(terminator2, function (err, response) {        if (response) console.log('Response: ', response);        if (err) console.error(err);    });    let fetchRequest = {        name: 'The Lion King'    }    console.log('Fetching movie: ', fetchRequest);    //Call our fetch rpc and log a success or failure    client.FetchExistingMovie(fetchRequest, function (err, response) {        if (response) console.log('Response: ', response);        if (err) console.error(err);    });}//Run our main methodmain();

让我们看看它运行! (Let’s See It Run!)

Java服务器(正在启动) (Java Server (starting up))

Starting movie server...Server started on port 9090!

Java客户端 (Java Client)

Movie was saved: true / item id: 6Fetch movie The Matrix at price $12.990000. In stock?: trueProcess finished with exit code 0

C#客户端 (C# Client)

Starting gRPC client...Fetched movie from server: { "name": "War Games", "price": 22.99, "inStock": true }Saved new movie: { "wasSaved": true, "itemId": 7 }Process finished with exit code 0.

节点客户端 (Node Client)

$ node index.jsSaving movie:  { name: 'Terminator 2', price: 20.95, inStock: true }Fetching movie:  { name: 'The Lion King' }Response:  { name: 'The Lion King', price: 24.99, inStock: true }Response:  { wasSaved: true, itemId: 8 }

Java Server(客户端运行后) (Java Server (after clients have run))

Starting movie server...Server started on port 9090!Saved movie: The MatrixFound movie: The MatrixFound movie: War GamesSaved movie: Toy StoryFound movie: The Lion KingSaved movie: Terminator 2

As you can see, each of these languages are capable of talking to a Java server as if it were regular source code in their native language. This has been a fairly simple example that doesn’t really show off some of the really neat stuff you can do, but hopefully this gives you an idea of the basics so that you can start experimenting yourself.

如您所见,这些语言中的每一种都能够与Java服务器通信,就好像它们是使用其本地语言的常规源代码一样。 这是一个非常简单的示例,并没有真正展示出您可以做的一些真正整洁的事情,但是希望这可以使您对基本概念有所了解,以便您可以开始自己进行实验。

那我选择的语言呢? (What about my language of choice?)

gRPC supports many different languages, so check out the documentation to see if your language is supported, and how to get started. Since every target language converts their payloads to protobuf as part of the service call, any language can interop with any other.

gRPC支持许多不同的语言,因此请查阅文档以查看是否支持您的语言以及如何入门。 由于每种目标语言都会在服务调用中将其有效载荷转换为protobuf,因此任何一种语言都可以与其他语言互操作。

好吧,有什么收获? (Okay, what’s the catch?)

基础设施 (Infrastructure)

gRPC has a bit of an up-front cost in terms of setting up your infrastructure to use it. Your DevOps infrastructure has to support HTTP/2 and there are some tricky things to get load balancing to work properly since gRPC uses long-lived socket connections as opposed to polling. You will also need to implement a health check service and update some configurations in order for Kubernetes, or whatever other platform you’re using, to ensure the service is running properly.

在设置基础架构以使用gRPC方面,gRPC会有一些前期成本。 您的DevOps基础架构必须支持HTTP / 2,并且有一些棘手的事情才能使负载平衡正常工作,因为gRPC使用了长期的套接字连接而不是轮询。 您还需要实现运行状况检查服务并更新一些配置,以使Kubernetes或您使用的任何其他平台都可以确保服务正常运行。

安全 (Security)

gRPC security typically requires a certificate and a private key for all clients if you want an encrypted connection. The setup for this is out of scope for this article, but the documentation can help you a bit.

如果要加密连接,则gRPC安全通常需要所有客户端的证书和私钥。 此设置不在本文讨论范围之内,但是文档可以为您提供一些帮助。

测试中 (Testing)

Since gRPC requires you to have a client library to talk to a server, manually testing requests the way you would with a REST service (via Postman or Insomnia, etc.) can be done with a tool called BloomRPC. Since the data is binary over the wire, it may be difficult to diagnose data issues if you can’t deserialize it, but you can test your protobufs using this tool while developing your server.

由于gRPC要求您具有与服务器进行通信的客户端库,因此可以使用称为BloomRPC的工具(通过Postman或Insomnia等)手动测试请求,以使用REST服务的方式进行。 由于数据是通过网络传输的二进制数据,因此如果无法对数据进行反序列化,可能很难诊断出数据问题,但是可以在开发服务器时使用此工具测试原型缓冲区。

基于浏览器的RPC (Browser-based RPCs)

Working with gRPC in the browser is not as straight-forward. You will need to use gRPC Web to communicate with a gRPC service, which uses a client and a server-side proxy to create gRPC request on the server side. Streaming support is also fairly limited with gRPC Web as of now. See this article on the gRPC blog for info.

在浏览器中使用gRPC并不那么简单。 您将需要使用gRPC Web与gRPC服务进行通信,该服务使用客户端和服务器端代理在服务器端创建gRPC请求。 到目前为止,gRPC Web的流支持也相当有限。 有关信息,请参见gRPC博客上的本文 。

结论 (In Conclusion)

Whether gRPC is appropriate for your team could depend on a number of things. If you are a small group of 5 developers working on a website with the same stack, the overhead of setting up gRPC may not be worth it. On the other hand, if you are a large organization that uses a lot of different tech stacks and languages that need to interact with each other, then the benefits of code generation and allowing developers to work in their native language could be worth the initial cost.

gRPC是否适合您的团队可能取决于许多因素。 如果您是由5个开发人员组成的小组,在一个具有相同堆栈的网站上工作,则设置gRPC的开销可能不值得。 另一方面,如果您是一个使用大量不同技术堆栈和需要相互交互的语言的大型组织,那么代码生成和允许开发人员使用其本国语言进行工作的好处可能是值得的初始成本。 。

来源和相关链接 (Sources and Related Links)

  • gRPC Documentation

    gRPC文档

  • Protocol Buffers Documentation

    协议缓冲区文档

  • BloomRPC

    BloomRPC

  • Intro to gRPC: A Modern Toolkit for Microservice Communication

    gRPC简介:微服务通信的现代工具包

  • Why Milliseconds Matter: Comparing REST performance with gRPC

    为何如此重要:将REST性能与gRPC进行比较

  • Using gRPC with JSON instead of Protobuf

    结合使用gRPC和JSON而不是Protobuf

  • State of gRPC Web

    gRPC Web的状态

REDspace is a software development company that builds innovative, custom, and flexible platforms for global enterprises. We combine well-built backends with engaging front-end user experiences. redspace.com.

REDspac e是一家软件开发公司,为全球企业构建创新,定制和灵活的平台。 我们将精心打造的后端与引人入胜的前端用户体验结合在一起。 redspace.com

翻译自: https://medium.com/well-red/intro-to-grpc-and-protocol-buffers-c21054ef579c

grpc协议


http://www.taodudu.cc/news/show-4640751.html

相关文章:

  • NSObject常用方法 和反射
  • 安装和控制DNS服务器
  • Apache和 Nginx的介绍
  • vue-These relative modules were not found
  • vue Error: No PostCSS Config found in
  • INI 文件读取专用类
  • DBA组件---ADO数据库编程利器
  • vuex的一些学习
  • 关于H5的一些杂思细想(一)
  • js数据类型以及数组字符串常用方法
  • 引用图标库到自己页面
  • vue-cli+mock.js+axios模拟前后台数据交互
  • 关于css盒子模型和BFC的理解
  • vue路由传参的三种方式区别(params,query)
  • vue-cli模拟后台数据交互
  • 移动端h5 实现多个音频播放
  • 红米2支持java吗_红米2a会有报错:java.lang.NullPointerException
  • 【Hadoop大数据分析与挖掘实战】(一)----------P19~22
  • Aiqyi 笔试
  • Other——苹果锁屏有个像播放音乐的界面如何去掉
  • Mac电脑待机长时间离开后自动退出登录和关机的解决方法
  • iphone怎么关闭浮屏键_iPhone屏幕上的圆圈怎么设置 打开/关闭方法
  • 安卓callkit_苹果Callkit国内被叫停:无需解锁即可接听网络电话 曾在微信短暂“现身”...
  • 给Ubuntu18.04安装mac os主题
  • iOS 保持APP在后台长时间运行
  • XCode8新的功能
  • 无星的RN学习之旅(六)-第三方App跳转,苹果商店跳转,loading框
  • 工信部叫停苹果 Callkit,微信不能直接接听视频了
  • Linux也可以这样美——Ubuntu18.04安装、配置、美化
  • Ubuntu18.0.4仿Mac界面

grpc协议_gRPC和协议缓冲区简介相关推荐

  1. 【计算机网络】网络层 : BGP 协议 ( BGP 协议简介 | BGP 协议信息交换 | BGP 协议报文格式 | BGP-4 常用报文 | RIP 、OSPF、BGP 协议对比 )

    文章目录 一.路由选择协议分类 二.BGP 协议 简介 三.BGP 协议 信息交换过程 三.BGP 协议 报文格式 四.BGP 协议 特点 五.BGP-4 协议的 四种报文 六.RIP .OSPF.B ...

  2. 【转】SSL协议、SET协议、HTTPS简介

    一.SSL协议简介 SSL是Secure Socket Layer的缩写,中文名为安全套接层协议层.使用该协议后,您提交的所有数据会首先加密后,再提交到网易邮箱,从而可以有效防止黑客盗取您的用户名.密 ...

  3. BACnet协议简要说明及组网简介

    主题 概要 BACnet协议 BACnet协议简要说明,组网简介 编辑 时间 新建 20160217 序号 参考资料 1 BACnet协议正文1995版 2 http://www.bacnet.org ...

  4. 透视HTTP协议-01|HTTP协议简介

    目录 透视HTTP协议-01|HTTP协议简介 透视HTTP协议-02|HTTP协议基础 透视HTTP协议-03|HTTP协议进阶(一) 透视HTTP协议-04|HTTP协议进阶(二) 透视HTTP协 ...

  5. MQTT协议-MQTT协议简介及协议原理

    MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的"轻量级" ...

  6. 机智云相关的控制协议和上报协议简介

    大家好,今天小编给大家介绍一些机智云通信协议相关的基础知识,欢迎一起交流学习. 1.gagent目录 该目录下的文件为机智云设备接入协议库文件,包括mqttlib.o,mqttgat.o等mqtt(M ...

  7. 常用应用层协议及HTTP协议

    文章目录 简介 HTTP HTTP协议特点 HTTP的组成结构 HTTPS HTTP2.0 HTTP 3.0 简介 应用层协议是用于精确定义不同主机件通信的规则,传输层提供端到端的数据逻辑传输,应用层 ...

  8. 计算机原理---什么叫协议?主流协议族TCP/IP协议与HTTP协议的联系及区别

    文章目录 一. 背景 1. 名词定义 2. 协议选择 3. 常用协议 二. 协议协议,究竟什么是协议? 1.举个例子 2.计算机网络一般分为5层 应用层 传输层 网络层 数据链路层 物理层 三.总结 ...

  9. 什么是UPNP协议:UPNP协议作用及启用路由器UPNP支持的方法详细介绍

    目录 [隐藏] UPNP简介 基本概念 官网解释 以下是微软官方网站对UPnP的解释: 以下是BC官方网站对UPnP的解释: UPnP是用来干什么的? 经典应用 网络地址转换 NAT 穿越技术 实际应 ...

最新文章

  1. [Java] Welcome to Artifactory 使用说明
  2. elementui el-dialog 离顶部的位置_驻马店建筑物避雷带的安装位置,本月报价
  3. MFC程序执行过程剖析
  4. fullcalendar自定义搜索框_??这款搜索神器,真希望你早点使用,越早越好!有效提升学习和生活的幸福感!
  5. oracle取时间间隔天,如何掌握 Oracle 中的时间间隔型数据(转)
  6. 东大OJ-5到100000000之间的回文质数
  7. python sqlite3 executemany_python – SQLite executemany的问题
  8. 【快速高斯模糊的实现】
  9. 100个高质量Java开发者博客 【转】
  10. 使用AdapterTypeRender对不同类型的item数据到UI的渲染
  11. hermite插值c语言程序,张艳-埃尔米特Hermite 插值逼近的C语言程序.doc
  12. 二维数组与指针(详解)
  13. Asterisk入门教程
  14. P1688 餐厅点餐
  15. python编写的动物识别专家系统_自己写的简单动物识别专家系统
  16. 双软企业税收优惠政策
  17. 金融学本科跨考计算机,跨考研究生怎么选专业,计算机金融最喜欢谁?小编今天告诉你...
  18. 十进制怎样转二进制?
  19. c语言doc是什么文件类型,c语言文件后缀意思.doc
  20. Cadence Pspice添加外部白噪声

热门文章

  1. 互联网时代中医药产业复兴的科技创新
  2. 字节跳动(抖音)收购VR眼镜厂商Pico的划时代意义
  3. android diy固件,官方固件不给力?咱自己DIY!手把手教你修改固件!
  4. VMware 装Windows Server 系统
  5. 利用arcgispro将倾斜摄影三维数据OSGB转换为slpk格式
  6. android 头部折叠,Android 头像折叠效果
  7. day05 【异常、线程】
  8. 毕业设计 基于大数据的共享单车数据分析与可视化
  9. 中国FW贝尔探头市场现状研究分析与发展前景预测报告(2022)
  10. ESP32 ESP-IDF安装教程(windows 64位)