gRPC 服務底層使用 Protocol Buffers 做為序列化的格式,與我們經常使用的 JSON 格式相比之下,其大小已經小非常多了,如果我們還覺得不夠,想要再更進一步地減少傳輸量,可以啟用 gRPC 服務的壓縮(Compression)機制,讓傳輸的資料量再更少一些。
ResponseCompressionLevel
啟用壓縮機制的方式非常簡單,在伺服器端 Startup.cs
的 ConfigureServices()
方法裡面呼叫 AddGrpc()
時,指定 ResponseCompressionLevel
及 ResponseCompressionAlgorithm
的值。
public void ConfigureServices(IServiceCollection services)
{
services.AddGrpc(
grpcOptions =>
{
grpcOptions.ResponseCompressionLevel = CompressionLevel.Optimal;
grpcOptions.ResponseCompressionAlgorithm = "gzip";
});
}
ResponseCompressionLevel 有三個值可以選,分別是:Optimal
、Fastest
、NoCompression
,而 ResponseCompressionAlgorithm 則是根據 CompressionProviders
中有的壓縮演算法來指定, gRPC 服務預設提供的只有 Gzip 壓縮演算法。
這樣做,壓縮機制就算是啟用完畢了,Client 端都不用改。
服務層級的壓縮
上述的設定方式是屬於全域設定,一設定之後所有的服務都會套用,如果只想針對單一個服務啟用壓縮機制,須改用 AddServiceOptions()
方法。
public void ConfigureServices(IServiceCollection services)
{
services.AddGrpc()
.AddServiceOptions<EmployeeService>(
grpcOptions =>
{
grpcOptions.ResponseCompressionLevel = CompressionLevel.Optimal;
grpcOptions.ResponseCompressionAlgorithm = "gzip";
});
}
服務方法層級的壓縮
想再更精確地控制到某個服務方法才啟用壓縮機制,這個需要搭配啟用「服務層級的壓縮」之後,在不需要壓縮機制的服務方法內,變更其回應的 WriteOptions
值為 NoCompress
。
客戶端單方面關閉壓縮
通常我們會把壓縮這件事情設定在伺服器端,客戶端只能被動接受,但是某些客戶端的情境會希望不要使用壓縮,gRPC 服務也允許我們在客戶端將其關閉,我們只要在建立 Channel 的時候將 CompressionProviders 清空就行了。
看看差了多少?
為了看出差異,我請出了老牌的網路監控工具 - Network Monitor,以我的範例來看,在還沒壓縮前整個傳輸量在 3500 bytes 左右。
啟用最佳壓縮之後,降到了 350 bytes 左右。
然而,壓縮這件事並不是免費的午餐,它會讓伺服器端及客戶端多一點 CPU 的消耗,因此要不要使用壓縮,我們必須加以衡量,看看我們的資料中,重複性的內容是不是很多?測試看看啟用前後的回應速度是不是如我們預期?做好完整的驗證之後,再來決定是否應該使用壓縮。