1. 什么是RPC
RPC全称为Remote Procedure Call ,远程过程调用,与之对应的是本地调用。
本地调用
运行在同一个程序里,A方法调用B方法,不涉及网络传输。

C#
static async Task Main(string[] args)
{
OutputPage(1,10);
Payment();
Order();
}
static void OutputPage(int pageIndex,int pageSize)
{
using BookDbContext dbContext = new BookDbContext();
IQueryable<Book> books = dbContext.Books.Where(b=>!b.Title!.Contains("张三"));
//总条数
long count = books.LongCount();
//页数
long pageCount = (long)Math.Ceiling(count*1.0/pageSize);
Console.WriteLine("页数"+pageCount);
var pagedBooks = books.Skip((pageIndex-1)*pageSize).Take(pageSize);
foreach (var book in pagedBooks)
{
Console.WriteLine(book.ID+","+book.Title);
}
}
远程调用
- 常规HTTP调用
C#
using HttpClient client = new();
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/vnd.github.v3+json"));
client.DefaultRequestHeaders.Add("User-Agent", ".NET Foundation Repository Reporter");
await ProcessRepositoriesAsync(client);
- RPC调用
RPC的本质来说就是让你在调用的时候,看上去就像在调用本地方法,而不是走常规的HTTP调用方式

在订单服务中注册一个Payment的Client,建立一个请求RPC连接,实现远程调用。
ASP.NET Core gRPC 服务项目模板提供了一个入门版服务:
C#
public class GreeterService : Greeter.GreeterBase
{
private readonly ILogger<GreeterService> _logger;
public GreeterService(ILogger<GreeterService> logger)
{
_logger = logger;
}
public override Task<HelloReply> SayHello(HelloRequest request,
ServerCallContext context)
{
_logger.LogInformation("Saying hello to {Name}", request.Name);
return Task.FromResult(new HelloReply
{
Message = "Hello " + request.Name
});
}
}
使用RPC的目的:使开发者感受不到远程调用和本地调用的区别,感觉就像在调用同一个项目里的方法。
2. 一个完整的RPC总共分几步
桩文件=>序列号=>TCP
- 函数映射:静态代理,生成stub文件
- 对比建立HTTP请求连接,RPC在编写代码时,降低了复杂度
- stub文件让远程调用看上去像是本地调用
- 序列化
- JSON明文传输
- gRPC以protobuf作为序列化协议
- 网络传输
- 自定义RPC协议实现通信,大厂几乎都用自定义RPC框架去自定义RPC协议
- 使用成熟的网络库,实现多路复用,可靠传输