为什么我的 Node.js gRPC 客户端需要 3 秒才能向我的 Python gRPC 服务器发送请求?
Why does my Node.js gRPC client take 3 seconds to send a request to my Python gRPC server?
首先承认我是 gRPC 菜鸟。如果我问了一个愚蠢的问题,请继续告诉我,但只有在 解释 为什么它是愚蠢的之后。谢谢! :)
概览
我正在开发一个处理图像的应用程序。影响处理结果的变量可由用户更改。我想在保持跨平台兼容性的同时提供美观的 GUI。因此,我决定在 Python 中实现我的图像处理,并在我的 GUI 中使用 Node.js 和 Electron。
需要一种方法来向我的 Python 后端发送和接收数据,我决定使用 gRPC。因此,我有一个 Node.js gRPC Client 与 Python gRPC Server.
配对
在阅读了许多教程并了解了一些关于协议缓冲区的知识之后,我能够在两个程序之间成功传输数据。
设置
Node.js Electron 应用程序接受用户的输入,并向 Python 后端发送请求。请求大小为小对象:
// From My Protocol Buffer
message DetectionSettings {
float lowerThreshold = 1;
float upperThreshold = 2;
float smallestObject = 3;
float largestObject = 4;
float blurAmount = 5;
int64 frameNumber = 6;
string streamSource = 7;
}
收到此请求后,Python 应用程序从指定的 streamSource
读取一个帧并对其进行处理。然后将此处理后的帧转换为 JPEG 格式,并通过 gRPC returned 到 Node.js 应用程序作为 Image
:
// From My Protocol Buffer
message Image {
bytes image_data = 1;
int32 height = 2;
int32 width = 3;
int64 frame = 4;
}
问题
我注意到在发出请求和接收图像之间存在可变延迟。这个时间从几毫秒到近 3 秒不等!在分析 Python 代码后,我确定处理时间可以忽略不计。此外,通过 gRPC return 到 Image
所花费的时间也可以忽略不计。
因此在 RPC 执行和 Python 应用程序接收调用之间存在有趣的延迟。这里有一些带有时间的日志,可以更好地解释发生了什么(括号中的数字以秒为单位):
/* Node.js */
[160408.072] "Sending Request..."
[160408.072] "Executing RPC"
[160408.072] "RPC Executed"
/* Python */
[160411.032] [ py-backend ] Getting frame
/* Node.js */
[160411.617] "Got Data"
你可以看到,在这种情况下,从 Node.js RPC 执行到调用 Python 方法的时间约为 3 秒,而从执行 Python 的时间Node.js 应用程序接收 Image
的方法少于 1 秒 0.o
代码
Python gRPC 服务器
# Create the server
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
# Add our service to the server
processor_pb2_grpc.add_ProcessorServicer_to_server(
ProcessorServicer(), server
)
server.add_insecure_port('[::1]:50053')
server.start()
server.wait_for_termination()
Node.js 客户:
const grpc = require('grpc')
const PROTO_PATH = '../processor.proto'
const serviceConfig = {
"loadBalancingConfig": [ {"round_robin": {} } ]
}
const options = {
'grpc.service_config': JSON.stringify(serviceConfig)
}
const ProcessorService = grpc.load(PROTO_PATH).Processor
const client = new ProcessorService ('[::1]:50053',
grpc.credentials.createInsecure(), options);
module.exports = client
协议缓冲区:
syntax = "proto3";
message Number {
float value = 1;
}
message Image {
bytes image_data = 1;
int32 height = 2;
int32 width = 3;
int64 frame = 4;
}
message DetectionSettings {
float lowerThreshold = 1;
float upperThreshold = 2;
float smallestObject = 3;
float largestObject = 4;
float blurAmount = 5;
int64 frameNumber = 6;
string streamSource = 7;
}
service Processor{
rpc GetFrame(DetectionSettings) returns (Image) {};
}
Node.js gRPC 调用:
function GetFrameBytes(detectionSettings, streamSource, frameNumber, callback)
{
detectionSettings["streamSource"] = streamSource;
detectionSettings["frameNumber"] = frameNumber;
client.GetFrame(detectionSettings, (error, response) =>
{
if(!error){
callback(response)
}
else
{
console.error(error);
}
});
}
tl;博士
为什么我的 Node.js 客户端请求需要这么长时间才能触发我的 Python 代码?
有几个因素可能会影响您看到的时间。
首先,客户端发出的第一个请求总是需要更长的时间,因为它必须进行一些连接设置工作。一般的预期是单个客户端会发出许多请求,并且设置时间将分摊到所有这些请求上。
其次,您提到您正在使用 Electron。有一些报告称,在 Electron 渲染过程中使用 gRPC for Node 时性能不佳。当 运行 您的代码在主进程或常规 Node 进程中时,您可能会看到不同的结果。
如果您尝试包 @grpc/grpc-js
,您可能也会有不同的运气,它是 Node gRPC 库的完整重新实现。您当前用于加载 .proto
包的 API 在该库中不存在,但是使用 @grpc/proto-loader
的替代方法适用于这两种实现,而其他 API 是一样。
首先承认我是 gRPC 菜鸟。如果我问了一个愚蠢的问题,请继续告诉我,但只有在 解释 为什么它是愚蠢的之后。谢谢! :)
概览
我正在开发一个处理图像的应用程序。影响处理结果的变量可由用户更改。我想在保持跨平台兼容性的同时提供美观的 GUI。因此,我决定在 Python 中实现我的图像处理,并在我的 GUI 中使用 Node.js 和 Electron。
需要一种方法来向我的 Python 后端发送和接收数据,我决定使用 gRPC。因此,我有一个 Node.js gRPC Client 与 Python gRPC Server.
配对在阅读了许多教程并了解了一些关于协议缓冲区的知识之后,我能够在两个程序之间成功传输数据。
设置
Node.js Electron 应用程序接受用户的输入,并向 Python 后端发送请求。请求大小为小对象:
// From My Protocol Buffer
message DetectionSettings {
float lowerThreshold = 1;
float upperThreshold = 2;
float smallestObject = 3;
float largestObject = 4;
float blurAmount = 5;
int64 frameNumber = 6;
string streamSource = 7;
}
收到此请求后,Python 应用程序从指定的 streamSource
读取一个帧并对其进行处理。然后将此处理后的帧转换为 JPEG 格式,并通过 gRPC returned 到 Node.js 应用程序作为 Image
:
// From My Protocol Buffer
message Image {
bytes image_data = 1;
int32 height = 2;
int32 width = 3;
int64 frame = 4;
}
问题
我注意到在发出请求和接收图像之间存在可变延迟。这个时间从几毫秒到近 3 秒不等!在分析 Python 代码后,我确定处理时间可以忽略不计。此外,通过 gRPC return 到 Image
所花费的时间也可以忽略不计。
因此在 RPC 执行和 Python 应用程序接收调用之间存在有趣的延迟。这里有一些带有时间的日志,可以更好地解释发生了什么(括号中的数字以秒为单位):
/* Node.js */
[160408.072] "Sending Request..."
[160408.072] "Executing RPC"
[160408.072] "RPC Executed"
/* Python */
[160411.032] [ py-backend ] Getting frame
/* Node.js */
[160411.617] "Got Data"
你可以看到,在这种情况下,从 Node.js RPC 执行到调用 Python 方法的时间约为 3 秒,而从执行 Python 的时间Node.js 应用程序接收 Image
的方法少于 1 秒 0.o
代码
Python gRPC 服务器
# Create the server
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
# Add our service to the server
processor_pb2_grpc.add_ProcessorServicer_to_server(
ProcessorServicer(), server
)
server.add_insecure_port('[::1]:50053')
server.start()
server.wait_for_termination()
Node.js 客户:
const grpc = require('grpc')
const PROTO_PATH = '../processor.proto'
const serviceConfig = {
"loadBalancingConfig": [ {"round_robin": {} } ]
}
const options = {
'grpc.service_config': JSON.stringify(serviceConfig)
}
const ProcessorService = grpc.load(PROTO_PATH).Processor
const client = new ProcessorService ('[::1]:50053',
grpc.credentials.createInsecure(), options);
module.exports = client
协议缓冲区:
syntax = "proto3";
message Number {
float value = 1;
}
message Image {
bytes image_data = 1;
int32 height = 2;
int32 width = 3;
int64 frame = 4;
}
message DetectionSettings {
float lowerThreshold = 1;
float upperThreshold = 2;
float smallestObject = 3;
float largestObject = 4;
float blurAmount = 5;
int64 frameNumber = 6;
string streamSource = 7;
}
service Processor{
rpc GetFrame(DetectionSettings) returns (Image) {};
}
Node.js gRPC 调用:
function GetFrameBytes(detectionSettings, streamSource, frameNumber, callback)
{
detectionSettings["streamSource"] = streamSource;
detectionSettings["frameNumber"] = frameNumber;
client.GetFrame(detectionSettings, (error, response) =>
{
if(!error){
callback(response)
}
else
{
console.error(error);
}
});
}
tl;博士
为什么我的 Node.js 客户端请求需要这么长时间才能触发我的 Python 代码?
有几个因素可能会影响您看到的时间。
首先,客户端发出的第一个请求总是需要更长的时间,因为它必须进行一些连接设置工作。一般的预期是单个客户端会发出许多请求,并且设置时间将分摊到所有这些请求上。
其次,您提到您正在使用 Electron。有一些报告称,在 Electron 渲染过程中使用 gRPC for Node 时性能不佳。当 运行 您的代码在主进程或常规 Node 进程中时,您可能会看到不同的结果。
如果您尝试包 @grpc/grpc-js
,您可能也会有不同的运气,它是 Node gRPC 库的完整重新实现。您当前用于加载 .proto
包的 API 在该库中不存在,但是使用 @grpc/proto-loader
的替代方法适用于这两种实现,而其他 API 是一样。