使用 gRPC 和 Unix 域套接字进行进程间通信
注意
此版本不是本文的最新版本。 有关当前版本,请参阅本文的 .NET 9 版本。
警告
此版本的 ASP.NET Core 不再受支持。 有关详细信息,请参阅 .NET 和 .NET Core 支持策略。 对于当前版本,请参阅此文的 .NET 8 版本。
.NET 支持使用 gRPC (IPC) 进行进程间通信 (IPC)。 有关开始使用 gRPC 在进程之间进行通信的详细信息,请参阅使用 gRPC 进行进程间通信。
Unix 域套接字 (UDS) 是一种广泛受支持的 IPC 传输技术,当客户端和服务器位于同一台计算机上时,它比 TCP 更有效。 本文讨论如何通过 UDS 配置 gRPC 通信。
先决条件
- .NET 5 或更高版本
- Linux、macOS 或 Windows 10/Windows Server 2019 或更高版本
服务器配置
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;
});
});
上面的示例:
- 在 ConfigureKestrel 中配置 Kestrel 的终结点。
- 调用 ListenUnixSocket 来侦听具有指定路径的 UDS。
- 创建未配置为使用 HTTPS 的 UDS 终结点。 有关启用 HTTPS 的信息,请参阅 Kestrel HTTPS 终结点配置。
客户端配置
GrpcChannel
支持通过自定义传输进行 gRPC 调用。 创建通道后,可以使用包含自定义 ConnectCallback 的 SocketsHttpHandler 来配置它。 回调允许客户端通过自定义传输建立连接,然后通过该传输发送 HTTP 请求。
注意
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 调用。