文章目录
- 1. RPC的概述
- 2. RPC的核心工作原理
- 3. RPC与 HTTP 的区别
- 4. RPC 框架的核心功能
- 5. 常见的RPC框架对比
- 6. 什么时候考虑引入RPC
- 7. 选型
- 8. Dubbo
- 1)概述
- 2. Dubbo核心功能
- 3. Dubbo 具体使用
1. RPC的概述
RPC(Remote Procedure Call,远程过程调用)是分布式系统的核心基础,是一种编程模型。 简单说,它让你像调用本地方法一样,去调用另一台服务器上的代码。
2. RPC的核心工作原理
1)代理:框架为接口动态生成一个代理类,调用方法的时候,实际调用的是代理。 2)序列化:把方法名、参数等转成字节流(如 Hessian、Protobuf、JSON)。 3)网络传输:通过 TCP 或 HTTP 把字节流发给服务端。 4)反序列化:服务端把字节流还原成方法名和参数。 5)执行:找到真正的实现类,调用方法。 6)返回:结果再按同样的路径返回。
3. RPC与 HTTP 的区别
![]()
4. RPC 框架的核心功能
1)服务注册与发现 a. 服务启动时自动向注册中心(Zookeeper、Nacos)注册。 b. 调用方从注册中心动态获取服务地址,不写死 IP。 2) 负载均衡 分布式系统中将请求/任务分摊到多个服务器上执行的机制。常用的策略有:随机、轮询等。 核心目标:避免单点过载、提升整体吞吐量和系统可用性。 随机:从可用服务器列表中随机选择一个,请求量足够大时,各服务器被选中的比例接近 1 : 1 : ...,默认随机。 轮询:请求按顺序轮流分配给每台服务器。改进版:加权轮询。 3) 集群容错 在分布式系统中,当服务消费者调用服务提供者失败时(如网络超时、服务提供者宕机),系统根据预设的策略来处理这次失败,以保证整个应用的稳定性或可用性。常用的策略有:失败重试、快速失败等。 失败重试:当调用某台服务器失败后,自动从可用服务器列表中剔除该节点,并重新选择一个节点重试。通常会设置一个重试次数(如 retries=2,表示最多重试2次,共3次尝试)。【关键注意事项:要求业务操作是幂等的】 快速失败:只发起一次调用,如果失败立即抛出异常,不做任何重试,最安全。 4) 协议与序列化 可切换协议(Dubbo协议、HTTP、gRPC)。 可切换序列化(Hessian2、Protobuf、JSON、Kryo)。 5) 流量治理 路由规则(只调用指定机房的机器)。 降级、限流、超时控制。
5. 常见的RPC框架对比
![]()
6. 什么时候考虑引入RPC
1)服务数量超过 5-10 个,手动管理调用地址已很痛苦。 2)对性能有一定要求(QPS > 1000,内部调用)。 3)需要动态扩缩容,服务节点经常变化。 4)希望统一管理超时、重试、熔断。
7. 选型
1)如果你是Go、Python、C++等多语言团队,或者需要构建对外公开的API:gRPC 是你的不二之选。它是云原生时代的事实标准,与Kubernetes、Service Mesh(服务网格)等基础设施配合得天衣无缝。 2)如果你是Java团队,追求极致的性能和全面的服务治理能力,并且希望方案更轻量:Dubbo 是非常成熟的选择。它在国内有海量的实践案例,尤其适合大规模、复杂的微服务场景。特别是Dubbo 3.x引入的Triple协议,已经很好地解决了跨语言和多协议互通的问题。 3)如果你的团队以Spring Boot为主,希望获得从配置到监控的一站式体验,对性能要求不那么极致:直接使用 Spring Cloud 全家桶是最省心的。它强大的生态和便利性,使其成为企业级应用开发的主流选择。 4)如果你需要构建一个对性能要求达到极致,并且涉及多种编程语言的高性能计算系统:Apache Thrift 值得考虑。虽然它的学习曲线和社区活跃度不如gRPC,但在纯性能场景下,它依然非常强大。
8. Dubbo
1)概述
Dubbo 是一个由阿里巴巴开源、后进入 Apache 基金会的高性能、面向微服务的 Java RPC 框架。
2. Dubbo核心功能
1) 服务发现与注册 服务启动时自动向注册中心(如 Zookeeper、Nacos)注册自己的地址和提供的接口,调用方从注册中心动态获取服务地址,无需硬编码 IP 和端口。 2)高性能 RPC 通信 默认使用自有的、基于 TCP 的高性能协议(Dubbo 协议),比 HTTP 协议在内部网络环境中更轻量、更快。 3)服务治理 内置了负载均衡(如随机、轮询)、集群容错(如失败重试、快速失败、失败安全、失败自动恢复)、服务路由、流量控制等功能。 负载均衡:分布式系统中将请求/任务分摊到多个服务器上执行的机制。 核心目标:避免单点过载、提升整体吞吐量和系统可用性。 随机:从可用服务器列表中随机选择一个,请求量足够大时,各服务器被选中的比例接近 1 : 1 : ...,默认随机。 轮询:请求按顺序轮流分配给每台服务器。改进版:加权轮询。 集群容错:在分布式系统中,当服务消费者调用服务提供者失败时(如网络超时、服务提供者宕机),系统根据预设的策略来处理这次失败,以保证整个应用的稳定性或可用性。 核心原则:写操作慎重重试,读操作可以多试几次。 失败重试:当调用某台服务器失败后,自动从可用服务器列表中剔除该节点,并重新选择一个节点重试。通常会设置一个重试次数(如 retries=2,表示最多重试2次,共3次尝试)。【关键注意事项:要求业务操作是幂等的】 快速失败:只发起一次调用,如果失败立即抛出异常,不做任何重试,最安全。 典型场景: 1)写操作且非幂等:比如创建订单、转账。宁可失败,也不要重复执行。 2)对延迟极度敏感:比如用户快速滑动刷新,宁可显示失败让用户点一下“重试”,也不能让界面卡住几秒。 3)客户端有重试机制:比如前端页面已经有点击重试按钮,后端就不需要再自动重试了。
3. Dubbo 具体使用
1)定义服务接口: 在 API 模块中定义一个普通的 Java 接口,比如 UserService。这个接口被服务提供者和消费者共同依赖。 2)在提供者中实现,在消费者中引用: 服务提供者:实现 UserService 接口,并使用 @DubboService 注解标记这个实现类。Dubbo 启动后会将其发布为远程服务。 服务消费者:在需要调用该服务的地方,使用 @DubboReference 注解注入一个 UserService 类型的变量。Dubbo 会为其生成一个代理对象,你调用此对象的方法时,Dubbo 在背后完成了网络通信、参数序列化、结果反序列化等所有工作。 3)应对复杂场景:当接口有多个实现时 Dubbo 通过 分组(Group) 和 版本(Version) 来优雅解决。 group: 用于业务/逻辑隔离:同一个接口,给不同业务线或场景提供不同实现。 version: 用于服务升级:当接口需要不兼容升级时,可以发布 version="2.0" 的新服务,同时保留 version="1.0" 的老服务,消费者可以根据需要调用不同版本,实现平滑迁移。