IceRPC之調用管道Invocation pipeline與傳出請求Outgoing request->快樂的RPC

作者引言 .Net 8.0 下的新RPC

很高興啊,我們來到了IceRPC之調用管道 Invocation pipeline與傳出請求 Outgoing request->快樂的RPC, 基礎引導,讓自已不在迷茫,快樂的暢遊世界。

調用管道 Invocation pipeline

瞭解如何發送請求requests和接收響應responses

定義

發送請求並接收相應響應的過程稱爲調用。

通常會通過客戶端連接進行調用。然而,由於客戶端和服務器連接具有相同的功能,因此也可以反過來調用,從連接的服務器端到此連接的客戶端。

調用抽象

IceRPC總是通過調用調用器invoker來進行調用。調用器是一個簡單的抽象,它接受傳出的請求並返回傳入的響應。

C# 中, 這個抽象是 IInvoker 接口:

namespace IceRpc;

public interface IInvoker
{
    Task<IncomingResponse> InvokeAsync(OutgoingRequest request, CancellationToken cancellationToken = default);
}

ClientConnectionConnectionCache 都實現此接口。 這允許通過創建客戶端連接或連接緩存,然後在生成的實例上調用 InvokeAsync 來進行調用:

await using var clientConnection = new ClientConnection(new Uri("icerpc://hello.zeroc.com"));
using var request = new OutgoingRequest(...);

// Make an invocation by calling the IInvoker.InvokeAsync method implemented by ClientConnection.
IncomingResponse response = await clientConnection.InvokeAsync(request);

處理調用

在將其提供給連接之前,通常會對調用執行附加處理。例如,可能需要壓縮請求的有效負載、爲每個請求添加遙測字段、添加截止時間或簡單地添加日誌記錄等。

調用器實現可以調用另一個調用器,它本身調用另一個調用器,等等;用於進行調用的調用器可以是調用器鏈或樹的頭,稱爲"調用管道"invocation pipeline.

3種常見的調用者類型:

  • Leaf invoker
    這是調用管道中的一片葉子。該調用器通常是連接。

  • Interceptor
    攔截器攔截調用,並將其轉發到"下一個"next攔截器。IceRPC提供了幾個內置的攔截器,用於記錄,壓縮等。

  • Pipeline
    管道在向調用器發出請求之前,通過在該管道中註冊的攔截器來執行請求。

--- title: A typical invocation pipeline --- flowchart LR app([application code]) -- request --> i1["interceptor #1"] -- request --> i2["interceptor #2"] i2 -- request --> ti["ClientConnection\n or ConnectionCache"] -- request --> connection connection -- response --> ti -- response --> i2 -- response --> i1 -- response --> app

傳出請求 Outgoing request

瞭解如何創建傳出請求

創建傳出請求 Outgoing request

爲了創建 RPC,構造一個傳出請求,然後將此請求作爲參數傳遞給調用者invoke的調用方法。

傳出請求攜帶調用者發送請求所需的所有信息:

  • 目標服務的服務地址service address
  • 調用此服務的操作名稱
  • 請求字段
  • 請求的有效負載

傳出請求還包含功能features。這些功能用於該管道內的本地通信;它們還用於管道中的調用者和應用程序代碼之間的通信。

請求字段

請求字段表示由"傳輸連接"的請求承載的帶外信息". 這些字段通常由攔截器和中間件讀取和寫入,以協調客戶端和服務器中相同請求的處理。

字段是字節序列的字典 RequestFieldKey 中的條目,其中 RequestFieldKeySlice 中定義的枚舉:

unchecked enum RequestFieldKey : varuint62 {
    Context = 0
    TraceContext = 1
    CompressionFormat = 2
    Deadline = 3
    Idempotent = 4
}

例如,當壓縮攔截器壓縮傳出請求的有效負載時,它設置請求字段CompressionFormat。這告訴連接另一側的壓縮中間件"該有效負載是用 brotli 壓縮的";然後壓縮中間件可以解壓縮該(傳入)請求有效負載。

請求有效負載和繼續有效負載Payload

請求的有效負載是表示操作參數的字節流。 當連接發送請求時,它會讀取這些字節並將其邏輯複製到網絡連接,直到不再有字節需要讀取。

另一方面,連接從網絡讀取這些字節,創建傳入請求並將此請求提供給調度器 dispatcher

傳出請求的有效負載實際上分爲兩部分:連接在等待響應之前發送的第一部分,以及連接在等待、接收和返回響應時在後臺發送的第二部分("繼續")。

sequenceDiagram Local-)Remote: request header + payload par Remote--)Local: response header + payload and Local-)Remote: request payload continuation end

另一方面,調度器僅看到單個連續的傳入請求有效負載。

請求功能

調用管道中的調用者在調用期間相互傳輸信息是很常見的。 例如,重試攔截器需要與連接緩存通信,以確保連接緩存不會繼續使用相同的服務器地址重試。C# 中,這些調用者獲取並設置請求的 IFeatureCollection 以相互通信。

還可以使用這些功能與調用管道進行通信。例如,您可以設置功能 ICompressFeature 以要求壓縮機攔截器(如果已安裝)壓縮請求的有效負載:

using var request = new OutgoingRequest(serviceAddress)
{
    Payload = largePayload,
    Features = new FeatureCollection().With<ICompressFeature>(CompressFeature.Compress)
};

// Hopefully invoker is an invocation pipeline with a compressor interceptor.
IncomingResponse response = await invoker.InvokeAsync(request);

按照慣例,這些功能是使用接口類型進行管控的,例如上面示例中的 ICompressFeature

字段用於"傳輸連接"進行通信,而特徵用於調用管道內的本地通信。IceRPC同時提供請求字段(由請求承載)和響應字段(由響應承載),但只提供請求特性:由於它都是本地的,因此不需要響應特性。

作者結語

  • 一直做,不停做,才能提升速度
  • 翻譯的不好,請手下留情,謝謝
  • 如果對我有點小興趣,如可加我哦,一起探討人生,探討道的世界
  • 覺得還不錯的話,點個
    image
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章