分布式系统Dubbo
一、简介
1.Dubbo介绍
使用Maven 引入依赖:
<!-- Dubbo 依赖 --> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.7.6</version> </dependency> <!-- zookeeper 注册中心 依赖 --> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-registry-zookeeper</artifactId> <version>2.7.6</version> </dependency>
Dubbo 主要包括以下核心功能:
远程调用: 提供高性能的远程调用协议和序列化机制。
服务治理: 包括服务自动注册、发现、路由、降级和集群容错等。
负载均衡: 支持多种负载均衡策略,例如随机、轮询、一致性哈希等。
容错机制: 提供服务降级、超时处理、失败重试等容错机制。
分布式部署: 支持分布式部署,方便构建微服务架构。
分布式架构就是将一个完整的系统,按照业务功能,拆分成一个个独立的子系统。
在分布式结构中,每个子系统就被称为“服务”。这些子系统能够独立运行在web容器中,它们之间通过RPC方式通信。
- 系统之间的耦合度大大降低,可以独立开发、独立部署、独立测试,系统与系统之间的边界非常明确,排错也变得相当容易,开发效率大大提升。
- 系统之间的耦合度低使得系统更易于扩展。我们可以针对性地扩展某些服务。
RPC(Remote Procedure Call,远程过程调用)是一种通过网络从远程计算机上请求服务,而不需要了解底层网络细节的通信协议。
它允许像调用本地服务一样调用远程服务,使得分布式系统中的不同部分能够相互通信和协作。
在传统的本地过程调用(Local Procedure Call)中,调用过程与被调用过程在同一地址空间,它们直接共享相同的内存空间。
而在 RPC 中,调用过程和被调用过程可能运行在不同的机器上,通过网络进行通信。
RPC 的目标是让远程调用看起来像本地调用一样简单,对开发者屏蔽底层的网络通信细节。
RPC两个作用:
-
屏蔽远程调用跟本地调用的区别,让我们感觉就是调用项目内的方法
-
隐藏底层网络通信的复杂性,让我们更加专注业务逻辑。
常见 RPC 技术和框架:
-
阿里的 Dubbo/Dubbox。
-
Google gRPC。
-
Dubbo支持的协议
-
Dubbo协议
-
Hessian协议
-
HTTP协议
-
RMI协议
-
WebService协议
-
Memcached协议
-
Redis协议
推荐: 使用Dubbo协议
5. Dubbo核心组件
5.1 Registry 注册中心
在Dubbo微服务体系中,注册中心是其核心组件之一。Dubbo通过注册中心实现了分布式环境中各服务之间的注册与发现,是各个分布式节点之间的纽带。
- 动态加入:一个服务提供者通过注册中心可以动态地把自己暴露给其他消费者,无须消费者逐个去更新配置文件。
- 动态发现:一个消费者可以动态地感知新的配置、路由规则和新的服务提供者,无须重启服务使之生效。
- 动态调整:注册中心支持参数的动态调整,新参数自动更新到所有相关服务节点。
常见注册发现服务
-
zookeeper
-
eureka
-
nacos
-
consul
5.2 服务提供者Provider
服务的提供方
5.3 服务消费者 Consumer
调用远程服务的服务消费方
5.4 监控中心 Monitor
主要负责监控统计调用次数和调用时间等。
5.5 工作流程
-
服务提供者启动过程:
-
服务提供者启动时,会向注册中心注册自己提供的服务,包括服务接口、版本、分组等信息。
-
注册中心收到服务提供者的注册信息后,将其存储在本地,并定期将更新的服务信息同步到其他节点。
-
服务提供者还会定期从注册中心获取服务消费者的地址列表,以便后续的远程调用。
-
-
服务消费者启动过程:
-
服务消费者启动时,会向注册中心订阅自己感兴趣的服务,包括服务接口、版本、分组等信息。
-
注册中心收到服务消费者的订阅请求后,将匹配的服务提供者地址列表发送给服务消费者。
-
服务消费者根据获取的地址列表,建立与服务提供者的连接。
-
-
远程调用过程:
-
服务消费者根据负载均衡策略,选择一个合适的服务提供者进行远程调用。
-
通过 RPC 协议,服务消费者将请求消息发送给服务提供者。
-
服务提供者接收到请求消息后,解析出请求参数,然后调用本地对应的服务实现进行处理,并将结果通过 RPC 协议返回给服务消费者。
-
-
服务调用监控和管理:
-
Dubbo 支持对服务调用的性能、成功率、错误率等指标进行监控,方便管理员及时发现和解决问题。
-
Dubbo 还提供了丰富的服务治理能力,如动态配置、路由规则、限流熔断等,帮助开发者更好地管理和维护分布式系统。
-
-
服务下线和更新:
-
当服务提供者需要下线或更新服务时,可以向注册中心发送注销或更新通知。
-
注册中心收到通知后,会将其广播到其他节点,以便及时更新服务信息。
-
二、Docker高级特性
1. 序列化协议安全
由于网络传输的数据必须是二进制数据,但调用方请求的出入参数都是对象,所以需要对需要传输的数据进行序列化
2. 地址缓存
dubbo服务消费者在 第一次调用时 ,会将服务提供方地址缓存到本地 ,以后在调用则不会访问注册中心。
服务提供者地址发生变化时,注册中心会通服务消费者。
3. 超时机制
在某个峰值时刻,大呈的请求都在同时请求服务消费者,会造成线程的大呈堆积,势必会造成雪崩。
@Service(timeout = 3000)//3S超时 public class UserServiceImpl implements UserService
注意这个@Service注解不是spring提供的,而是dubbo提供的,标识当前类为服务提供者,并进行暴露。
服务消费者配置
@Reference(timeout = 2000)//2s超时 private UserService userService;
@Reference注解表示远程调用,会为表标识的接口生成代理对象,然后拦截实现类的方法进行远程调用。
3.3 超时覆盖
当双方都配置了超时时间,只要一方的超时时间更短就会覆盖另一方的配置。
超时是针对消费者而言的,但是提供者、消费者都可以配置超时时间
这其实是一种策略,其实服务端的超时配置是消费端的缺省配置,即如果服务端设置了超时,任务消费端可以不设置超时时间,简化了配置。
另外针对控制的粒度,Dubbo支持了接口级别也支持方法级别,可以根据不同的实际情况精确控制每个方法的超时时间。
因为生产者端更贴近业务实现,对超时时间的把握更准确,而消费者端更多的是调用服务,超时时间可以相对宽松一些。
同时,在配置超时时间时,需要考虑方法的实际执行时间、网络延迟等因素,避免超时时间设置过短导致调用失败。
4. 重试机制
Dubbo在调用服务时失败默认会重试 2 次,避免因网络抖动导致请求失败。
配置:
@Service(timeout = 3000,retries = 2)
5. 多版本
5.1 灰度发布(金丝雀发布)
当出现新功能时,会让一部分用户先使用新功能,用户反馈没问题时,再将所有用户迁移到新功能。
-
在低压力时间段,先升级一半提供者为新版本
-
再将所有消费者升级为新版本
-
6. 负载均衡
Dubbo是一个分布式服务框架,能避免单点故障和支持服务的横向扩容。一个服务通常会部署多个实例。
6.1 Dubbo内置负载均衡策略
Dubbo内置负载均衡策略
-
RandomLoadBalance:随机负载均衡,随机的选择一个,默认该策略。
-
RoundRobinLoadBalance:轮询负载均衡。
-
LeastActiveLoadBalance:最少活跃调用数,相同活跃数的随机。
-
ConsistentHashLoadBalance:一致性哈希负载均衡,相同参数的请求总是落在同一台机器上。
6.2 负载均衡策略配置
服务提供者
@Service(version = "2.0.0",loadbalance = "roundrobin") public class UserServiceImpl implements UserService
服务消费者
@Reference(version = "*",loadbalance = "random") private UserService userService;
- random:随机负载均衡
- leastactive:最少活跃调用数,相同活跃数的随机
- roundrobin:轮询负载均衡
7. 集群容错
集群容错是分布式系统中的一种机制,旨在提高系统的可用性和稳定性。
在一个分布式系统中,服务通常被部署在多个节点上,当一个节点或服务出现故障时,集群容错机制能够保证系统仍能够继续工作,而不至于因为单点故障而导致整个系统的崩溃。
7.1 容错模式
-
Failover Cluster:失败重试。默认值。当出现失败,重试其它服务器,默认重试2次,使用retries配置。一般用于读操作
-
Failfast Cluster : 快速失败,只发起一次调用,失败立即报错。通常用于写操作。
-
Failsafe Cluster : 失败安全,出现异常时,直接忽略。返回一个空结果。日志不重要操作。
-
Failback Cluster : 失败自动恢复,后台记录失败请求,定时重发。非常重要的操作。
-
Forking Cluster:并行调用多个服务器,只要有一个成功即返回。
-
7.2 配置
@Service(version = "2.0.0",cluster = "failover") public class UserServiceImpl implements UserService
8. 服务降级
8.1 介绍
服务降级,当服务器压力剧增的情况下,根据当前业务情况及流量对一些服务和页面有策略的降级,以此释放服务器资源以保证核心任务的正常运行。
- 当下游的服务因为某种原因响应过慢,下游服务主动停掉一些不太重要的业务,释放出服务器资源,增加响应速度!
@Reference(mock = "force:return null")
消费方对该服务的方法调用在失败后,再返回null值,不抛异常。用来容忍不重要服务不稳定时对调用方的影响。
@Reference(mock = "fail:return null")
9. 服务限流
9.1 限流算法
① 漏桶算法
漏桶算法思路很简单,水(请求)先进入到漏桶里,漏桶以一定的速度出水,当水流入速度过大会直接溢出,可以看出漏桶算法能强行限制数据的传输速率。
② 令牌桶算法
令牌桶算法的原理是系统会以一个恒定的速度往桶里放入令牌,而如果请求需要被处理,则需要先从桶里获取一个令牌,当桶里没有令牌可取时,则拒绝服务。
9.2 漏桶 vs 令牌桶的区别
漏桶的天然特性决定了它不会发生突发流量,就算每秒1000个请求到来,那么它对后台服务输出的访问速率永远恒定。而令牌桶则不同,其特性可以“预存”一定量的令牌,因此在应对突发流量的时候可以在短时间消耗所有令牌,其突发流量处理效率会比漏桶高,但是导向后台系统的压力也会相应增多。
9.3 配置限流
① 并发控制
例:服务端并发执行(或占用线程池线程数)不能超过10个
@Service(executes = 10)
② 连接控制
占用连接的请求的数不能超过10个。
@Service(actives= 10)
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· spring官宣接入deepseek,真的太香了~