Nat*_*Lee 17 protocol-buffers grpc
我想创建一个简单的gRPC
端点,用户可以上传他/她的图片.协议缓冲区声明如下:
message UploadImageRequest {
AuthToken auth = 1;
// An enum with either JPG or PNG
FileType image_format = 2;
// Image file as bytes
bytes image = 3;
}
Run Code Online (Sandbox Code Playgroud)
无论gRPC文档中的警告如何,这种上传图片(和接收图片)的方法仍然可以吗?
如果没有,使用标准表格上传图片并存储图像文件位置是更好的方法(标准)吗?
Eri*_*son 17
对于大型二进制传输,标准方法是分块.分块可以用于两个目的:1)减少处理每个消息所需的最大内存量; 2)提供恢复部分上载的边界.对于您的用例,#2可能不是非常必要的.
在gRPC中,客户端流式调用允许相当自然的分块,因为它具有流控制,流水线操作,并且易于在客户端和服务器代码中维护上下文.如果您关心部分上传的恢复,那么双向流工作正常,因为服务器可以响应客户端可以用来恢复的进度确认.
使用单独的RPC进行分块也是可能的,但是有更多的复杂性.当负载平衡时,可能需要后端与每个块的其他后端协调.如果您按顺序上传块,那么网络延迟可能会降低上传速度,因为您花费大部分时间等待从服务器接收响应.然后你要么必须并行上传(但并行上传多少?)或增加块大小.但是,增加块大小会增加处理每个块所需的内存,并增加恢复失败上载的粒度.并行上载还要求服务器处理无序上载.
Sam*_*dra 13
问题中提供的解决方案不适用于大尺寸的文件.它只适用于较小的图像尺寸.更好的标准方法是使用分块.grpc支持内置流式传输.所以很容易以块的形式发送
syntax = 'proto3'
message UploadImageRequest{
bytes image = 1;
}
rpc UploadImage(stream UploadImageRequest) returns (Ack);
Run Code Online (Sandbox Code Playgroud)
以上述方式我们可以使用流式传输进行分块.
对于分块,所有语言都根据块大小提供了自己的块文件方式.
需要注意的事项:
你需要处理分块逻辑,流媒体有助于自然发送.如果你想发送元数据也有三种方法.
1:使用以下结构
message UploadImageRequest{
AuthToken auth = 1;
FileType image_format = 2;
bytes image = 3;
}
rpc UploadImage(stream UploadImageRequest) returns (Ack);
Run Code Online (Sandbox Code Playgroud)
这里的字节仍然是块,对于第一个块发送AuthToken和FileType,对于所有其他请求,只是不发送那些元数据.
2:你也可以使用oneof
哪个更容易.
message UploadImageRequest{
oneof test_oneof {
Metadata meta = 2;
bytes image = 1;
}
}
message Metadata{
AuthToken auth = 1;
FileType image_format = 2;
}
rpc UploadImage(stream UploadImageRequest) returns (Ack);
Run Code Online (Sandbox Code Playgroud)
3:只使用下面的结构并在第一个块发送元数据和其他块将有数据.你需要在代码中处理它.
syntax = 'proto3'
message UploadImageRequest{
bytes message = 1;
}
rpc UploadImage(stream UploadImageRequest) returns (Ack);
Run Code Online (Sandbox Code Playgroud)
最后,对于auth,您可以使用标头而不是在消息中发送它.
归档时间: |
|
查看次数: |
19225 次 |
最近记录: |