dubbo组件功能
2024-06-28 15:09:47 3 举报
AI智能生成
dubbo
作者其他创作
大纲/内容
DynamicDirectory
【服务发现的组件】
RegistryDirectory,2.7.x,2.6.x
【服务发现的组件】
RegistryDirectory,2.7.x,2.6.x
功能点
1 主动查询zk来第一次获取集群地址
2 目标服务实例集群地址有变化,自动维护更新
概述
目标服务实例集群,不光是说要通过主动查询zk来第一次获取集群地址,还需要zk反过来,如果目标服务实例集群地址有变化
* zk会感受到了,zk应该是会反过来推送你的目标服务实例集群地址给DynamicDirectory,动态更新和维护
* 自己内存里的目标服务实例集群地址列表,invokers
* zk会感受到了,zk应该是会反过来推送你的目标服务实例集群地址给DynamicDirectory,动态更新和维护
* 自己内存里的目标服务实例集群地址列表,invokers
容错策略【模板设计模式】
FailfastClusterInvoker
调用失败,不会抛错,返回空,打印日志而已
FailoverClusterInvoker
失败自动切换,当出现失败,重试其它服务器
假设配置timeout1秒,加上重试3次,一个接口就会出现3秒超时
注意此场景带来的雪崩效应
FailbackClusterInvoker
调用失败了,会把这次调用记录存储起来,后续根据一定的策略,再去隔一段时间进行重试
默认重试三次[除业务调用],每次间隔5秒【定时器实现】
重试成功的结果不再返回业务应用程序,适合写请求等不依赖结果场景
BroadcastClusterInvoker
依次调用所有的服务,只要服务存在异常就停止调用,抛出异常
通常用于通知所有提供者更新缓存或日志等本地资源信息。
ForkingClusterInvoker
会并行的调用几个服务,如果谁能先返回结果,就用谁的结果
BlockingQueue数据结构实现
自定义实现
负载均衡策略算法
RandomLoadBalance
基于权重的随机负载均衡算法
RoundRobinLoadBalance
轮询,你有10个invokers,先调用第一个invoker,然后再调用第二个invoker
LeastActiveLoadBalance
会去尽量选择你的被调用最少的invoker
ConsistentHashLoadBalance
相关介绍
一致性hash
会针对你的各个节点,搞一些虚拟节点,节点和虚拟节点联合起来,就可以组成一个节点环
你对参数的hash后的值,会在一个环里,落在某个地方,环里落了很多的虚拟节点,此时会让原先给那个节点的请求,
分散到多个虚拟节点上去.
把你的请求尽量分散给各个节点.
你对参数的hash后的值,会在一个环里,落在某个地方,环里落了很多的虚拟节点,此时会让原先给那个节点的请求,
分散到多个虚拟节点上去.
把你的请求尽量分散给各个节点.
纯hash算法
【很有可能导致节点的负载是不均衡的】
【很有可能导致节点的负载是不均衡的】
hash(zhangsan),hash(lisi),根据这个hash的值,可以把这个hash值路由到某个节点上去
dubbo进行rpc调用,如果你rpc调用里某个参数值,在多次调用里都是一样的,每次对这个值做hash,结果都是一样的
rpc调用都路由到同一个节点上去
dubbo进行rpc调用,如果你rpc调用里某个参数值,在多次调用里都是一样的,每次对这个值做hash,结果都是一样的
rpc调用都路由到同一个节点上去
一致性hash,把你的请求尽量分散给各个节点
LeastActiveLoadBalance
会去尽量选择你的被调用最少的invoker
ShortestResponseLoadBalance
获取最短响应时间Invoker集合
自定义实现
降级策略
MockClusterInvoker
含义
如果说你的目标provider服务实例,突然故障了,这个时候consumer端可以进行降级调用
本地进行mock,consumer端就不再发起远程调用了,直接在本地搞一个mock就可以了
本地调用一个mock方法,在mock方法里构造写死一个结果,返回就完了
本地进行mock,consumer端就不再发起远程调用了,直接在本地搞一个mock就可以了
本地调用一个mock方法,在mock方法里构造写死一个结果,返回就完了
源码图
Rpc调用
DubboInvoker
功能
判断与远程交互的客户端,如果是一个,直接用,如果是多个则轮训
判断接口是单方向的,直接向远端发送请求send(),如果不是,
则判断是不是异步的,如果是异步调用将future放到context里,
如果是同步则等接口执行完之后get出结果
判断接口是单方向的,直接向远端发送请求send(),如果不是,
则判断是不是异步的,如果是异步调用将future放到context里,
如果是同步则等接口执行完之后get出结果
注册中心
缓存机制
AbstractRegistry
功能
两大块公共基础能力,基于本地磁盘文件的数据缓存写入和重启恢复加载的一套机制
注册、取消注册、订阅、取消订阅、变更通知,注册中心相关的交互逻辑,在这里都有对应的数据结构存储
亮点代码
SPI的扩展机制
含义
关键组件再代码里全部没有写死实现类,
都是在代码运行的时候,
动态的去查找以及实例化出来的
都是在代码运行的时候,
动态的去查找以及实例化出来的
Java的SPI机制
代码里,需要有一个接口,有多个实现类
在src/main/resource目录里,META-INF
需要你的接口全限定名命名的一个文件,xx.xx.xx.XCass【具体实现】
需要你的接口全限定名命名的一个文件,xx.xx.xx.XCass【具体实现】
//扫描元数据
ServiceLoader<接口> serviceLoaders = ServiceLoader.load(接口.class);
for(接口 变量 : serviceLoaders) {
变量.xx
}
ServiceLoader<接口> serviceLoaders = ServiceLoader.load(接口.class);
for(接口 变量 : serviceLoaders) {
变量.xx
}
一次性实例化所有的扩展点实现【消耗资源】
dubbo的SPI机制
特点
META-INF/dubbo/internal
META-INF/dubbo/internal
自动包装,扩展类把其他的扩展类作为构造函数的参数,扩展类做为一个Wrapper包装类
自动加载,IOC,扩展类是另外一个扩展类的一个属性,setter方法,dubbo会自动进行IOC,接管你的这些扩展类的依赖注入
自动适应,@Adaptive,他需要根据你的dubbo有url,参数,可以根据一些参数自动去适应和匹配对应的实现类【重新生成代码】
自动激活,dubbo SPI有很多的高阶的特性,他是为了实现一套自己的非常灵活的扩展机制
protocolSPI,在他的原理里,见过了很多,其他的组件都是类似的
@SPI(“impl”)
public interface UserService {
}
META-INF/dubbo/internal,搞一个接口名字的文件
@SPI(“impl”)
public interface UserService {
}
META-INF/dubbo/internal,搞一个接口名字的文件
dubbo是在方法执行时才决定调用哪个扩展点
核心源码
ExtensionLoader
加载的目录
META-INF/services/ (标准的SPI路径)
META-INF/dubbo/
META-INF/dubbo/internal/ (内部实现)
扩展点文件定义格式:目录 / 接口全路径
子主题
spring中的spi机制
META-INF目录底下,所有的文件名都是叫spring.factories
过滤器
provider
AccessLogFilter
打印日志
ExecuteLimitFilter
根据你的配置,可以针对你的类和方法,去限制同时调用的并发数量
....
consumer
ActiveLimitFilter
他是放在cosumer端对并发进行控制的
DeprecatedFilter
对你要调用的接口方法是否过期做一个判断和处理
....
分发策略和线程池
用法
<dubbo:protocol name="dubbo" dispatcher="all" threadpool="fixed" threads="100" />
分发策略
AllDispatcher【默认】
将所有请求、连接等事件都分发到ThreadPool扩展点指定的线程池中,如果ThreadPool指定的线程池已关闭或不存在则使用默认的一个cached线程池
DirectDispatcher
不使用多线程,在当前的接收线程(IO线程)上直接处理所有事件、请求
MessageOnlyDispatcher
只将所有请求都分发到ThreadPool扩展点指定的线程池中,事件直接由接收线程(IO线程)处理
ExecutionDispatcher
只把请求类消息派发到业务线程池处理,但是响应和其它连接断开事件,心跳等消息直接在IO线程上执行
ConnectionOrderedDispatcher
将所有请求、异常都分发到ThreadPool扩展点指定的线程池中。而连接等事件发送到只有一个工作线程的线程池内按调用接收顺序逐个执行
为什么需要不同的分发策略?
根据不同的情况是有关系的,direct,你的实际要执行的代码并没有外部数据库的io操作
你要是不关注网络连接和断开,关注的请求和响应的处理,message,execution
如果你要是对网络连接和端口特别关注,connection
线程池
FixedThreadPool【默认】
固定大小线程池,启动时建立线程,不关闭,一直持有。
CachedThreadPool
如果有空闲的线程,就进行回收,如果有新的任务来,就创建新的线程
LimitedThreadPool
可伸缩线程池,但池中的线程数只会增长不会收缩。只增长不收缩的目的是为了避免收缩时突然来了大流量引起的性能问题。
EagerThreadPool【慎用】
如果你的线程池里的线程都是忙碌的状态下,此时你可以创建新的线程出来,而不是放到queue里去排队
router
设计思想
责任链模式的思想
invoker->invoker->invoker->invoker
在发起rpc调用的时候,肯定会涉及到很多的机制,比如降级调用机制(mock),集群容错机制,负载均衡机制,rpc调用。
【设计一个invoker,代码会很多很多】
【设计一个invoker,代码会很多很多】
配置中心
元数据
监控
0 条评论
下一页