一、为什么选择gRPC和DotNetCore的组合

在现代分布式系统中,服务之间的通信效率直接影响整体性能。gRPC是一个高性能的RPC框架,基于HTTP/2协议,支持双向流和低延迟通信。而DotNetCore凭借其跨平台、高性能的特性,成为构建微服务的理想选择。

举个例子,假设我们需要在电商系统中实现订单服务和库存服务的高频数据交互。传统的REST API可能因为HTTP/1.1的文本传输和多次握手显得笨重,而gRPC的二进制协议和复用连接能显著提升效率。

技术栈:DotNetCore 6.0 + gRPC

// 订单服务Proto定义(Protobuf)
syntax = "proto3";
service OrderService {
  rpc CreateOrder (OrderRequest) returns (OrderResponse);
}
message OrderRequest {
  int32 product_id = 1;
  int32 quantity = 2;
}
message OrderResponse {
  bool success = 1;
  string order_id = 2;
}

二、如何搭建基础通信框架

1. 服务端实现

首先通过NuGet安装Grpc.AspNetCore包,然后定义服务实现:

// DotNetCore服务端示例
public class OrderServiceImpl : OrderService.OrderServiceBase {
  public override Task<OrderResponse> CreateOrder(
      OrderRequest request, ServerCallContext context) {
    // 模拟订单创建逻辑
    return Task.FromResult(new OrderResponse { 
      Success = true, 
      OrderId = Guid.NewGuid().ToString() 
    });
  }
}

// Program.cs配置
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddGrpc();
var app = builder.Build();
app.MapGrpcService<OrderServiceImpl>();
app.Run();

2. 客户端调用

客户端同样需要Proto文件,并通过通道复用提升性能:

// DotNetCore客户端示例
var channel = GrpcChannel.ForAddress("https://localhost:5001");
var client = new OrderService.OrderServiceClient(channel);
var response = await client.CreateOrderAsync(new OrderRequest {
  ProductId = 123,
  Quantity = 2
});
Console.WriteLine($"订单创建结果: {response.Success}");

三、性能优化实战技巧

1. 连接复用

gRPC的Channel本质是HTTP/2长连接,应该全局单例:

// 最佳实践:使用静态Channel
private static readonly GrpcChannel _channel = 
    GrpcChannel.ForAddress("https://api.example.com");

2. 流式处理

适合实时日志推送等场景:

// Proto定义流式接口
service LogService {
  rpc StreamLogs (stream LogMessage) returns (LogSummary);
}
// 客户端流式调用示例
using var call = logClient.StreamLogs();
foreach (var log in GenerateLogs()) {
  await call.RequestStream.WriteAsync(log);
}
await call.RequestStream.CompleteAsync();

四、避坑指南与场景适配

1. 不适合的场景

  • 需要浏览器直接调用的API(gRPC-Web有额外限制)
  • 传输超大文件(建议分块或专用文件服务)

2. 常见问题解决

问题: NAT环境下连接失败
方案: 使用gRPC健康检查+负载均衡:

// 健康检查配置
builder.Services.AddGrpcHealthChecks();
app.MapGrpcHealthChecksEndpoint();

五、总结与选型建议

gRPC在内部微服务通信中表现优异,尤其适合:

  • 高频数据交换(如物联网设备上报)
  • 需要强类型约束的跨语言调用
  • 低延迟要求的实时系统

但对于简单CRUD场景,REST可能更快速上手。建议根据团队技术栈和具体需求权衡。