最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

为什么我的Node.js gRPC客户端需要3秒钟才能将请求发送到我的Python gRPC服务器?

网站源码admin25浏览0评论

为什么我的Node.js gRPC客户端需要3秒钟才能将请求发送到我的Python gRPC服务器?

为什么我的Node.js gRPC客户端需要3秒钟才能将请求发送到我的Python gRPC服务器?

让我们首先承认我是gRPC菜鸟。如果我问了一个愚蠢的问题,请继续让我知道,但只能在explaining为什么如此愚蠢之后。谢谢! :)

概述

我正在开发一个处理图像的应用程序。用户可以更改影响处理结果的变量。我想提供一个美观的GUI,同时保持跨平台兼容性。因此,我决定在Python中实现图像处理,并在GUI中使用Node.js和Electron。

需要一种与Python后端之间收发数据的方法,我决定使用gRPC。因此,我有一个Node.js gRPC ClientPython 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以Image的形式返回到Node.js应用程序:

// From My Protocol Buffer
message Image {
    bytes image_data = 1;
    int32 height = 2;
    int32 width = 3;
    int64 frame = 4;    
}

问题

我已经注意到,在提出请求和接收到图像之间存在延迟时间的变化。这段时间从几毫秒到近3秒不等!对Python代码进行性能分析后,我确定处理时间可以忽略不计。此外,通过gRPC返回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; dr

为什么我的Node.js客户端请求触发我的Python代码需要这么长时间?

回答如下:

有几个因素可能会影响您长时间观看。

首先,客户端发出的第一个请求始终需要更长的时间,因为它必须执行一些连接设置工作。通常的期望是,单个客户端将发出许多请求,并且建立时间将分摊到所有这些请求中。

其次,您提到您正在使用Electron。有报道称,在电子渲染过程中使用gRPC for Node时,性能会很差。在主流程或常规Node流程中运行代码时,您可能会看到不同的结果。

如果尝试使用程序包@grpc/grpc-js,也可能会有所不同,这是对Node gRPC库的完全重新实现。该库中不存在您当前用于加载.proto程序包的API,但是使用@grpc/proto-loader的替代方法可用于两种实现,其他API相同。

发布评论

评论列表(0)

  1. 暂无评论