Giao tiếp liên tiến trình với gRPC và Unix domain sockets
.NET hỗ trợ giao tiếp liên tiến trình (IPC - inter-process communication) sử dụng gRPC. Để biết thêm thông tin về cách bắt đầu sử dụng gRPC để giao tiếp giữa các tiến trình, xem Giao tiếp liên tiến trình với gRPC.
Unix domain sockets (UDS) là một transport (giao thức truyền tải) IPC được hỗ trợ rộng rãi, hiệu quả hơn TCP khi client và server nằm trên cùng một máy. Bài viết này trình bày cách cấu hình giao tiếp gRPC qua UDS.
Yêu cầu tiên quyết
- .NET 5 hoặc mới hơn
- Linux, macOS, hoặc Windows 10/Windows Server 2019 trở lên
Cấu hình server
Unix domain sockets được hỗ trợ bởi Kestrel, được cấu hình trong 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;
});
});Ví dụ trên:
- Cấu hình các endpoint của Kestrel trong
ConfigureKestrel. - Gọi
ListenUnixSocketđể lắng nghe trên một UDS với đường dẫn đã chỉ định. - Tạo một UDS endpoint không được cấu hình để dùng HTTPS. Để biết thông tin về kích hoạt HTTPS, xem Cấu hình HTTPS endpoint của Kestrel.
Cấu hình client
GrpcChannel hỗ trợ thực hiện các gRPC call qua các transport tùy chỉnh. Khi một channel được tạo, nó có thể được cấu hình với một SocketsHttpHandler có ConnectCallback tùy chỉnh. Callback này cho phép client thực hiện kết nối qua các transport tùy chỉnh và sau đó gửi các HTTP request qua transport đó.
Lưu ý: Một số tính năng kết nối của GrpcChannel, như client side load balancing (cân bằng tải phía client) và channel status (trạng thái channel), không thể sử dụng cùng với Unix domain sockets.
Ví dụ về Unix domain sockets connection factory (nhà máy kết nối):
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;
}
}
}Sử dụng custom connection factory để tạo channel:
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
});
}Các channel được tạo bằng code trên sẽ gửi các gRPC call qua Unix domain sockets.