2016-01-23 42 views
4

我想創建一個簡單的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; 
} 

是上傳圖片(和recieving圖片)的這種方法還行,而不管GRPC文檔中的警告?

如果不是,使用標準表單上傳圖片並更改圖片文件位置是更好的方法(標準)嗎?

+0

您提到的gRPC文檔中有哪些警告? –

+0

@EricAnderson「協議緩衝區並不是爲了處理大量消息而設計的,根據一般經驗,如果您處理的消息大於每兆字節,則可能是考慮替代策略的時候了。」 -https://developers.google.com/protocol-buffers/docs/techniques?hl = en –

回答

4

對於大型二進制傳輸,標準方法是分塊。分塊可以用於兩個目的:1)減少處理每條消息所需的最大內存量; 2)爲恢復部分上載提供一個邊界。對於你的用例,#2可能不是非常必要的。

在gRPC中,客戶端流式調用允許相當自然的分塊,因爲它具有流控制,流水線並且易於在客戶端和服務器代碼中維護上下文。如果您關心部分上傳的恢復,那麼雙向流技術可以很好地工作,因爲服務器可以響應客戶端可以用來恢復的進度確認。

使用獨立RPC的分塊也是可能的,但有更多的複雜性。當負載均衡時,後端可能需要與每個塊的其他後端進行協調。如果您連續上傳塊,那麼網絡的延遲會降低上傳速度,因爲您大部分時間都在等待接收來自服務器的響應。然後,您必須並行上傳(但多少並行?)或增加塊大小。但增加塊大小會增加處理每個塊所需的內存,並增加恢復失敗上載的粒度。並行上傳還要求服務器處理亂序上傳。

+0

所以你建議返回(流字節)?有什麼方法可以將元數據和字節流返回到一個? – FrozenKiwi

+0

我建議用消息來回復,其中一個字段是字節。所以你可以有元數據作爲其他領域。 –

1

問題中提供的解決方案不適用於大尺寸文件。它只適用於較小的圖像尺寸。 更好和標準的方法是使用chunking。 GRPC支持流內置的,所以它是很容易在塊中,我們可以使用流媒體分塊上述方式發送

syntax = 'proto3' 

message UploadImageRequest{ 
    bytes image = 1; 

} 

rpc UploadImage(stream UploadImageRequest) returns (Ack); 

用於分塊的所有語言提供了它自己的方式來基於塊大小的塊文件。

事情打理:

你需要處理的分塊邏輯,流有助於自然發送。 如果你想發送元數據也有三種方法。

1:以下結構

message UploadImageRequest{ 
    AuthToken auth = 1; 
    FileType image_format = 2; 
    bytes image = 3; 
} 

rpc UploadImage(stream UploadImageRequest) returns (Ack); 

這裏字節的使用仍然塊和第一個塊發送的authToken和文件類型以及所有其他請求只是不發送這些元數據。

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); 

3:只是使用以下結構與在第一組塊發送的元數據和其他塊將有數據。你需要在代碼中處理。

syntax = 'proto3' 

message UploadImageRequest{ 
    bytes message = 1; 

} 

rpc UploadImage(stream UploadImageRequest) returns (Ack); 

最後爲auth你可以使用頭,而不是發送消息。