背景
目前正在参与一个现有 .NET 系统的改造项目。
该系统整体基于 .NET Framework 开发,由于系统中存在大量子应用,因此各子系统之间长期通过 .NET Remoting 进行通信。
随着项目的持续迭代,原有的技术架构逐渐暴露出一些问题:
- .NET Remoting 已停止维护
- 技术生态逐渐老旧
- 跨语言支持能力较弱
- 前后端分离改造困难
- 不利于后续微服务化扩展
与此同时,客户希望将部分面向用户的子应用改造为 Angular 前端,以提升系统的可维护性与用户体验。
因此,本次改造中,一个核心任务便是:
将原有基于 .NET Remoting 的系统间通信,逐步迁移为基于 gRPC 的通信方案。
那么接下来我们来了解一下 gRPC 吧。
与 .NET Remoting 的比较
下面是通过网络了解到的 .NET Remoting 和 gRPC 的一些方面的比较,用以说明为什么这个项目要将 .NET Remoting 的接口迁移为基于 gRPC 的接口。
| 对比项 | .NET Remoting | gRPC |
|---|---|---|
| 定位 | 早期 .NET 远程对象调用技术 | 现代高性能 RPC 框架 |
| 时代 | .NET Framework 时代 | 云原生、微服务时代 |
| 是否推荐新项目使用 | 不推荐 | 推荐 |
| 官方支持情况 | 已基本淘汰,.NET Core/.NET 5+ 不支持 | 主流支持,.NET 现代版本可用 |
| 主要用途 | .NET 程序之间远程调用对象 | 服务之间高性能通信 |
| 跨语言能力 | 很弱,基本限于 .NET | 很强,支持 C#、Java、Go、Python、Node.js 等 |
| 跨平台能力 | 弱,主要依赖 Windows/.NET Framework | 强,支持 Windows、Linux、macOS |
| 通信方式 | 像调用远程对象一样调用方法 | 通过 .proto 定义服务和消息 |
| 协议 | TCP / HTTP 等 | HTTP/2 |
| 数据格式 | BinaryFormatter / SOAP 等 | Protocol Buffers |
| 性能 | 当年还可以,但现在不占优势 | 高性能,序列化体积小 |
| 类型安全 | 有,但强依赖 .NET 类型 | 强类型,通过 proto 生成代码 |
| 配置复杂度 | 较高,配置和部署麻烦 | 中等,需要写 proto,但结构清晰 |
| 微服务适配 | 不适合现代微服务 | 非常适合 |
| 云原生适配 | 差 | 好 |
| 浏览器直接调用 | 不适合 | 原生 gRPC 浏览器支持有限,但可用 gRPC-Web |
| 双向流 | 不方便 | 原生支持客户端流、服务端流、双向流 |
| 负载均衡 | 不友好 | 更适合现代服务治理体系 |
| 安全性 | 老旧,存在较多历史包袱 | 支持 TLS,生态更现代 |
| 学习成本 | 对老 .NET 程序员较低,但资料旧 | 需要学习 proto、HTTP/2、服务定义 |
| 维护成本 | 高 | 较低 |
| 典型场景 | 老系统、遗留项目维护 | 微服务、跨语言系统、高性能内部通信 |
| 替代方案 | WCF、Web | API、gRPC REST API、消息队列、SignalR |
| 当前建议 | 只在维护老项目时了解 | 新项目可以重点学习 |
gRPC 概述
在 gRPC 中,客户端应用程序可以直接调用位于不同机器上的服务器应用程序的方法,就像调用本地对象一样,这使得创建分布式应用程序和服务变得更加容易。与许多 RPC 系统一样,gRPC 的核心思想是定义服务,并指定可以远程调用的方法及其参数和返回类型。在服务器端,服务器实现此接口并运行 gRPC 服务器来处理客户端调用。在客户端,客户端有一个存根(在某些语言中简称为客户端),它提供与服务器相同的方法。

环境准备
目前 gRPC 对主流开发语言都已经提供了较为完善的支持,因此整体环境搭建并不复杂。
以 .NET 为例,通常只需要:
- 安装较新的 .NET SDK
- 引入对应的 gRPC NuGet 包
- 配置 ASP.NET Core gRPC 服务
- 编写 proto 文件
即可快速开始开发。
而如果是浏览器端(例如 Angular)调用 gRPC,则通常还需要额外使用:
- gRPC-Web
- Envoy
- ASP.NET Core gRPC-Web
等方案进行支持。
后续我们也会进一步介绍如何在实际项目中搭建完整的 gRPC 开发环境。
创建服务
在 proto 文件中定义 gRPC 服务,其中 RPC 方法参数和返回类型指定为协议缓冲区消息:
1 | // 定义一个 Greeter 服务 |
gRPC 使用一个特殊的 gRPC 插件 protoc ,从 proto 文件生成代码:从而获得生成的 gRPC 客户端和服务端代码,以及定义的各个用于传入和返回的类。gRPC 官方文档
gRPC 服务
我们了解了 gRPC 是如何创建一个服务的,那么接下来我们展开来了解一下 gRPC 一共为我们提供了哪些类型的服务吧。
gRPC 一共为我们提供了四种不同类型的服务,分别是一对一、一对多、多对多和多对一的消息发送模式。后续我们将一一讲解如何创建和使用各种模式。
一对一
一对一的模式允许客户端向服务端发送一个请求,并且收到一个响应,这是最基础,也是最常见的方式。
proto 定义:
1 | service xxx { |
一对多
一对多的模式允许客户端向服务端发送一个请求,并且会与服务端保持连接,从而能够从服务端获取多条响应信息,可以将其看作向服务端发起了一个订阅,然后服务端可以一直向订阅者推送消息。
proto 定义:
1 | service xxx { |
多对多
多对多的模式允许客户端在与服务端建立连接以后,向服务端推送多条消息,同时也允许服务端向客户端返回多条消息
proto 定义:
1 | service xxx { |
多对一
多对一的模式允许在与服务端建立连接以后,客户端多次向服务端发送消息,但是服务端只会在客户端告知所有消息发送结束后,返回一条消息到客户端
proto 定义:
1 | service xxx { |
总结
本文主要结合当前项目的改造背景,初步了解了 gRPC 的基本概念以及其与 .NET Remoting 之间的差异。
相比已经逐渐退出历史舞台的 .NET Remoting,gRPC 在性能、跨语言支持、微服务适配以及现代化生态方面都具备更加明显的优势,这也是当前越来越多项目选择使用 gRPC 的重要原因。
同时,我们也初步了解了 gRPC 中最核心的几个概念:
- proto 文件
- 服务定义
- 四种通信模式
其中,gRPC 提供的:
- 一对一
- 一对多
- 多对一
- 多对多
四种通信方式,使其能够很好地适配不同场景下的服务通信需求。
不过,目前本文更多还是停留在概念层面,后续还需要进一步学习:
- 如何创建真正的 gRPC 服务
- 如何实现客户端与服务端通信
- gRPC-Web 的使用
- 认证与权限控制
- 异常处理
- 流式通信实践
- 性能优化
后续我也会继续记录整个项目中关于 gRPC 改造过程中的学习与踩坑内容。
说些什么吧!