簡體   English   中英

在 Net Core 3.0 中同時使用 GRPC 通道

[英]An using GRPC Channel concurrently in Net Core 3.0

根據文檔,gRPC 客戶端是從通道創建的。 可以從一個通道創建多個具體的 gRPC 客戶端,包括不同類型的客戶端,但我沒有找到任何有關並發的信息。

所以,我的問題是,我可以使用該通道進行如下並發呼叫嗎?

var channel = GrpcChannel.ForAddress("https://localhost:5001");

// the first task
Task.Run(() => {
     var client = new Greet.GreeterClient(channel);
     var response = await client.SayHelloAsync(new HelloRequest { Name = "World" });

     Console.WriteLine("Greeting: " + response.Message); 
 });
// the second task
Task.Run(() => {
     var client = new Greet.GreeterClient(channel);
     var response = await client.SayHelloAsync(new HelloRequest { Name = "World" });

     Console.WriteLine("Greeting: " + response.Message); 
 });

或者我需要為每個線程(任務)創建自己的通道。

正如@Mike 所指出的,GrpcChannel 在后台使用 HttpClient。 因此,根據這個,我們可能可以創建單個 http 客戶端並在應用程序的整個生命周期中重用它。

HttpClient 旨在被實例化一次並在應用程序的整個生命周期中重復使用。

我已經建立了一個簡單的示例來調查該區域。

GRPS服務:

public class GreeterService
    : Greeter.GreeterBase
{
    private readonly ILogger<GreeterService> _logger;
    public GreeterService(ILogger<GreeterService> logger)
    {
        _logger = logger;
    }

    //Server side handler of the SayHello RPC
    public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
    {
        _logger.LogInformation($"Sending hello to {request.Name}");
        Thread.Sleep(500);
        return Task.FromResult(new HelloReply { Message = "Hello " + request.Name });
    }
}

所有線程的單一通道

        string uri = $"https://localhost:5001";

        var channel = GrpcChannel.ForAddress(uri, new GrpcChannelOptions()
        {
            HttpClient = HttpClientFactory.Create(),
            DisposeHttpClient = true
        });

        int threadCount = 6;
        Thread[] threads = new Thread[threadCount];

        for(int i = 0; i < threadCount; ++i)
        {
            threads[i] = new Thread((index) =>
            {
                Console.WriteLine($"Thread({(int)index}) has been started!");
                for (int req = 0; req < 75; ++req)
                {
                    var client = new Greeter.GreeterClient(channel);
                    client.SayHello(new HelloRequest()
                    {
                        Name = $"Thread {(int)index}"
                    });
                }

                Console.WriteLine($"Thread({(int)index}) has been finished!");
            });
        }

        for (int i = 0; i < threadCount; ++i)
        {
            threads[i].Start(i);
        }

        for (int i = 0; i < threadCount; ++i)
        {
            threads[i].Join();
        }

每個線程都有自己的頻道

        string uri = $"https://localhost:5001";

        int threadCount = 6;
        Thread[] threads = new Thread[threadCount];

        for(int i = 0; i < threadCount; ++i)
        {
            threads[i] = new Thread((index) =>
            {
                var channel = GrpcChannel.ForAddress(uri, new GrpcChannelOptions()
                {
                    HttpClient = HttpClientFactory.Create(),
                    DisposeHttpClient = true
                });

                Console.WriteLine($"Thread({(int)index}) has been started!");
                for (int req = 0; req < 75; ++req)
                {
                    var client = new Greeter.GreeterClient(channel);
                    client.SayHello(new HelloRequest()
                    {
                        Name = $"Thread {(int)index}"
                    });
                }

                Console.WriteLine($"Thread({(int)index}) has been finished!");
            });
        }

        Thread.Sleep(1000 * 10);

        for (int i = 0; i < threadCount; ++i)
        {
            threads[i].Start(i);
        }

        for (int i = 0; i < threadCount; ++i)
        {
            threads[i].Join();
        }

總結,我可以得出一個結論,我們可以創建一個單一的 GRPC 通道並在應用程序中重用它。 但我不知道使用一個渠道處理多個請求的效果如何

我看到這個問題得到了回答,但我想補充一點,文檔中有關於客戶端並發的部分。 如果有人新閱讀了這個問題,我希望這會有所幫助。

微軟文檔

.NET Core 上的 gRPC 介紹

關於gRPC 性能和實踐的“重用 gRPC 通道”一章。

通道可以安全地在 gRPC 調用之間共享和重用:

  • gRPC 客戶端是使用通道創建的。 gRPC 客戶端是輕量級對象,不需要緩存或重用。
  • 可以從一個通道創建多個 gRPC 客戶端,包括不同類型的客戶端。
  • 一個通道和從通道創建的客戶端可以被多個線程安全地使用。
  • 從通道創建的客戶端可以同時進行多個調用。

連接並發”一章對這個主題也很有幫助。

注意:查看主題配置以配置服務和客戶端通道。

gRPC API 文檔

命名空間 Grpc.Net.Client

GrpcChannel

表示一個 gRPC 通道。 通道是與遠程服務器的長期連接的抽象。 客戶端對象可以重用相同的通道。 與調用遠程調用相比,創建通道是一項昂貴的操作,因此通常您應該為盡可能多的調用重用單個通道。

gRPC 文檔

沒有關於客戶端並發的細節,但核心概念主題也非常有幫助,讓我們了解 gRPC 在底層是如何工作的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM