Dubbo详解
文章目录
- 概述
- Dubbo缺点
- Dubbo架构
- Dubbo的工作原理
- Dubbo容错策略
- Dubbo的缓存机制
- Dubbo 的服务请求失败怎么处理
- Dubbo是如何动态感知服务下线的
- 注册中心挂了可以继续通信吗
- Dubbo支持哪些调用协议
- Dubbo 支持哪些序列化方式
- dubbo负载均衡策略
- Dubbo 有哪些注册中心
- Dubbo 服务器注册与发现的流程
- Dubbo 支持哪些协议,它们的优缺点有哪些
- Dubbo 使用的是什么通信框架
- Dubbo 超时设置有两种方式
- Dubbo的异步调用
概述
Dubbo 是一款开源的高性能分布式服务框架,由阿里巴巴集团开发和维护。它提供了一套完整的分布式服务治理解决方案,帮助用户轻松构建和管理大规模的分布式系统。
下面是 Dubbo 的一些主要特点和核心概念:
- 服务注册与发现:Dubbo 提供了服务注册中心,用于集中管理服务的注册和发现。服务提供者在启动时将自己的服务注册到注册中心,服务消费者通过注册中心获取服务提供者的地址并进行调用。
- 负载均衡:Dubbo 支持多种负载均衡策略,可以根据实际场景选择适合的负载均衡算法,以实现请求在服务提供者之间的均衡分发。
- 容错机制:Dubbo 提供了多种容错机制,包括失败自动切换、失败安全、失败快速等,用于处理服务提供者的故障,保证系统的可靠性和稳定性。
- 服务路由:Dubbo 支持灵活的服务路由配置,可以根据不同的条件和规则来决定请求转发到哪个服务提供者。
- 服务降级:Dubbo 支持服务降级,当服务提供者出现故障或性能下降时,可以通过配置降级策略来保证系统的可用性。
- 分布式事务:Dubbo 提供了分布式事务的解决方案,支持跨多个服务的事务一致性。
- 监控与管理:Dubbo 提供了丰富的监控和管理功能,包括统计服务调用次数和响应时间、实时监控等,帮助用户及时发现和解决问题。
Dubbo 的核心设计思想是面向接口的远程方法调用(RPC),在服务提供者和消费者之间通过网络进行通信。Dubbo 提供了对多种协议的支持,包括Dubbo协议、RMI协议、Hessian协议等,同时也支持多种序列化和传输方式。
总结来说,Dubbo 是一个强大的分布式服务框架,它可以帮助开发人员构建高性能、可扩展、可靠的分布式系统。通过提供全面的分布式服务治理解决方案,Dubbo 在阿里巴巴和其他众多企业中得到了广泛应用。
Dubbo缺点
1、跨语言支持较弱:目前Dubbo只在JAVA语言流行,其他语言支持较少。不适用跨语言调用。
2、Registry 严重依赖第三方组件(ZooKeeper 或者 Redis),当这些组件出现问题时,服务调用很快就会中断。
Dubbo架构
Dubbo 的核心功能
Remoting:网络通信框架,提供对多种 NIO 框架抽象封装,包括 “同步转异步”和“请求-响应”模式的信息交换方式。
Cluster:服务框架,提供基于接口方法的透明远程过程调用,包括多协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集群支持。
Registry:服务注册,基于注册中心目录服务,使服务消费方能动态 的查找服务提供方,使地址透明,使服务提供方可以平滑增加或减少机器。
Dubbo框架组件
- Provider:发布服务并将服务注册到注册中心,等待消费者调用。
- Consumer:从注册中心订阅服务,和服务提供者进行通信,消费服务。
- Registry:记录服务提供者的信息,以及服务提供者和服务消费者之间的关系,帮助消费者发现可用的服务实例。
- Monitor:收集Dubbo节点的性能指标、服务调用统计信息等,以便运维人员进行监控和管理。
- Container:服务的运行容器。
Dubbo是以高性能RPC框架,它提供了分布式架构下的服务之间通信方案,使得开发者可以不需要关心网络通信的细节。通过该框架可以使得远程服务调用方式和本地服务调用方式一样简单。
Dubbo是一款高性能、轻量级的开源RPC框架。由10层模式构成,整个分层依赖由上至下。
第一层的Business业务逻辑层由我们自己来提供接口和实现还有一些配置信息。
第二层的RPC调用的核心层负责封装和实现整个RPC的调用过程、负载均衡、集群容错、代理等核心功能。
第三层 Remoting则是对网络传输协议和数据转换的封装。
根据 Dubbo 官方文档的介绍,Dubbo 提供了六大核心能力
面向接口代理的高性能 RPC 调用
智能容错和负载均衡
服务自动注册和发现
高度可扩展能力
运行期流量调度
可视化的服务治理与运维
Dubbo的工作原理
1.服务启动的时候,provider和consumer根据配置信息,连接到注册中心register,分别向注册中心注册和订阅服务
2.register根据服务订阅关系,返回provider信息到consumer,同时consumer会把provider信息缓存到本地。如果信息有变更,consumer会收到来自register的推送
3.consumer生成代理对象,同时根据负载均衡策略,选择一台provider,同时定时向monitor记录接口的调用次数和时间信息
4.拿到代理对象之后,consumer通过代理对象发起接口调用
5.provider收到请求后对数据进行反序列化,然后通过代理调用具体的接口实现
Dubbo容错策略
Dubbo 官网提出总共有六种容错策略
1)Failover Cluster 模式
失败自动切换,当出现失败,重试其它服务器。(默认)
2)Failfast Cluster
快速失败,只发起一次调用,失败立即报错。 通常用于非幂等性的写操作,比如新增记录。
3)Failsafe Cluster
失败安全,出现异常时,直接忽略。 通常用于写入审计日志等操作。
4)Failback Cluster
失败自动恢复,后台记录失败请求,定时重发。 通常用于消息通知操作。
5)Forking Cluster
并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。
可通过 forks=”2”来设置最大并行数。
6)Broadcast Cluster
广播调用所有提供者,逐个调用,任意一台报错则报错。(2.1.0 开始支持) 通常用于通知所有提供者更新缓存
或日志等本地资源信息。
总结: 在实际应用中查询语句容错策略建议使用默认 Failover Cluster ,而增删改建议使用 Failfast Cluster 或
者 使用 Failover Cluster(retries=”0”) 策略 防止出现数据 重复添加等等其它问题!建议在设计接口时候把查询接口方法单独做一个接口提供查询。
集群的容错模式
模式一:failover(缺省)服务调用失败时自动切换,通过retries=”2”来设置重试次数。一般是读操作
模式二:Failfast 只发一次调用,失败立即异常,通常用于非幂等性的写操作例如新增操作
模式三:failsafe失败安全,通常用于日志服务
模式四:Forking并行调用多个服务,谁最先执行完,则使用谁的结果通常用于实时性较高的读操作,这种模式很浪费服务器资源可以通过forks=”2”来设置最高并发数
总结:
1:在生产环境读操作就使用默认的(failover)模式(retries=“2”)
2:在生产环境中写操作也可以用默认模式,但是记得将retries设置为0。
Dubbo提供了一系列的容错机制,可以提高分布式系统的可靠性和稳定性,主要包括以下几种:
- 容错策略:Dubbo支持多种容错策略,如Failover、Failfast、Failsafe等。这些容错策略在服务调用失败或超时时,会采取不同的措施进行容错处理,比如重试、切换服务提供者,或者忽略异常等。
- 超时重试:Dubbo支持对服务调用设置超时时间,当服务提供者在规定时间内未能完成响应时,Dubbo会自动进行重试,以降低由于网络波动等原因而造成的请求失败概率。
- 服务降级:Dubbo支持服务降级功能,即当某个服务出现故障或响应变慢时,可以将请求路由到备选服务上,从而保证系统的正常运行。通过降级可以提高系统的可用性和稳定性。
- 快速失败:在一些场景下,快速失败可以是更好的选择。如果在远程调用中发生异常,Dubbo可以立即返回给调用方一个异常结果,避免客户端长时间等待无响应等待操作。
- 隔离机制:Dubbo提供了多种隔离机制,包括线程隔离、进程隔离、集群隔离等。这些隔离机制可以对服务进行分组,防止某个服务异常对其他服务产生影响。
通过上述容错机制的选择和组合,可以提高Dubbo分布式系统的可靠性和健壮性,从而让用户更好地享受分布式系统带来的便利性
Dubbo的缓存机制
Dubbo的缓存机制主要用于提高系统性能和减少对远程服务的调用频率。Dubbo框架中的缓存机制可以在服务提供者端和服务消费者端都进行配置和使用。
在Dubbo服务提供者端,可以通过@Service注解或配置文件的方式开启缓存,并指定缓存的类型和其他相关参数。Dubbo支持的缓存类型包括:lru(Least Recently Used)、threadlocal、jcache等。开启缓存后,Dubbo会将服务的响应结果缓存起来,下次相同的请求到达时,可以直接从缓存中获取结果,而不必再执行实际的服务调用。
在Dubbo服务消费者端,可以通过配置文件的方式指定调用某个服务时是否启用缓存,以及指定具体的缓存策略。消费者端也可以根据需要自定义缓存策略。
需要注意的是,Dubbo的缓存机制是基于内存的缓存,适用于热点数据的缓存和重复查询的结果缓存。在使用Dubbo的缓存机制时,需要根据业务场景和需求合理配置缓存参数,避免缓存带来的数据一致性和过期数据等问题。
Dubbo 的服务请求失败怎么处理
Dubbo 是一个 RPC 框架,它为我们的应用提供了远程通信能力的封装,同时,Dubbo 在 RPC 通信的基础上,逐步在向一个生态在演进,它涵盖了服务注册、动态路由、容错、服务降级、负载均衡等能力,基本上在微服务架构下面临的问题,Dubbo 都可以解决。
而对于 Dubbo 服务请求失败的场景,默认提供了重试的容错机制,也就是说,如果基于 Dubbo 进行服务间通信出现异常,服务消费者会对服务提供者集群中,其他的节点发起重试,确保这次请求成功,默认的额外重试次数是 2 次。除此之外,Dubbo 还提供了更多的容错策略,我们可以根据不同的业务场景来进行选择。
快速失败策略,服务消费者只发起一次请求,如果请求失败,就直接把错误抛出去。这种比较适合在非幂等性场景中使用失败安全策略,如果出现服务通信异常,直接把这个异常吞掉不做任何处理
失败自动恢复策略,后台记录失败请求,然后通过定时任务来对这个失败的请求进行重发。
并行调用多个服务策略,就是把这个消息广播给服务提供者集群,只要有任何一个节点返回,就表示请求执行成功。广播调用策略,逐个调用服务提供者集群,只要集群中任何一个节点出现异常,就表示本次请求失败要注意的是,默认基于重试策略的容错机制中,需要注意幂等性的处理,否则在事务型的操作中,容易出现多次数据变更的问题。
Dubbo是如何动态感知服务下线的
首先,Dubbo默认采用Zookeeper实现服务的注册与服务发现,简单来说啊,就是多个Dubbo服务之间的通信地址,是使用Zookeeper来维护的。在Zookeeper上,会采用树形结构的方式来维护Dubbo服务提供端的协议地址,
Dubbo服务消费端会从Zookeeper Server上去查找目标服务的地址列表,从而完成服务的注册和消费的功能。
Zookeeper会通过心跳检测机制,来判断Dubbo服务提供端的运行状态,来决定是否应该把这个服务从地址列表剔除。当Dubbo服务提供方出现故障导致Zookeeper剔除了这个服务的地址,
那么Dubbo服务消费端需要感知到地址的变化,从而避免后续的请求发送到故障节点,导致请求失败。
也就是说Dubbo要提供服务下线的动态感知能力。这个能力是通过Zookeeper里面提供的Watch机制来实现的,
简单来说呢,Dubbo服务消费端会使用Zookeeper里面的Watch来针对Zookeeper
Server端的/providers节点注册监听,一旦这个节点下的子节点发生变化,Zookeeper Server就会发送一个事件通知Dubbo,Client端.Dubbo Client端收到事件以后,就会把本地缓存的这个服务地址删除,这样后续就不会把
请求发送到失败的节点上,完成服务下线感知。
注册中心挂了可以继续通信吗
可以,因为刚开始初始化的时候,消费者会将提供者的地址等信息拉取到本地缓存,所以注册中心挂了可以继续通信
首先,Dubbo 默认采用 Zookeeper 实现服务的注册与服务发现,简单来说,是多个 Dubbo 服务之间的通信地址,是使用 Zookeeper 来维护的。而在 Zookeeper 上,会采用树形结构的方式来维护 Dubbo 服务提供端的协议地址,Dubbo 服务消费端会从 Zookeeper Server 上去查找目标服务的地址列表,从而完成服务的注册和消费功能。
Dubbo支持哪些调用协议
Apache Dubbo(以前称为 Apache Dubbo)是一种高性能的 Java RPC 框架,支持多种调用协议。Dubbo 支持以下几种调用协议:
- Dubbo 协议:Dubbo 的自有协议,基于 TCP 长连接,采用单一长连接进行通信,适用于传输大数据量的场景。
- HTTP 协议:基于 HTTP 和 RESTful 风格的协议,适合与 Web 系统集成。
- RMI 协议:Java 原生的远程方法调用协议,适用于 Java 程序之间的远程调用。
- Hessian 协议:一种基于二进制的轻量级 RPC 协议,性能较好,适合跨语言调用。
- Thrift 协议:Facebook 开源的多语言 RPC 框架 Apache Thrift 的协议,支持多种语言之间的远程调用。
- gRPC 协议:由 Google 开发的高性能 RPC 框架,基于 HTTP/2 和 Protocol Buffers,支持多语言。
每种调用协议在不同场景下都有其适用性,可以根据具体的需求选择合适的协议来进行远程调用。Dubbo 提供了丰富的配置选项,使得开发者可以灵活地选择和配置不同的调用协议。
Dubbo 支持哪些序列化方式
默认使用 Hessian 序列化,还有 Duddo、FastJson、Java 自带序列 化。
dubbo负载均衡策略
Dubbo负载均衡在客户端,dubbo内置了4种负载均衡策略:
a. RandomLoadBalance:随机负载均衡。随机的选择⼀个。是Dubbo的默认负载均衡策略。
b. RoundRobinLoadBalance:轮询负载均衡。轮询选择⼀个。
c. LeastActiveLoadBalance:最少活跃调⽤数,相同活跃数的随机。活跃数指调⽤前后计数差。使慢的 Provider 收到更少请求,
因为越慢的 Provider 的调⽤前后计数差会越⼤。
d. ConsistentHashLoadBalance:⼀致性哈希负载均衡。相同参数的请求总是落在同⼀台机器上。
Dubbo 有哪些注册中心
Multicast 注册中心:Multicast 注册中心不需要任何中心节点,只要广播地址,就能进行服务注册 和发现,基于网络中组播传输实现。
Zookeeper 注册中心:基于分布式协调系统 Zookeeper 实现,采用 Zookeeper 的 watch 机制实 现数据变更。
Redis 注册中心:基于 Redis 实现,采用 key/map 存储,key 存储服务名和类型,map 中 key 存 储服务 url,value 服务过期时间。基于 Redis 的发布/订阅模式通知数据变更。 Simple 注册中心。
推荐使用 Zookeeper 作为注册中心
Dubbo 服务器注册与发现的流程
服务容器 Container 负责启动,加载,运行服务提供者。
服务提供者 Provider 在启动时,向注册中心注册自己提供的服务
服务消费者 Consumer 在启动时,向注册中心订阅自己所需的服务。
注册中心 Registry 返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长
连接推送变更数据给消费者。
服务消费者 Consumer,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行
调用,如果调用失败,再选另一台调用。
服务消费者 Consumer 和提供者 Provider,在内存中累计调用次数和调用时间,定时每
分钟发送一次统计数据到监控中心 Monitor
Dubbo 支持哪些协议,它们的优缺点有哪些
Dubbo: 单一长连接和 NIO 异步通讯,适合大并发小数据量的服务调用,以及消费者远大于提供
者。传输协议 TCP,异步 Hessian 序列化。Dubbo推荐使用dubbo协议。
RMI: 采用 JDK 标准的 RMI 协议实现,传输参数和返回参数对象需要实现 Serializable 接口,使
用 Java 标准序列化机制,使用阻塞式短连接,传输数据包大小混合,消费者和提供者个数差不 多,可传文件,传输协议 TCP。 多个短连接 TCP 协议传输,同步传输,适用常规的远程服务调用 和 RMI 互操作。在依赖低版本的 Common-Collections 包,Java 序列化存在安全漏洞。
WebService:基于 WebService 的远程调用协议,集成 CXF 实现,提供和原生 WebService 的互
操作。多个短连接,基于 HTTP 传输,同步传输,适用系统集成和跨语言调用。
HTTP: 基于 Http 表单提交的远程调用协议,使用 Spring 的 HttpInvoke 实现。多个短连接,传
输协议 HTTP,传入参数大小混合,提供者个数多于消费者,需要给应用程序和浏览器 JS 调用。
Hessian:集成 Hessian 服务,基于 HTTP 通讯,采用 Servlet 暴露服务,Dubbo 内嵌 Jetty 作为
服务器时默认实现,提供与 Hession 服务互操作。多个短连接,同步 HTTP 传输,Hessian 序列 化,传入参数较大,提供者大于消费者,提供者压力较大,可传文件。
Memcache:基于 Memcache实现的 RPC 协议。
Redis:基于 Redis 实现的RPC协议
Dubbo 使用的是什么通信框架
默认使用 Netty 作为通讯框架
Dubbo 超时设置有两种方式
服务提供者端设置超时时间,在 Dubbo 的用户文档中,推荐如果能在服务端多配置就尽量多配置,因为服务提供者比消费者更清楚自己提供的服务特性。
服务消费者端设置超时时间,如果在消费者端设置了超时时间,以消费者端为主,即优先 级更高。因为服务调用方设置超时时间控制性更灵活。如果消费方超时,服务端线程不会 定制,会产生警告
Dubbo的异步调用
在 Apache Dubbo 中,可以通过异步调用来提高系统的并发性能和响应速度。Dubbo 支持两种方式的异步调用:
- Future 异步调用:
○ 通过返回 java.util.concurrent.Future 对象来进行异步调用。在服务提供者端,方法需要返回 java.util.concurrent.CompletableFuture 或 Dubbo 提供的 AsyncContext 对象,以表示异步结果。
○ 在服务消费者端,可以通过 Future.get() 方法获取结果,从而实现异步调用。
- Callback 异步调用:
○ 通过回调函数的方式来处理异步调用的结果。在服务提供者端,方法需要接受一个回调函数参数,用于在异步调用完成时通知结果。
○ 在服务消费者端,可以设置回调函数,当异步调用完成时会触发回调函数,从而处理结果。
下面是一个简单的示例代码,演示 Dubbo 的异步调用:
服务提供者端: public interface AsyncService { CompletableFuture sayHelloAsync(String name); } public class AsyncServiceImpl implements AsyncService { @Override public CompletableFuture sayHelloAsync(String name) { return CompletableFuture.supplyAsync(() -> "Hello, " + name); } } 服务消费者端: public class AsyncConsumer { public void invokeAsyncService() { AsyncService asyncService = // 获取远程服务引用 CompletableFuture future = asyncService.sayHelloAsync("Alice"); future.whenComplete((result, exception) -> { if (exception == null) { System.out.println("Result: " + result); } else { System.err.println("Error occurred: " + exception.getMessage()); } }); } }
通过以上示例代码,服务消费者可以实现对异步服务方法的调用,并在异步调用完成后处理结果。这样可以提高系统的并发性能,更好地利用系统资源。