grpc调用
Remote procedure call (RPC) architecture is popular in building scalable distributed client/server model based applications.
远程过程调用(RPC)体系结构在构建可扩展的基于分布式客户端/服务器模型的应用程序中很流行。
RPC allows a client to a make procedure call (also referred to as subroutine call or function call ) to a server on a different address space without understanding the network configuration as if the server was in the same network (making a local procedure call).
RPC允许客户端在不同的地址空间上对服务器进行过程调用(也称为子例程调用或函数调用 ),而无需像服务器在同一网络中那样理解网络配置(进行本地过程调用 )。
In this tutorial, we will implement an RPC client/server model using Google's gRPC and Protocol Buffers.
在本教程中,我们将使用Google的gRPC和协议缓冲区来实现RPC客户端/服务器模型。
Before we dive into the heart of RPC, let's take some time to understand how it works.
在深入研究RPC的核心之前,让我们花一些时间来了解它是如何工作的。
While in the process of building out a scalable microservice architecture and Andela, we are implementing REST to expose API endpoints, through and API gateway, to external applications (mostly web apps in AngularJS and ReactJS). Inter service communication is then handled using RPC.
在构建可伸缩的微服务架构和Andela的过程中 ,我们正在实现REST,以通过API网关将API端点公开给外部应用程序(主要是AngularJS和ReactJS中的Web应用程序)。 然后使用RPC处理服务间通信。
Remote procedure call's data serialization into binary format for inter-process (server to server) communication makes it ideal for building out scalable microservice architecture by improving performance.
远程过程调用将数据序列化为二进制格式以进行进程间(服务器到服务器)通信,使其成为通过提高性能来构建可伸缩微服务体系结构的理想选择。
RPC client and server run-time stubs take care of the network protocol and communication so that you can focus on your application.
RPC客户端和服务器运行时存根负责网络协议和通信,因此您可以专注于应用程序。
While RPC and REST use the request/response HTTP protocol to send and receive data respectively, REST is the most popular and preferred client-server communication approach.
尽管RPC和REST使用请求/响应HTTP协议分别发送和接收数据,但是REST是最受欢迎的客户端-服务器通信方法。
Before we dive into RPC. Let's make a comparison of the two.
在我们深入到RPC之前。 让我们对两者进行比较。
The choice of architecture to use entirely remains at the discretion of the development teams and the nature of the system. Some developers have argued against comparing the two, and rightfully so because they can work well together.
完全使用体系结构的选择取决于开发团队和系统的性质。 一些开发人员反对将两者进行比较,这是正确的,因为它们可以很好地协同工作。
Read more about how the two compare on this article by Joshua Hartman.
在Joshua Hartman的这篇文章中阅读更多有关两者比较的信息。
Google managed gRPC is a very popular open source RPC framework with support of languages such as C++, Java, Python, Go, Ruby, Node.js, C#, Objective-C and PHP.
Google托管的gRPC是一个非常流行的开源RPC框架,支持诸如C ++,Java,Python,Go,Ruby,Node.js,C#,Objective-C和PHP等语言。
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框架。 它可以通过可插拔的支持来有效地连接数据中心内和跨数据中心的服务,以实现负载平衡,跟踪,健康检查和身份验证。 它也适用于分布式计算的最后一英里,以将设备,移动应用程序和浏览器连接到后端服务。
http://www.grpc.io/about/
http://www.grpc.io/about/
As we mentioned, with gRPC, a client application can directly call methods on a server application on a different network as if the method was local. The beauty about RPC is that it is language agnostic. This means you could have a grpc server written in Java handling client calls from node.js, PHP and Go.
如前所述,使用gRPC,客户端应用程序可以直接在其他网络上的服务器应用程序上调用方法,就像该方法是本地方法一样。 RPC的优点在于它与语言无关。 这意味着您可以使用Java编写的grpc服务器来处理来自node.js,PHP和Go的客户端调用。
gRPC allows you to define a service which specifies the methods that you can call remotely, the parameters that can be passed to the procedure call and the return responses. The server then implements this definitions and creates a new grpc server to handle the procedure calls from the client.
gRPC允许您定义服务,该服务指定可以远程调用的方法,可以传递给过程调用的参数以及返回响应。 然后,服务器将实现此定义,并创建一个新的grpc服务器来处理来自客户端的过程调用。
By default, gRPC implements Protocol Buffers to serialize structured data as well as define the parameters and return responses for the callable methods.
默认情况下,gRPC实现协议缓冲区来序列化结构化数据以及定义参数并返回可调用方法的响应。
Before we get into your first RPC application with gRPC, it is good to look at why we should go for gRPC as opposed to other RPC frameworks such as Apache's Thrift.
在使用gRPC进入您的第一个RPC应用程序之前,先了解一下为什么要使用gRPC而不是其他RPC框架(例如Apache的Thrift)是一件好事。
We will be building a simple RPC based app that let's you employees know if they are eligible for work leave or not, if they are, we will proceed to grant them leave days. The rundown of how we will achieve this
我们将构建一个简单的基于RPC的应用程序,该应用程序可让您知道员工是否有资格请假,如果符合条件,我们将继续为他们提供请假天数。 我们将如何实现这一目标
Our project structure will be laid out as follows.
我们的项目结构如下。
├── package.json
├── .gitignore
├── .grpclirc
├── server/
├── index.js
├── client/
├── node/
├── python/
├── proto/
├── work_leave.proto
proto/work_leave.proto
proto / work_leave.proto
syntax = "proto3"; //Specify proto3 version.
package work_leave; //Optional: unique package name.
//Service. define the methods that the grpc server can expose to the client.
service EmployeeLeaveDaysService {
rpc EligibleForLeave (Employee) returns (LeaveEligibility);
rpc grantLeave (Employee) returns (LeaveFeedback);
}
// Message Type fefinition for an Employee.
message Employee {
int32 employee_id = 1;
string name = 2;
float accrued_leave_days = 3;
float requested_leave_days = 4;
}
// Message Type definition for LeaveEligibility response.
message LeaveEligibility {
bool eligible = 1;
}
// Message Type definition for LeaveFeedback response.
message LeaveFeedback {
bool granted = 1;
float accrued_leave_days = 2;
float granted_leave_days = 3;
}
Let's take a logical walk through of the .proto
file.
让我们对.proto
文件进行逻辑遍历。
Notice how easy it is to interpret the Service method implementations.
请注意,解释Service方法实现很容易。
With our .proto
file in hand, let's go ahead and create our gRPC server. Since our server is written in Node, go ahead and initalize a new node project and install the grpc package.
有了我们的.proto
文件,让我们继续创建gRPC服务器。 由于我们的服务器是用Node编写的,因此继续并启动一个新的Node项目并安装grpc软件包。
npm install --save grpc
Next, create a server directory and add the following code to spin up the server.
接下来,创建服务器目录并添加以下代码以启动服务器。
server/index.js
服务器/ index.js
const grpc = require('grpc');
const proto = grpc.load('proto/work_leave.proto');
const server = new grpc.Server();
//define the callable methods that correspond to the methods defined in the protofile
server.addProtoService(proto.work_leave.EmployeeLeaveDaysService.service, {
/**
Check if an employee is eligible for leave.
True If the requested leave days are greater than 0 and within the number
of accrued days.
*/
eligibleForLeave(call, callback) {
if (call.request.requested_leave_days > 0) {
if (call.request.accrued_leave_days > call.request.requested_leave_days) {
callback(null, { eligible: true });
} else {
callback(null, { eligible: false });
}-1
} else {
callback(new Error('Invalid requested days'));
}
},
/**
Grant an employee leave days
*/
grantLeave(call, callback) {
let granted_leave_days = call.request.requested_leave_days;
let accrued_leave_days = call.request.accrued_leave_days - granted_leave_days;
callback(null, {
granted: true,
granted_leave_days,
accrued_leave_days
});
}
});
//Specify the IP and and port to start the grpc Server, no SSL in test environment
server.bind('0.0.0.0:50050', grpc.ServerCredentials.createInsecure());
//Start the server
server.start();
console.log('grpc server running on port:', '0.0.0.0:50050');
First, we load the grpc package and load the proto file using the exposed load method and then create a new instance of ther grpc server.
首先,我们使用暴露的load方法加载grpc软件包并加载proto文件,然后创建grpc服务器的新实例。
The server instance gives us access to the following key methods.
服务器实例使我们可以访问以下关键方法。
Takes two parameters, a link to the service name and a list of methods defined in the respective service. The service name is referenced as
.
采用两个参数,即指向服务名称的链接和在相应服务中定义的方法列表。 服务名称引用为
。
Each of the defined method takes in a call which contains the payload from the client and a callback function that returns an error and response respectively.
每个定义的方法都接受一个调用,该调用包含来自客户端的有效负载和一个分别返回错误和响应的回调函数。
The bind method specifies the IP and port on which to create the server. Since we are on a test environment, we will also create an insecure server(No SSL).
bind方法指定要在其上创建服务器的IP和端口。 由于我们处于测试环境中,因此我们还将创建一个不安全的服务器(无SSL)。
The start method simply starts the server.
start方法只是启动服务器。
To take our new server for a test drive, let's globally install a CLI grpc client before we proceed to create our own clients.
为了将我们的新服务器用于测试驱动器,让我们先全局安装一个CLI grpc客户端,然后再继续创建自己的客户端。
npm install -g grpcli
Next, let's start our server.
接下来,让我们启动服务器。
node server
To run the client, navigate to the route of your grpc application and run the grpcli command with the path to the protofile, the IP address and port to connect to and a command to start the client as insecured. You can also specify the configurations in a .grpclirc
file
要运行客户端,请导航至grpc应用程序的路由,并运行grpcli命令以及原型文件的路径,要连接的IP地址和端口以及以不安全的方式启动客户端的命令。 您也可以在.grpclirc
文件中指定配置
grpcli -f proto/work_leave.proto --ip=127.0.0.1 --port=50050 -i
Once a connection is established, you will be able to list all callable methods with rpc list
and call methods with rpc call
.
建立连接后,您将能够使用rpc list
列出所有可调用方法,并使用rpc call
rpc list
调用方法。
Sweet! Now with that working, let's go ahead and create the grpc clients.
甜! 现在,完成这项工作,让我们继续创建grpc客户。
Like we had mentioned earlier, we will be creating gRPC clients in Node.js and Python just because we can. This will help us appreciate the power of RPC.
就像我们之前提到的那样,我们将尽我们所能在Node.js和Python中创建gRPC客户端。 这将帮助我们欣赏RPC的强大功能。
For each of the clients we will basically confirm if an employee is eligible for leave and if they are, we will proceed to grant them the requested leave days.
对于每个客户,我们基本上都会确认员工是否有资格请假,如果有请假,我们将继续向他们授予所要求的请假天数。
Let's go ahead and create an index.js file in client/node and proceed to create our first client.
让我们继续在客户端/节点中创建一个index.js文件,然后继续创建我们的第一个客户端。
const grpc = require('grpc');
const protoPath = require('path').join(__dirname, '../..', 'proto');
const proto = grpc.load({root: protoPath, file: 'work_leave.proto' });
//Create a new client instance that binds to the IP and port of the grpc server.
const client = new proto.work_leave.EmployeeLeaveDaysService('localhost:50050', grpc.credentials.createInsecure());
const employees = {
valid: {
employee_id: 1,
name: 'John Kariuki',
accrued_leave_days: 10,
requested_leave_days: 4
},
ineligible: {
employee_id: 1,
name: 'John Kariuki',
accrued_leave_days: 10,
requested_leave_days: 20
},
invalid: {
employee_id: 1,
name: 'John Kariuki',
accrued_leave_days: 10,
requested_leave_days: -1
},
illegal: {
foo: 'bar'
}
}
client.eligibleForLeave(employees.valid, (error, response) => {
if (!error) {
if (response.eligible) {
client.grantLeave(employees.valid, (error, response) => {
console.log(response);
})
} else {
console.log("You are currently ineligible for leave days");
}
} else {
console.log("Error:", error.message);
}
});
Just like we did for the server, we need to load the proto file and the grpc package. We then create a new client instance that binds to our server's address and port.
就像我们对服务器所做的一样,我们需要加载原始文件和grpc软件包。 然后,我们创建一个绑定到服务器地址和端口的新客户端实例。
At this point, we can now directly make calls to the methods defined in our server. As we had mentioned, each method take in a payload parameter and a callback function that returns an error and response respectively.
此时,我们现在可以直接调用服务器中定义的方法。 正如我们已经提到的,每种方法都带有一个有效负载参数和一个分别返回错误和响应的回调函数。
Let's take a look at how this looks like on our terminal.
让我们看看终端上的情况。
simply call
只需致电
node client/node
Simple, but powerful.
简单,但功能强大。
The protocol buffer limits us to how the employee object looks like so an error would be raised if you tried passing the employees.illegal
object. Give it a spin for the different employees provided.
协议缓冲区将我们限制为employee对象的外观,因此如果您尝试传递employees.illegal
对象,则会引发错误。 尝试一下提供的不同员工。
To build a Python client, here are a few prerequisites.
要构建Python客户端,这里有一些先决条件。
python -m pipinstall --upgrade pip
mkvirtualenv grpc_tutorial && workon grpc_tutorial
`
In our virtual environment, install the grpc and grpc tools packages
在我们的虚拟环境中,安装grpc和grpc工具包
pipinstall grpcio grpcio-tools
The grpcio-tools
module ships with protoc, the protocol buffer compiler as well as plugins for generating server and client code from the service definitions in the proto file.
所述grpcio-tools
模块附带protoc,协议缓冲编译器,以及用于从在原文件中的服务定义生成服务器和客户端代码的插件。
Create a generate_pb.py file in client/python and add the following code to compile the protocol buffer file to python.
在client / python中创建一个generate_pb.py文件,并添加以下代码以将协议缓冲区文件编译为python。
from grpc.tools import protoc
protoc.main(
(
'',
'--proto_path=../../proto/',
'--python_out=.',
'--grpc_python_out=.',
'../../proto/work_leave.proto'
)
)
With that, from the python client directory, simply run:
这样,只需在python客户端目录中运行:
python generate_pb.py
This will generate a client/python/work_leave_pb2.py
which we will use to create our python client.
这将生成一个client/python/work_leave_pb2.py
,我们将使用它来创建我们的python客户端。
in *client/python/client.py *, let's go ahead and load the grpc module and the python protobuf. We then create an insecure channel to bind to the server's address and port and create a stub from the EmployeeLeaveDaysService
.
在* client / python / client.py *中,让我们继续并加载grpc模块和python protobuf。 然后,我们创建一个不安全的通道来绑定到服务器的地址和端口,并从EmployeeLeaveDaysService
创建一个存根。
import grpc
import work_leave_pb2 as pb
def main():
"""Python Client for Employee leave days"""
# Create channel and stub to server's address and port.
channel = grpc.insecure_channel('localhost:50050')
stub = pb.EmployeeLeaveDaysServiceStub(channel)
# Exception handling.
try:
# Check if the Employee is eligible or not.
response = stub.EligibleForLeave(pb.Employee(employee_id=1,
name='Peter Pan',
accrued_leave_days=10,
requested_leave_days=5))
print(response)
# If the Employee is eligible, grant them leave days.
if response.eligible:
leaveRequest = stub.grantLeave(pb.Employee(employee_id=1,
name='Peter Pan',
accrued_leave_days=10,
requested_leave_days=5))
print(leaveRequest)
# Catch any raised errors by grpc.
except grpc.RpcError as e:
print("Error raised: " + e.details())
if __name__ == '__main__':
main()
Start the node server and run the python client on a different terminal.
启动节点服务器,并在其他终端上运行python客户端。
For the PHP developers, gRPC can only support PHP clients currently. You can therefore not create a gRPC server with PHP.
对于PHP开发人员,gRPC当前仅支持PHP客户端。 因此,您无法使用PHP创建gRPC服务器。
In this tutorial, we have managed to create a gRPC server in Node.js and made RPC calls from a Node.js and Python client based on a protocol buffer definition.
在本教程中,我们设法在Node.js中创建了一个gRPC服务器,并根据协议缓冲区定义从Node.js和Python客户端进行了RPC调用。
For those of you that dare, you may make pull requests to this tutorial's repository for both gRPC clients and servers in all the other supported languages. Make sure to abide to the directory structure.
对于那些胆敢的人,您可以使用所有其他受支持的语言向gRPC客户端和服务器的本教程存储库发出拉取请求。 确保遵守目录结构。
翻译自: https://scotch.io/tutorials/implementing-remote-procedure-calls-with-grpc-and-protocol-buffers
grpc调用