ASP.NET Core: Giao tiếp giữa các tiến trình với gRPC
Trong bài viết này
Các tiến trình chạy trên cùng một máy có thể được thiết kế để giao tiếp với nhau. Hệ điều hành cung cấp các công nghệ cho phép giao tiếp giữa các tiến trình (Inter-Process Communication - IPC) nhanh chóng và hiệu quả. Các ví dụ phổ biến về công nghệ IPC là socket tên miền Unix và đường ống Named.
.NET cung cấp hỗ trợ giao tiếp giữa các tiến trình bằng gRPC.
Ghi chú
Hỗ trợ tích hợp cho các đường ống được đặt tên trong ASP.NET Core yêu cầu .NET 8 trở lên.
Để biết thêm thông tin, hãy xem phiên bản .NET 8 trở lên của chủ đề này
Bắt đầu
Các lời gọi gRPC được gửi từ máy khách đến máy chủ. Để giao tiếp giữa các ứng dụng trên máy có gRPC, ít nhất một ứng dụng phải lưu trữ máy chủ gRPC ASP.NET Core.
ASP.NET Core và gRPC có thể được lưu trữ trong bất kỳ ứng dụng nào sử dụng .NET Core 3.1 trở lên bằng cách thêm framework Microsoft.AspNetCore.App
vào dự án.
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Grpc.AspNetCore" Version="2.47.0" />
<Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
</ItemGroup>
</Project>
Tệp dự án trên:
- Thêm tham chiếu framework vào
Microsoft.AspNetCore.App
. Tham chiếu framework cho phép các ứng dụng không phải ASP.NET Core, chẳng hạn như Dịch vụ Windows, ứng dụng WPF hoặc ứng dụng WinForms sử dụng ASP.NET Core và lưu trữ máy chủ ASP.NET Core. - Thêm tham chiếu gói NuGet vào Grpc.AspNetCore.
- Thêm một file
.proto
.
Định cấu hình socket tên miền Unix
Các lời gọi gRPC giữa máy khách và máy chủ trên các máy khác nhau thường được gửi qua socket TCP. TCP được thiết kế để liên lạc qua mạng. Socket miền Unix (UDS) là công nghệ IPC được hỗ trợ rộng rãi, hiệu quả hơn TCP khi máy khách và máy chủ ở trên cùng một máy. .NET cung cấp hỗ trợ tích hợp cho UDS trong ứng dụng máy khách và máy chủ.
Yêu cầu:
- .NET 5 trở lên
- Linux, macOS hoặc Windows 10/Windows Server 2019 trở lên
Cấu hình máy chủ
Socket tên miền Unix (UDS) được hỗ trợ bởi Kestrel, được định cấu hình trong Program.cs
:
public static readonly string SocketPath = Path.Combine(Path.GetTempPath(), "socket.tmp");
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
webBuilder.ConfigureKestrel(options =>
{
if (File.Exists(SocketPath))
{
File.Delete(SocketPath);
}
options.ListenUnixSocket(SocketPath, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http2;
});
});
});
Ví dụ trên:
- Định cấu hình điểm cuối của Kestrel trong
ConfigureKestrel
. - Gọi ListenUnixSocket để nghe UDS với đường dẫn đã chỉ định.
- Tạo điểm cuối UDS không được định cấu hình để sử dụng HTTPS. Để biết thông tin về cách bật HTTPS, hãy xem Cấu hình điểm cuối HTTPS của Kestrel.
Cấu hình máy khách
GrpcChannel
hỗ trợ thực hiện lời gọi gRPC qua các phương thức truyền tải (transport) tùy chỉnh. Khi một kênh được tạo, nó có thể được định cấu hình bằng một SocketsHttpHandler
có ConnectCallback
tùy chỉnh. Lệnh gọi lại cho phép máy khách tạo kết nối qua các phương thức truyền tải tùy chỉnh và sau đó gửi các yêu cầu HTTP qua phương thức truyền tải đó.
Ví dụ về factory kết nối socket tên miền Unix:
public class UnixDomainSocketConnectionFactory
{
private readonly EndPoint _endPoint;
public UnixDomainSocketConnectionFactory(EndPoint endPoint)
{
_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(_endPoint, cancellationToken).ConfigureAwait(false);
return new NetworkStream(socket, true);
}
catch
{
socket.Dispose();
throw;
}
}
}
Sử dụng factory kết nối tùy chỉnh để tạo kênh:
public static readonly string SocketPath = Path.Combine(Path.GetTempPath(), "socket.tmp");
public static GrpcChannel CreateChannel()
{
var udsEndPoint = new UnixDomainSocketEndPoint(SocketPath);
var connectionFactory = new UnixDomainSocketConnectionFactory(udsEndPoint);
var socketsHttpHandler = new SocketsHttpHandler
{
ConnectCallback = connectionFactory.ConnectAsync
};
return GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions
{
HttpHandler = socketsHttpHandler
});
}
Các kênh được tạo bằng đoạn code trên sẽ gửi lệnh gọi gRPC qua socket miền Unix. Hỗ trợ cho các công nghệ IPC khác có thể được triển khai bằng khả năng mở rộng trong Kestrel và SocketsHttpHandler
.