Share via


gRPC と Unix ドメイン ソケットを使ったプロセス間通信

作成者: James Newton-King

.NET では、gRPC を使用したプロセス間通信 (IPC) がサポートされています。 gRPC を使用したプロセス間通信を開始する方法について詳しくは、「gRPC を使用したプロセス間通信」を参照してください。

Unix ドメイン ソケット (UDS) は、クライアントとサーバーが同じマシン上にある場合に TCP よりも効率的な、広くサポートされている IPC トランスポートです。 この記事では、UDS 経由で gRPC 通信を構成する方法について説明します。

前提条件

サーバー構成

Unix ドメイン ソケットは Kestrel でサポートされており、これは Program.cs で構成されます。

var socketPath = Path.Combine(Path.GetTempPath(), "socket.tmp");

var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ListenUnixSocket(socketPath, listenOptions =>
    {
        listenOptions.Protocols = HttpProtocols.Http2;
    });
});

上記の例の場合:

  • Kestrelで ConfigureKestrel のエンドポイントを構成します。
  • 指定されたパスを使用して UDS をリッスンするために、ListenUnixSocket を呼び出します。
  • HTTPS を使用するように構成されていない UDS エンドポイントを作成します。 HTTPS を有効にする方法については、Kestrel HTTPS エンドポイントの構成に関する記事を参照してください。

クライアントの構成

GrpcChannel では、カスタム トランスポート経由での gRPC 呼び出しがサポートされます。 チャネルが作成されると、カスタムの ConnectCallback がある SocketsHttpHandler で構成できます。 コールバックを使用すると、クライアントはカスタム トランスポート経由で接続を確立し、そのトランスポートを介して HTTP 要求を送信できます。

Note

クライアント側負荷分散やチャネル状態など、GrpcChannel の一部の接続機能は、Unix ドメイン ソケットと一緒に使用することはできません。

Unix ドメイン ソケットの接続ファクトリの例:

public class UnixDomainSocketsConnectionFactory
{
    private readonly EndPoint endPoint;

    public UnixDomainSocketsConnectionFactory(EndPoint endPoint)
    {
        this.endPoint = endPoint;
    }

    public async ValueTask<Stream> ConnectAsync(SocketsHttpConnectionContext _,
        CancellationToken cancellationToken = default)
    {
        var socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified);

        try
        {
            await socket.ConnectAsync(this.endPoint, cancellationToken).ConfigureAwait(false);
            return new NetworkStream(socket, true);
        }
        catch
        {
            socket.Dispose();
            throw;
        }
    }
}

カスタム接続ファクトリを使用してチャネルを作成する場合:

public static readonly string SocketPath = Path.Combine(Path.GetTempPath(), "socket.tmp");

public static GrpcChannel CreateChannel()
{
    var udsEndPoint = new UnixDomainSocketEndPoint(SocketPath);
    var connectionFactory = new UnixDomainSocketsConnectionFactory(udsEndPoint);
    var socketsHttpHandler = new SocketsHttpHandler
    {
        ConnectCallback = connectionFactory.ConnectAsync
    };

    return GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions
    {
        HttpHandler = socketsHttpHandler
    });
}

上記のコードを使用して作成されたチャネルの場合、Unix ドメイン ソケット経由で gRPC 呼び出しが送信されます。