grpc调用_避免使用套接字远程过程调用以及如何使用grpc进行程序通信

grpc调用

As we all know, it’s common to use sockets to create a communication channel between 2 programs that need to communicate over the internet. When doing so, our programs end up looking messy, with a lot of repetitive code to fix the common known problems and isn’t very pleasing to write.

众所周知,通常使用套接字在两个需要通过Internet进行通信的程序之间创建通信通道。 这样做时,我们的程序最终看起来很凌乱,带有许多重复的代码来解决常见的已知问题,并且编写起来并不令人满意。

Today I am telling you about RPC, a technology that has emerged lately and has one simple objective: to simplify the communication problem in programming.

今天,我将向您介绍RPC,该技术是最近出现的,其目标很简单:简化编程中的通信问题。

Now if you have never worked with sockets you might be wondering “Wow what’s so hard about programming with sockets anyway?”. For that, let me give you a few examples:

现在,如果您从未使用过套接字,您可能会想:“哇,用套接字编程到底有什么难呢?”。 为此,让我举几个例子:

  • Your programs need to explicitly handle communications for sockets to be deployed. This includes handling all the errors that might happen (for example retransmission, in case a message gets lost) and it’s not only complex but also very, very tiring

    您的程序需要显式处理要部署的套接字的通信。 这包括处理所有可能发生的错误(例如,重新传输,以防丢失消息),这不仅很复杂,而且非常累人
  • Your program will probably be interacting with other ones and this means it will have to marshal/unmarshal the data that will be sent as the systems participating might be heterogeneous (that is, they have different configurations — take a look at the simple example of endianness)

    您的程序可能正在与其他程序进行交互,这意味着它将不得不封送/取消封送该程序。 随着系统参与而发送的数据可能是异构的(也就是说,它们具有不同的配置,请看一下字节序简单示例 )

When creating a communication channel between 2 programs, it’s common to have the client-server paradigm. RPC’s objective is to turn the communication into a more high-level task, avoiding wasting time solving the tasks that require time and can cause some mistakes.

在两个程序之间创建通信通道时,通常具有客户端-服务器模式。 RPC的目标是将通信变成更高级的任务,避免浪费时间解决需要时间并可能导致一些错误的任务。

请求-应答协议 (The Request-Reply Protocol)

This protocol defines how the client and the server interact with each other. Every time the client needs to talk to the server it performs a request operation which will have a reply operation performed by the server, which will hide the network communication.

该协议定义了客户端和服务器之间如何交互。 每次客户端需要与服务器对话时,客户端都会执行请求操作 ,服务器将执行回复操作 ,这将隐藏网络通信。

It is still needed to use a specific protocol for the transport layer, and one must decide between TCP or UDP. Because of the TCP overhead, this protocol has been built over UDP (which means TCP also works).

仍然需要为传输层使用一种特定的协议,并且必须在TCP或UDP之间做出决定。 由于存在TCP开销,因此该协议是基于UDP构建的(这意味着TCP也可以使用)。

So now, we need to define how messages will be represented. A basic representation is to split it into 3 parts: Request identifier, Operation identifier and Arguments/Return value

所以现在,我们需要定义如何表示消息。 一个基本的表示形式是将其分为3部分:请求标识符,操作标识符和参数/返回值

Image for post
Division of an RPC message
RPC消息的划分

So now that we have split the message and know how it will be sent, we now need to think on how to codify the data. Because of the problem mentioned before, we are required to be careful about how this is codified, to avoid having inconsistent data types across devices. We also need to convert complex data structures into a sequence of bytes for them to be transmitted. Therefore, the type of data from one of the endpoints must be chosen or even a canonic type should be selected. This process of codifying our data into a specific type is called marshalling and the inverse is unmarshalling.

因此,既然我们已经拆分了消息并知道将如何发送消息,那么现在我们需要考虑如何对数据进行编码。 由于前面提到的问题,我们需要对此进行编码时要小心,以避免跨设备的数据类型不一致。 我们还需要将复杂的数据结构转换为字节序列以进行传输。 因此,必须选择来自端点之一的数据类型,甚至应该选择规范类型 。 将我们的数据编码为特定类型的过程称为编组 ,而反过程则是解组

We have yet another detail to pay attention: the fault model. As we’re now using UDP, messages can get lost, be repeated or even arrive out-of-order. Processes can also crash, to which we call it a silent fault. When developing an RPC tool, one must pay attention to this model for it to work correctly. One of the problems that stands out is how to detect these problems if there is no connection. For this, a client can then have a timeout with a callback behaviour to fix these problems, by resending the request until a specified amount of times before concluding it’s not working.

我们还有另一个需要注意的细节: 故障模型 。 当我们现在使用UDP时,消息可能会丢失,被重复甚至乱序发送。 进程也可能崩溃,对此我们称之为静默故障 。 开发RPC工具时,必须注意此模型才能使其正常工作。 突出的问题之一是在没有连接的情况下如何检测这些问题。 为此,客户端可以通过重新发送请求直到指定的时间量(在确定其不起作用之前),使超时并具有回调行为来解决这些问题。

And this is where it’s important to have idempotent functions — functions that when applied multiple times in a row produce the same result as if only executed once. This way, the request can be sent multiple times to avoid having unexpected behaviour in the server.

这就是拥有幂等函数的重要位置-连续应用多次的函数产生的结果与只执行一次的结果相同。 这样,可以多次发送请求,以避免服务器中发生意外行为。

To avoid repeating the request, the server must verify the id of the request and if it has been already received. If it is the first, it executes it, otherwise, it must save a log of the answers and return that answer, by using a (request.id, answer) table.

为避免重复请求,服务器必须验证请求ID,以及是否已收到请求 。 如果是第一个, 它将执行它 ,否则,它必须保存一个答案日志并通过使用(request.id,answer)表返回该答案。

There’s still another problem, which stands with using messages bigger than the supported by a UDP datagram. There are multiple solutions, and one can just opt to use TCP by now. It’s the one that’s used in the request-reply HTTP variant.

还有另一个问题,就是使用比UDP数据报支持的消息大的消息。 有多种解决方案,并且现在可以选择使用TCP。 这是在请求-答复HTTP变体中使用的那个。

This protocol helps to simplify the problem. It has the advantage of hiding the communication making it simpler. Nonetheless, it has the problem of having to codify the data into a specific type.

该协议有助于简化问题。 它具有隐藏通信的优势,使其更简单。 但是,它存在必须将数据编码为特定类型的问题。

远程过程调用如何工作 (How Remote Procedure Calls work)

The RPC layer was created with a basis on the Request-Reply Protocol. It’s based on the client-server model of programming and it will hide the remote call as a simple function call inside the code. It’s more generic than the request-reply but looks more like standard programming.

RPC层是基于请求-应答协议创建的。 它基于编程的客户端-服务器模型,它将远程调用隐藏为代码内的简单函数调用。 它比请求-应答更通用,但看起来更像是标准编程。

With this approach, the programmer can focus more on the business logic of the application and not worry much about the details on how to implement the system — it can use the tool as a degree of abstraction to simplify the problem.

使用这种方法,程序员可以将更多的精力放在应用程序的业务逻辑上,而不必担心如何实现系统的细节-它可以将工具用作抽象度来简化问题。

RPC is structured in:

RPC的结构如下:

  • A language for describing remote interfaces of the procedure calls that will be done — gRPC uses Protobuf which is then compiled into multiple programming languages.

    一种用于描述将要完成的过程调用的远程接口的语言-gRPC使用Protobuf,然后将其编译为多种编程语言。
  • Stubs, entities that work like an object that has multiple procedures and transform the data in the system into the shared data types (canonic types for example)

    存根,实体像具有多个过程的对象一样工作,并将系统中的数据转换为共享数据类型(例如,规范类型)
  • Run-time library for generic support of the operations that solve the problems mentioned in the beginning

    运行时库,用于对解决开头提到的问题的操作提供通用支持
  • A name manager to locate the servers

    查找服务器的名称管理器

Each topic is extremely dense and I encourage you to take a look at them by yourself with time.

每个主题都非常密集,我鼓励您随着时间的流逝来亲自研究它们。

gRPC —为什么以及如何使用它 (gRPC — why and how to use it)

gRPC is an open-source RPC technology developed by Google which focuses on achieving high-performance remote calls. It has a lot of documentation and this was the gRPC tool I used developing a Distributed Systems project in my bachelor degree.

gRPC是Google开发的一种开源RPC技术,致力于实现高性能的远程调用。 它有很多文档,这是在本科学历中用于开发分布式系统项目的gRPC工具。

The advantages I found while using gRPC is that it simplifies how to create a communication channel between multiple endpoints. By knowing how RPCs work on the inside, one can with great ease create a system that can fulfil its role on the implementation of replication algorithms. The speed of development was also very useful, as I could quickly implement whatever change I wished without having to worry much.

我在使用gRPC时发现的优势在于,它简化了如何在多个端点之间创建通信通道。 通过了解RPC在内部的工作原理,可以轻松地创建一个可以在复制算法的实现中发挥作用的系统。 开发的速度也非常有用,因为我可以快速实现我希望的任何更改,而不必担心太多。

gRPC can maximize its efficiency using HTTP/2 as the way to transfer information (HTTP/2 is extremely fast) and by transforming the messages into binary, maximizing the amount of data that needs to be sent. The problem with this format is that it is difficult the inspection and modification of messages (usually useful in the development of applications — RESTful applications take good advantage of this).

