【Dubbo】dubbo与zookeeper(初学者的宝典!)
目录
详细说明过程——当consumer 启动,Dubbo 框架会自动处理服务引用,并创建代理对象
1、consumer和provider二者不可见,如何调用?
为什么在dubbo框架中,只用先启动provider,再启动consumer。为什么service不用启动呢?
ZooKeeper 在 Dubbo 应用中的作用
ZooKeeper 是一个开源的分布式协调服务,它在 Dubbo 中被广泛使用来实现服务注册、发现和配置管理等功能。在 Dubbo 架构中,ZooKeeper 扮演了一个重要的角色,可以提供以下功能:
ZooKeeper 是一个开源的分布式协调服务,它在 Dubbo 中被广泛使用来实现服务注册、发现和配置管理等功能。在 Dubbo 架构中,ZooKeeper 扮演了一个重要的角色,可以提供以下功能:
- 服务注册与发现:Dubbo 的 provider(服务提供者)会将自己提供的服务信息注册到 ZooKeeper 上,consumer(服务消费者)则通过 ZooKeeper 发现可用的服务。
- 负载均衡:ZooKeeper 可以记录每个 provider 提供的服务,并且 Dubbo 的 consumer 可以从中选择一个适合的 provider 进行调用,实现负载均衡的效果。
- 故障恢复:如果某个 provider 发生故障或下线,ZooKeeper 可以及时更新服务注册信息,使得 consumer 不再选择该 provider,从而实现故障恢复。
- 动态配置:Dubbo 的一些配置信息(如超时设置、权重等)可以通过 ZooKeeper 实现动态配置,这样避免了修改代码或重启应用的麻烦。
- 集群管理:ZooKeeper 还能够用于管理 Dubbo 集群的多个节点,确保集群的高可用性和一致性。
所以,ZooKeeper 在 Dubbo 应用中可以起到一个公告板的作用,它集中管理服务的注册、发现和配置信息,使得 Dubbo 的 provider 和 consumer 能够方便地进行通信和协调。通过 ZooKeeper,Dubbo 应用可以实现高可用、动态扩展和负载均衡等特性。
consumer是怎么样使用provider的提供的服务的
如果 consumer 和 provider 不在同一个包下,但是要使用 provider 提供的服务,可以通过以下步骤进行:
- 在 consumer 的代码中,创建一个与 provider 相同的服务接口类(通常在 common 包下),该接口定义了 provider 可以提供的各种服务方法,包括输入参数和返回值等信息。
// 服务接口 public interface UserService { User getUserById(int id); void saveUser(User user); // 其他服务方法... }
- 将 provider 提供的服务接口类的 Jar 包或依赖添加到 consumer 的项目中。这样,在 consumer 的代码中就可以引用该服务接口类了。
- 在 consumer 的代码中,通过 Dubbo 的配置方式来声明对 provider 提供的服务的引用。
- 如果是使用 XML 配置,需要在配置文件中声明对服务接口的引用,并设置相关参数。
<!-- Dubbo 服务引用配置 --> <dubbo:reference id="userService" interface="com.example.UserService" url="dubbo://localhost:20880"/>
- 如果是使用注解方式,可以在消费方的代码中使用
@Reference
注解来引用服务接口。
// 引入服务接口 @Reference private UserService userService;
-
当 consumer 启动时,Dubbo 框架会自动处理服务引用,并创建代理对象。
-
consumer 就可以像调用本地方法一样,直接使用代理对象来调用 provider 提供的服务方法。
// 调用服务 User user = userService.getUserById(1);
通过以上步骤,consumer 就可以使用 provider 提供的服务了。无论 consumer 和 provider 是否在同一个包下,只要声明了相同的服务接口并进行合适的引用配置,consumer 就能够调用 provider 的服务方法。
详细说明过程——当consumer 启动,Dubbo 框架会自动处理服务引用,并创建代理对象
当 consumer 启动时,Dubbo 框架会自动处理服务引用,并创建代理对象。这个过程可以分为以下几个步骤:
-
根据 Dubbo 配置文件或注解配置,Dubbo 框架会加载配置信息,包括 ZooKeeper 地址、服务注册信息、负载均衡策略等。
-
Dubbo 框架会扫描 consumer 的代码,查找被
@Reference
注解修饰的服务引用字段或方法参数。或者根据 XML 配置文件中声明的服务引用信息。 -
对于每一个被
@Reference
注解修饰的服务引用字段或方法参数,Dubbo 框架会根据被注解修饰的类型(服务接口类型),创建一个代理对象。 -
创建代理对象的方式通常有两种:JDK 动态代理和 Javassist 字节码生成。Dubbo 默认使用 Javassist 字节码生成。
-
创建代理对象时,Dubbo 框架会将服务接口类型、服务引用配置、集群配置等信息传递给代理对象。
-
代理对象内部封装了网络通信、负载均衡、序列化、容错处理等底层细节的逻辑。
-
当 consumer 调用代理对象的方法时,实际上是通过代理对象将调用请求发送给 Dubbo 框架。
-
Dubbo 框架根据负载均衡策略选择一个合适的 provider 实例,并将请求转发给该 provider 实例。
-
provider 接收到请求后,执行相应的服务逻辑,并将结果返回给 Dubbo 框架。
-
Dubbo 框架将服务调用结果返回给代理对象,然后代理对象再将结果返回给 consumer。
通过以上步骤,Dubbo 框架在 consumer 启动时会自动处理服务引用,创建代理对象,还可以根据配置信息对服务调用进行负载均衡和容错处理。在 consumer 的代码中,可以直接调用代理对象的方法来调用 provider 提供的服务,而无需关心底层的网络通信和调用细节。这种透明化的远程调用方式使得 consumer 和 provider 可以像调用本地方法一样方便地进行服务交互。
zookeeper负责干嘛,它详细具体的起到了什么作用
ZooKeeper 是一个分布式协调服务,它具体起到以下作用:
- 配置管理:ZooKeeper 可以用于集中管理分布式系统中的各种配置信息。在模拟场景中,假设有一个分布式应用程序需要连接到不同的数据库实例,而这些数据库的连接信息可能会发生变化。使用 ZooKeeper,可以将数据库连接信息存储在一个节点上,并且各个应用程序可以监听该节点的变化,从而动态获取最新的连接信息。
流程:
a) 应用程序 A、B 和 C 需要连接到数据库实例。
b) ZooKeeper 创建一个节点
/database_config
并存储数据库连接信息(例如 IP 地址、端口等)。c) 应用程序 A、B 和 C 在启动时连接到 ZooKeeper,并监听节点
/database_config
的变化。d) 如果数据库连接信息发生变化,ZooKeeper 会通知应用程序 A、B 和 C。 e) 应用程序 A、B 和 C 接收到通知后,根据最新的连接信息重新连接到数据库。
- 命名服务:ZooKeeper 可以提供一个统一的命名空间来存储和查询分布式系统中的节点信息。在模拟场景中,假设有一个分布式存储系统,每个存储节点需要注册到 ZooKeeper,并提供自己的状态信息。
流程: a) 存储节点 A、B 和 C 启动时将自己的状态信息注册到 ZooKeeper 中。
b) 其他节点或应用程序可以查询 ZooKeeper 获取存储节点的列表和状态信息。
- 分布式锁:ZooKeeper 提供了分布式锁机制,用于在分布式环境下实现互斥访问共享资源的功能。在模拟场景中,假设有多个线程需要访问某个共享资源,使用 ZooKeeper 的分布式锁可以确保同一时刻只有一个线程可以访问该资源。
流程: a) 线程 A、B 和 C 需要访问共享资源。 b) 每个线程在访问资源之前尝试获取 ZooKeeper 上的一个分布式锁节点。 c) 只有一个线程能够成功创建分布式锁节点,表示获取到了锁。 d) 当线程完成对资源的访问后,释放分布式锁节点,以便其他线程可以竞争获取锁。
dubbo框架细节
1、common模块在最底层,用于最基本的配置,包括io,lombok等
2、service层需要common层依赖,对应ssm服务层的接口
3、consumer和provider层都需要service的依赖,但彼此之间没有依赖,不可见,二者对比ssm,前者类似controller层,后者类比service层的实现类和Dao层
那么问题来了
1、consumer和provider二者不可见,如何调用?
首先源码中并无任何花里胡哨的操作,虽然consumer中没有service层的实现类,依然可以通过类似注入的形式给service接口赋值,调用方法也像好像本模块中真的有这个接口的实现类一样,这就是远端执行,本地调用的rpc
2、zookeeper在从中扮演着什么角色?
我们既然启动项目的时候必须首先启动zookeeper,然后才能启动provider,在最后才能启动consumer,那么zookeeper一定起了很大的作用
rpc需要将请求通过网络发送的形式去调用远端,从而找到结果。那么zookeeper一定在网络发送中起了一定的作用,其实zookeeper可以维护一个类似于公告板的东西,从而能够使得consumer找到provider,然后发送请求
当然还有一种猜测,我们可能可以整一个像类似中转站一样,将网络请求解析,然后转发到正确的位置,但实际上这样并不好,因为网络最好去中心化,否则中心结点的崩溃会导致整个网络崩溃,所以我们采用了zookeeper去维护一个“公告板”,这样即使zookeeper真的产生了崩溃,客户端的缓存依旧可以使用一段时间,不会像中转一样立刻就去世了
3、转发流程
首先需要序列化,然后封装成为合格的网络协议,因为网络传输肯定是01比特流,不能直接传输对象,这其中还需要代理的使用,代理的作用即强化功能,需要完成序列化与反序列化流程
为什么在dubbo框架中,只用先启动provider,再启动consumer。为什么service不用启动呢?
在 Dubbo 中,服务提供者(provider)启动时会将自己的服务注册到注册中心(如 ZooKeeper)上,并监听指定的端口等待消费者(consumer)的请求。消费者会从注册中心获取可用的服务列表,并根据负载均衡策略选择一个服务提供者进行调用。所以在 Dubbo 中,可以先启动服务提供者(provider),再启动服务消费者(consumer)。
为什么不需要单独启动服务(service)呢?这是因为 Dubbo 框架将服务的定义和实现解耦,它通过接口的方式定义服务,并将服务的具体实现交给服务提供者去完成。服务提供者启动时会通过配置文件或注解的方式指定具体的服务实现类。消费者只需要引入服务的接口定义,并在配置文件或代码中声明要使用的服务接口,Dubbo 框架会自动根据配置信息找到可用的服务提供者。
因此,在 Dubbo 框架中,并不需要单独启动服务(service),其定义只是作为消费者和提供者之间的契约存在,实际的服务实现由提供者来负责。
也就是说consumer的请求会先打到zookeeper上面,然后zookeeper根据负载均衡去分配provider提供的服务,然后打到该provider监听的端口上
在 Dubbo 框架中,消费者(consumer)的请求首先会发送到注册中心(如 ZooKeeper)。注册中心会维护服务提供者(provider)的信息,包括它们的 IP 地址、端口和可用性等。消费者通过与注册中心交互,获取可用的服务列表。
接下来,消费者根据负载均衡策略选择一个合适的服务提供者进行调用。负载均衡策略可以是轮询、随机选择、权重等算法,用于分配请求到不同的服务提供者。
一旦消费者确定要调用的服务提供者,它会向该服务提供者发送请求。服务提供者监听指定的端口,等待消费者的请求到达。一旦请求到达,服务提供者会执行相应的服务实现,并将结果返回给消费者。
总结起来,消费者的请求首先经过注册中心获取可用的服务列表,然后根据负载均衡策略选择一个服务提供者,并向选定的服务提供者发送请求。最后,服务提供者执行具体的服务实现并返回结果给消费者。
更多推荐
所有评论(0)