gRPC可以使用HTTP / 2作为传输信息的方式(HTTP / 2非常快)并通过将消息转换为二进制文件来最大化其效率,从而最大化需要发送的数据量 。 这种格式的问题在于难以检查和修改消息(通常在应用程序的开发中很有用-RESTful应用程序充分利用了这一点)。

Now, how do you create an RPC? The first thing you must remember from RPC is that it is based on the Request-Reply Protocol. The logical thing first is to define what messages shall be exchanged. Each message must contain arguments (if there are any) and these arguments must have a name and a type which will then be serialized into a canonic type available in gRPC. Protobuf also needs to contain information about the position of each argument because the messages are serialized in binary and it needs to be able to differentiate it, so you will see a lot of times the usage of an ‘=’ sign with a number representing the position. These numbers don’t have to be sequential and are useful for backwards compatibility.

现在,如何创建RPC? 您必须从RPC记住的第一件事是它基于请求-应答协议。 逻辑上首先要定义应交换哪些消息。 每个消息必须包含参数(如果有),并且这些参数必须具有名称和类型 ,然后将其序列化为gRPC中可用的规范类型 。 Protobuf还需要包含有关每个参数位置的信息,因为消息是以二进制序列化的,并且需要能够区分它们,因此您会经常看到使用'='符号(其中的数字代表位置。 这些数字不必是连续的 ,对于向后兼容很有用。

Let’s now create our first message. Let’s say we want to create an application for a supermarket. For this, we create a Service called Shop which will have an RPC function GetQuantity that upon the request of a GetQuantityRequest returns a GetQuantityResponse.

现在让我们创建第一个消息。 假设我们要为一家超市创建一个应用程序。 对于这一点,我们创建了一个名为服务 将具有RPC功能GetQuantity是在一个GetQuantityRequest的请求返回一个GetQuantityResponse。

By analyzing the chunk above, we created 2 messages, each with an argument, and a service that uses these 2 messages. Each message has a type, name and position inside that message. The type, int32, is a base type available in gRPC. You can check more types in the documentation.

通过分析上面的块,我们创建了2条消息,每条消息都有一个参数,以及使用这2条消息的服务。 每条消息在其内部都有一个类型,名称和位置。 int32类型是gRPC中可用的基本类型。 您可以在文档中检查更多类型。

After installing gRPC on your computer you can compile this code and it will automatically generate stubs for the specific language you want. After that, they can be imported/included in the code and used to perform the communication part of your application very easily.

计算机上安装gRPC后,您可以编译此代码,它将自动生成所需特定语言的存根 。 之后,可以将它们导入/包含在代码中,并可以非常轻松地执行应用程序的通信部分。

In this snippet, the client asks the stub to perform a communication with the server and get the quantity of the product with the id 3. Now we need the server to be able to handle the communication on its side too (i.e. handle the business logic of the request)

在此代码段中,客户端要求存根与服务器进行通信并获取ID为3的产品数量。 现在,我们需要服务器也能够在其一侧处理通信(即处理请求的业务逻辑)

Here, the server will have a function handling this function when it gets called by the corresponding stub. It will then run the code and execute. This operation is a mere read from the server so no state is changed, but more complex operations can be performed.

在这里,服务器将由相应的存根调用它时处理该函数的函数。 然后它将运行代码并执行。 此操作仅是从服务器读取的,因此不会更改任何状态,但是可以执行更复杂的操作。

gRPC is a powerful tool and it’s difficult to simplify it much without getting into deeper details. If you’re interested in learning how to use it, my suggestion is getting started with their quick-start guide which is available in multiple languages. I used Java in the above examples but it’s only because it’s the one I’m the most used to. This was just a small introduction on how RPC works and there are many many things that require more time and dedication to be mastered, sometimes even some previous knowledge.

gRPC是功能强大的工具,如果不深入了解细节就很难对其进行大量简化。 如果您有兴趣学习如何使用它,我的建议是从他们的 快速入门指南 开始,该 指南提供多种语言。 我在上面的示例中使用过Java,但这仅仅是因为它是我最习惯的一种。 这只是有关RPC如何工作的一小部分介绍,许多事情需要花费更多的时间和精力来掌握,有时甚至需要一些以前的知识。

In case you have any questions or recommendations feel free to drop them below. I’ll be happy to answer them all.

如果您有任何疑问或建议,请随时将其放在下面。 我很乐意回答所有问题。

翻译自: https://medium.com/swlh/avoid-using-sockets-remote-procedure-calls-and-how-to-use-grpc-for-your-programs-communication-8670daad3322

grpc调用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值